aboutsummaryrefslogtreecommitdiff
path: root/source/Target/Thread.cpp
diff options
context:
space:
mode:
authorEd Maste <emaste@FreeBSD.org>2015-02-06 21:38:51 +0000
committerEd Maste <emaste@FreeBSD.org>2015-02-06 21:38:51 +0000
commit205afe679855a4ce8149cdaa94d3f0868ce796dc (patch)
tree09bc83f73246ee3c7a779605cd0122093d2a8a19 /source/Target/Thread.cpp
parent0cac4ca3916ac24ab6139d03cbfd18db9e715bfe (diff)
downloadsrc-205afe679855a4ce8149cdaa94d3f0868ce796dc.tar.gz
src-205afe679855a4ce8149cdaa94d3f0868ce796dc.zip
Import LLDB as of upstream SVN r225923 (git 2b588ecd)vendor/lldb/lldb-r225923
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
Notes
Notes: svn path=/vendor/lldb/dist/; revision=278332 svn path=/vendor/lldb/lldb-r225923/; revision=278333; tag=vendor/lldb/lldb-r225923
Diffstat (limited to 'source/Target/Thread.cpp')
-rw-r--r--source/Target/Thread.cpp259
1 files changed, 189 insertions, 70 deletions
diff --git a/source/Target/Thread.cpp b/source/Target/Thread.cpp
index a445517da6a8..b532d8d71c8f 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;