diff options
author | emaste <emaste@FreeBSD.org> | 2015-02-06 21:38:51 +0000 |
---|---|---|
committer | emaste <emaste@FreeBSD.org> | 2015-02-06 21:38:51 +0000 |
commit | 0c2019f4ca6b2dc6d710f6bb16a0e3ed10271531 (patch) | |
tree | 09bc83f73246ee3c7a779605cd0122093d2a8a19 /source/Target/Thread.cpp | |
parent | 01ee1789d6aa7294e5966a97f8d29387f6f81699 (diff) | |
download | FreeBSD-src-0c2019f4ca6b2dc6d710f6bb16a0e3ed10271531.zip FreeBSD-src-0c2019f4ca6b2dc6d710f6bb16a0e3ed10271531.tar.gz |
Import LLDB as of upstream SVN r225923 (git 2b588ecd)
This corresponds with the branchpoint for the 3.6 release.
A number of files not required for the FreeBSD build have been removed.
Sponsored by: DARPA, AFRL
Diffstat (limited to 'source/Target/Thread.cpp')
-rw-r--r-- | source/Target/Thread.cpp | 259 |
1 files changed, 189 insertions, 70 deletions
diff --git a/source/Target/Thread.cpp b/source/Target/Thread.cpp index a445517..b532d8d 100644 --- a/source/Target/Thread.cpp +++ b/source/Target/Thread.cpp @@ -32,6 +32,7 @@ #include "lldb/Target/ThreadPlan.h" #include "lldb/Target/ThreadPlanCallFunction.h" #include "lldb/Target/ThreadPlanBase.h" +#include "lldb/Target/ThreadPlanPython.h" #include "lldb/Target/ThreadPlanStepInstruction.h" #include "lldb/Target/ThreadPlanStepOut.h" #include "lldb/Target/ThreadPlanStepOverBreakpoint.h" @@ -43,7 +44,7 @@ #include "lldb/Target/ThreadSpec.h" #include "lldb/Target/Unwind.h" #include "Plugins/Process/Utility/UnwindLLDB.h" -#include "UnwindMacOSXFrameBackchain.h" +#include "Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h" using namespace lldb; @@ -278,6 +279,7 @@ Thread::Thread (Process &process, lldb::tid_t tid, bool use_invalid_index_id) : m_process_wp (process.shared_from_this()), m_stop_info_sp (), m_stop_info_stop_id (0), + m_stop_info_override_stop_id (0), m_index_id (use_invalid_index_id ? LLDB_INVALID_INDEX32 : process.GetNextThreadIndexID(tid)), m_reg_context_sp (), m_state (eStateUnloaded), @@ -465,6 +467,24 @@ Thread::GetPrivateStopInfo () SetStopInfo (StopInfoSP()); } } + + // The stop info can be manually set by calling Thread::SetStopInfo() + // prior to this function ever getting called, so we can't rely on + // "m_stop_info_stop_id != process_stop_id" as the condition for + // the if statement below, we must also check the stop info to see + // if we need to override it. See the header documentation in + // Process::GetStopInfoOverrideCallback() for more information on + // the stop info override callback. + if (m_stop_info_override_stop_id != process_stop_id) + { + m_stop_info_override_stop_id = process_stop_id; + if (m_stop_info_sp) + { + ArchSpec::StopInfoOverrideCallbackType callback = GetProcess()->GetStopInfoOverrideCallback(); + if (callback) + callback(*this); + } + } } return m_stop_info_sp; } @@ -642,7 +662,8 @@ Thread::SetupForResume () lldb::RegisterContextSP reg_ctx_sp (GetRegisterContext()); if (reg_ctx_sp) { - BreakpointSiteSP bp_site_sp = GetProcess()->GetBreakpointSiteList().FindByAddress(reg_ctx_sp->GetPC()); + const addr_t thread_pc = reg_ctx_sp->GetPC(); + BreakpointSiteSP bp_site_sp = GetProcess()->GetBreakpointSiteList().FindByAddress(thread_pc); if (bp_site_sp) { // Note, don't assume there's a ThreadPlanStepOverBreakpoint, the target may not require anything @@ -650,19 +671,30 @@ Thread::SetupForResume () ThreadPlan *cur_plan = GetCurrentPlan(); - if (cur_plan->GetKind() != ThreadPlan::eKindStepOverBreakpoint) + bool push_step_over_bp_plan = false; + if (cur_plan->GetKind() == ThreadPlan::eKindStepOverBreakpoint) { - ThreadPlanStepOverBreakpoint *step_bp_plan = new ThreadPlanStepOverBreakpoint (*this); - if (step_bp_plan) + ThreadPlanStepOverBreakpoint *bp_plan = (ThreadPlanStepOverBreakpoint *)cur_plan; + if (bp_plan->GetBreakpointLoadAddress() != thread_pc) + push_step_over_bp_plan = true; + } + else + push_step_over_bp_plan = true; + + if (push_step_over_bp_plan) + { + ThreadPlanSP step_bp_plan_sp (new ThreadPlanStepOverBreakpoint (*this)); + if (step_bp_plan_sp) { - ThreadPlanSP step_bp_plan_sp; - step_bp_plan->SetPrivate (true); + ; + step_bp_plan_sp->SetPrivate (true); if (GetCurrentPlan()->RunState() != eStateStepping) { + ThreadPlanStepOverBreakpoint *step_bp_plan + = static_cast<ThreadPlanStepOverBreakpoint *>(step_bp_plan_sp.get()); step_bp_plan->SetAutoContinue(true); } - step_bp_plan_sp.reset (step_bp_plan); QueueThreadPlan (step_bp_plan_sp, false); } } @@ -941,30 +973,30 @@ Thread::ShouldStop (Event* event_ptr) if (over_ride_stop) should_stop = false; - // One other potential problem is that we set up a master plan, then stop in before it is complete - for instance - // by hitting a breakpoint during a step-over - then do some step/finish/etc operations that wind up - // past the end point condition of the initial plan. We don't want to strand the original plan on the stack, - // This code clears stale plans off the stack. + } + + // One other potential problem is that we set up a master plan, then stop in before it is complete - for instance + // by hitting a breakpoint during a step-over - then do some step/finish/etc operations that wind up + // past the end point condition of the initial plan. We don't want to strand the original plan on the stack, + // This code clears stale plans off the stack. - if (should_stop) + if (should_stop) + { + ThreadPlan *plan_ptr = GetCurrentPlan(); + while (!PlanIsBasePlan(plan_ptr)) { - ThreadPlan *plan_ptr = GetCurrentPlan(); - while (!PlanIsBasePlan(plan_ptr)) - { - bool stale = plan_ptr->IsPlanStale (); - ThreadPlan *examined_plan = plan_ptr; - plan_ptr = GetPreviousPlan (examined_plan); + bool stale = plan_ptr->IsPlanStale (); + ThreadPlan *examined_plan = plan_ptr; + plan_ptr = GetPreviousPlan (examined_plan); - if (stale) - { - if (log) - log->Printf("Plan %s being discarded in cleanup, it says it is already done.", - examined_plan->GetName()); - DiscardThreadPlansUpToPlan(examined_plan); - } + if (stale) + { + if (log) + log->Printf("Plan %s being discarded in cleanup, it says it is already done.", + examined_plan->GetName()); + DiscardThreadPlansUpToPlan(examined_plan); } } - } if (log) @@ -1290,6 +1322,36 @@ Thread::SetTracer (lldb::ThreadPlanTracerSP &tracer_sp) m_plan_stack[i]->SetThreadPlanTracer(tracer_sp); } +bool +Thread::DiscardUserThreadPlansUpToIndex (uint32_t thread_index) +{ + // Count the user thread plans from the back end to get the number of the one we want + // to discard: + + uint32_t idx = 0; + ThreadPlan *up_to_plan_ptr = nullptr; + + for (ThreadPlanSP plan_sp : m_plan_stack) + { + if (plan_sp->GetPrivate()) + continue; + if (idx == thread_index) + { + up_to_plan_ptr = plan_sp.get(); + break; + } + else + idx++; + } + + if (up_to_plan_ptr == nullptr) + return false; + + DiscardThreadPlansUpToPlan(up_to_plan_ptr); + return true; +} + + void Thread::DiscardThreadPlansUpToPlan (lldb::ThreadPlanSP &up_to_plan_sp) { @@ -1483,18 +1545,16 @@ Thread::QueueThreadPlanForStepInRange LazyBool step_out_avoids_code_without_debug_info ) { - ThreadPlanSP thread_plan_sp; - ThreadPlanStepInRange *plan = new ThreadPlanStepInRange (*this, + ThreadPlanSP thread_plan_sp (new ThreadPlanStepInRange (*this, range, addr_context, stop_other_threads, step_in_avoids_code_without_debug_info, - step_out_avoids_code_without_debug_info); + step_out_avoids_code_without_debug_info)); + ThreadPlanStepInRange *plan = static_cast<ThreadPlanStepInRange *>(thread_plan_sp.get()); if (step_in_target) plan->SetStepInTarget(step_in_target); - - thread_plan_sp.reset (plan); QueueThreadPlan (thread_plan_sp, abort_other_plans); return thread_plan_sp; @@ -1546,17 +1606,18 @@ Thread::QueueThreadPlanForStepOutNoShouldStop uint32_t frame_idx ) { - ThreadPlanStepOut *new_plan = new ThreadPlanStepOut (*this, + ThreadPlanSP thread_plan_sp(new ThreadPlanStepOut (*this, addr_context, first_insn, stop_other_threads, stop_vote, run_vote, frame_idx, - eLazyBoolNo); + eLazyBoolNo)); + + ThreadPlanStepOut *new_plan = static_cast<ThreadPlanStepOut *>(thread_plan_sp.get()); new_plan->ClearShouldStopHereCallbacks(); - ThreadPlanSP thread_plan_sp(new_plan); - + if (thread_plan_sp->ValidatePlan(NULL)) { QueueThreadPlan (thread_plan_sp, abort_other_plans); @@ -1602,61 +1663,105 @@ Thread::QueueThreadPlanForStepUntil (bool abort_other_plans, } +lldb::ThreadPlanSP +Thread::QueueThreadPlanForStepScripted (bool abort_other_plans, + const char *class_name, + bool stop_other_threads) +{ + ThreadPlanSP thread_plan_sp (new ThreadPlanPython (*this, class_name)); + QueueThreadPlan (thread_plan_sp, abort_other_plans); + // This seems a little funny, but I don't want to have to split up the constructor and the + // DidPush in the scripted plan, that seems annoying. + // That means the constructor has to be in DidPush. + // So I have to validate the plan AFTER pushing it, and then take it off again... + if (!thread_plan_sp->ValidatePlan(nullptr)) + { + DiscardThreadPlansUpToPlan(thread_plan_sp); + return ThreadPlanSP(); + } + else + return thread_plan_sp; + +} + uint32_t Thread::GetIndexID () const { return m_index_id; } -void -Thread::DumpThreadPlans (lldb_private::Stream *s) const +static void +PrintPlanElement (Stream *s, const ThreadPlanSP &plan, lldb::DescriptionLevel desc_level, int32_t elem_idx) { - uint32_t stack_size = m_plan_stack.size(); - int i; - s->Indent(); - s->Printf ("Plan Stack for thread #%u: tid = 0x%4.4" PRIx64 ", stack_size = %d\n", GetIndexID(), GetID(), stack_size); - for (i = stack_size - 1; i >= 0; i--) - { s->IndentMore(); s->Indent(); - s->Printf ("Element %d: ", i); - m_plan_stack[i]->GetDescription (s, eDescriptionLevelFull); + s->Printf ("Element %d: ", elem_idx); + plan->GetDescription (s, desc_level); s->EOL(); s->IndentLess(); +} + +static void +PrintPlanStack (Stream *s, const std::vector<lldb::ThreadPlanSP> &plan_stack, lldb::DescriptionLevel desc_level, bool include_internal) +{ + int32_t print_idx = 0; + for (ThreadPlanSP plan_sp : plan_stack) + { + if (include_internal || !plan_sp->GetPrivate()) + { + PrintPlanElement (s, plan_sp, desc_level, print_idx++); + } } +} - stack_size = m_completed_plan_stack.size(); - if (stack_size > 0) +void +Thread::DumpThreadPlans (Stream *s, + lldb::DescriptionLevel desc_level, + bool include_internal, + bool ignore_boring_threads) const +{ + uint32_t stack_size; + + if (ignore_boring_threads) { - s->Indent(); - s->Printf ("Completed Plan Stack: %d elements.\n", stack_size); - for (i = stack_size - 1; i >= 0; i--) + uint32_t stack_size = m_plan_stack.size(); + uint32_t completed_stack_size = m_completed_plan_stack.size(); + uint32_t discarded_stack_size = m_discarded_plan_stack.size(); + if (stack_size == 1 && completed_stack_size == 0 && discarded_stack_size == 0) { + s->Printf ("thread #%u: tid = 0x%4.4" PRIx64 "\n", GetIndexID(), GetID()); s->IndentMore(); s->Indent(); - s->Printf ("Element %d: ", i); - m_completed_plan_stack[i]->GetDescription (s, eDescriptionLevelFull); - s->EOL(); + s->Printf("No active thread plans\n"); s->IndentLess(); + return; } } + s->Indent(); + s->Printf ("thread #%u: tid = 0x%4.4" PRIx64 ":\n", GetIndexID(), GetID()); + s->IndentMore(); + s->Indent(); + s->Printf ("Active plan stack:\n"); + PrintPlanStack (s, m_plan_stack, desc_level, include_internal); + + stack_size = m_completed_plan_stack.size(); + if (stack_size > 0) + { + s->Indent(); + s->Printf ("Completed Plan Stack:\n"); + PrintPlanStack (s, m_completed_plan_stack, desc_level, include_internal); + } + stack_size = m_discarded_plan_stack.size(); if (stack_size > 0) { s->Indent(); - s->Printf ("Discarded Plan Stack: %d elements.\n", stack_size); - for (i = stack_size - 1; i >= 0; i--) - { - s->IndentMore(); - s->Indent(); - s->Printf ("Element %d: ", i); - m_discarded_plan_stack[i]->GetDescription (s, eDescriptionLevelFull); - s->EOL(); - s->IndentLess(); - } + s->Printf ("Discarded Plan Stack:\n"); + PrintPlanStack (s, m_discarded_plan_stack, desc_level, include_internal); } + s->IndentLess(); } TargetSP @@ -1785,7 +1890,7 @@ Thread::ReturnFromFrame (lldb::StackFrameSP frame_sp, lldb::ValueObjectSP return // FIXME: ValueObject::Cast doesn't currently work correctly, at least not for scalars. // Turn that back on when that works. - if (0 && sc.function != NULL) + if (/* DISABLES CODE */ (0) && sc.function != NULL) { Type *function_type = sc.function->GetType(); if (function_type) @@ -2011,6 +2116,7 @@ Thread::StopReasonAsCString (lldb::StopReason reason) case eStopReasonExec: return "exec"; case eStopReasonPlanComplete: return "plan complete"; case eStopReasonThreadExiting: return "thread exiting"; + case eStopReasonInstrumentation: return "instrumentation break"; } @@ -2090,17 +2196,28 @@ Thread::GetStatus (Stream &strm, uint32_t start_frame, uint32_t num_frames, uint } bool -Thread::GetDescription (Stream &strm, lldb::DescriptionLevel level, bool print_json) +Thread::GetDescription (Stream &strm, lldb::DescriptionLevel level, bool print_json_thread, bool print_json_stopinfo) { DumpUsingSettingsFormat (strm, 0); strm.Printf("\n"); StructuredData::ObjectSP thread_info = GetExtendedInfo(); - - if (thread_info && print_json) + StructuredData::ObjectSP stop_info = m_stop_info_sp->GetExtendedInfo(); + + if (print_json_thread || print_json_stopinfo) { - thread_info->Dump (strm); - strm.Printf("\n"); + if (thread_info && print_json_thread) + { + thread_info->Dump (strm); + strm.Printf("\n"); + } + + if (stop_info && print_json_stopinfo) + { + stop_info->Dump (strm); + strm.Printf("\n"); + } + return true; } @@ -2194,6 +2311,8 @@ Thread::GetUnwinder () case llvm::Triple::aarch64: case llvm::Triple::thumb: case llvm::Triple::mips64: + case llvm::Triple::ppc: + case llvm::Triple::ppc64: case llvm::Triple::hexagon: m_unwinder_ap.reset (new UnwindLLDB (*this)); break; |