summaryrefslogtreecommitdiffstats
path: root/lldb/source/Target/Thread.cpp
diff options
context:
space:
mode:
authorJim Ingham <jingham@apple.com>2011-12-03 01:52:59 +0000
committerJim Ingham <jingham@apple.com>2011-12-03 01:52:59 +0000
commit25f66700038aecf35396c15ee6bdedc98ea04e8f (patch)
treeaea2acb33a41048b50f3b4cf2c6d85a4cb7acdb3 /lldb/source/Target/Thread.cpp
parent26c5df4733b7c83f5ca6a4ab11fb4a36c371fe26 (diff)
downloadbcm5719-llvm-25f66700038aecf35396c15ee6bdedc98ea04e8f.tar.gz
bcm5719-llvm-25f66700038aecf35396c15ee6bdedc98ea04e8f.zip
Make the ThreadPlanStepThrough set a backstop breakpoint on the return address from
the function it is being asked to step through, so that even if we get the trampoline target wrong (for instance) we will still not lose control. The other fix here is to tighten up the handling of the case where the current plan doesn't explain the stop, but a plan above us does. In that case, if the plan that does explain the stop says it is done, we need to clean up the plans below it and continue on with our processing. llvm-svn: 145740
Diffstat (limited to 'lldb/source/Target/Thread.cpp')
-rw-r--r--lldb/source/Target/Thread.cpp93
1 files changed, 57 insertions, 36 deletions
diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp
index b51356a579f..e4415b7b73e 100644
--- a/lldb/source/Target/Thread.cpp
+++ b/lldb/source/Target/Thread.cpp
@@ -272,7 +272,59 @@ Thread::ShouldStop (Event* event_ptr)
// The top most plan always gets to do the trace log...
current_plan->DoTraceLog ();
- if (current_plan->PlanExplainsStop())
+ // If the base plan doesn't understand why we stopped, then we have to find a plan that does.
+ // If that plan is still working, then we don't need to do any more work. If the plan that explains
+ // the stop is done, then we should pop all the plans below it, and pop it, and then let the plans above it decide
+ // whether they still need to do more work.
+
+ bool done_processing_current_plan = false;
+
+ if (!current_plan->PlanExplainsStop())
+ {
+ if (current_plan->TracerExplainsStop())
+ {
+ done_processing_current_plan = true;
+ should_stop = false;
+ }
+ else
+ {
+ // If the current plan doesn't explain the stop, then, find one that
+ // does and let it handle the situation.
+ ThreadPlan *plan_ptr = current_plan;
+ while ((plan_ptr = GetPreviousPlan(plan_ptr)) != NULL)
+ {
+ if (plan_ptr->PlanExplainsStop())
+ {
+ should_stop = plan_ptr->ShouldStop (event_ptr);
+
+ // plan_ptr explains the stop, next check whether plan_ptr is done, if so, then we should take it
+ // and all the plans below it off the stack.
+
+ if (plan_ptr->MischiefManaged())
+ {
+ // We're going to pop the plans up to AND INCLUDING the plan that explains the stop.
+ plan_ptr = GetPreviousPlan(plan_ptr);
+
+ do
+ {
+ if (should_stop)
+ current_plan->WillStop();
+ PopPlan();
+ }
+ while ((current_plan = GetCurrentPlan()) != plan_ptr);
+ done_processing_current_plan = false;
+ }
+ else
+ done_processing_current_plan = true;
+
+ break;
+ }
+
+ }
+ }
+ }
+
+ if (!done_processing_current_plan)
{
bool over_ride_stop = current_plan->ShouldAutoContinue(event_ptr);
@@ -333,25 +385,6 @@ Thread::ShouldStop (Event* event_ptr)
if (over_ride_stop)
should_stop = false;
}
- else if (current_plan->TracerExplainsStop())
- {
- should_stop = false;
- }
- else
- {
- // If the current plan doesn't explain the stop, then, find one that
- // does and let it handle the situation.
- ThreadPlan *plan_ptr = current_plan;
- while ((plan_ptr = GetPreviousPlan(plan_ptr)) != NULL)
- {
- if (plan_ptr->PlanExplainsStop())
- {
- should_stop = plan_ptr->ShouldStop (event_ptr);
- break;
- }
-
- }
- }
if (log)
{
@@ -797,22 +830,10 @@ Thread::QueueThreadPlanForStepOut
ThreadPlan *
Thread::QueueThreadPlanForStepThrough (bool abort_other_plans, bool stop_other_threads)
{
- // Try the dynamic loader first:
- ThreadPlanSP thread_plan_sp(GetProcess().GetDynamicLoader()->GetStepThroughTrampolinePlan (*this, stop_other_threads));
- // If that didn't come up with anything, try the ObjC runtime plugin:
- if (thread_plan_sp.get() == NULL)
- {
- ObjCLanguageRuntime *objc_runtime = GetProcess().GetObjCLanguageRuntime();
- if (objc_runtime)
- thread_plan_sp = objc_runtime->GetStepThroughTrampolinePlan (*this, stop_other_threads);
- }
-
- if (thread_plan_sp.get() == NULL)
- {
- thread_plan_sp.reset(new ThreadPlanStepThrough (*this, stop_other_threads));
- if (thread_plan_sp && !thread_plan_sp->ValidatePlan (NULL))
- return NULL;
- }
+ ThreadPlanSP thread_plan_sp(new ThreadPlanStepThrough (*this, stop_other_threads));
+ if (!thread_plan_sp || !thread_plan_sp->ValidatePlan (NULL))
+ return NULL;
+
QueueThreadPlan (thread_plan_sp, abort_other_plans);
return thread_plan_sp.get();
}
OpenPOWER on IntegriCloud