summaryrefslogtreecommitdiffstats
path: root/lldb/source/Target/ThreadPlanStepThrough.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Target/ThreadPlanStepThrough.cpp')
-rw-r--r--lldb/source/Target/ThreadPlanStepThrough.cpp68
1 files changed, 41 insertions, 27 deletions
diff --git a/lldb/source/Target/ThreadPlanStepThrough.cpp b/lldb/source/Target/ThreadPlanStepThrough.cpp
index 3c4824153cb..003d199e379 100644
--- a/lldb/source/Target/ThreadPlanStepThrough.cpp
+++ b/lldb/source/Target/ThreadPlanStepThrough.cpp
@@ -32,11 +32,12 @@ using namespace lldb_private;
// FIXME: At present only handles DYLD trampolines.
//----------------------------------------------------------------------
-ThreadPlanStepThrough::ThreadPlanStepThrough (Thread &thread, bool stop_others) :
+ThreadPlanStepThrough::ThreadPlanStepThrough (Thread &thread, StackID &m_stack_id, bool stop_others) :
ThreadPlan (ThreadPlan::eKindStepThrough, "Step through trampolines and prologues", thread, eVoteNoOpinion, eVoteNoOpinion),
m_start_address (0),
m_backstop_bkpt_id (LLDB_INVALID_BREAK_ID),
m_backstop_addr(LLDB_INVALID_ADDRESS),
+ m_return_stack_id (m_stack_id),
m_stop_others (stop_others)
{
@@ -46,12 +47,11 @@ ThreadPlanStepThrough::ThreadPlanStepThrough (Thread &thread, bool stop_others)
if (m_sub_plan_sp)
{
m_start_address = GetThread().GetRegisterContext()->GetPC(0);
- m_stack_id = m_thread.GetStackFrameAtIndex(0)->GetStackID();
// We are going to return back to the concrete frame 1, we might pass by some inlined code that we're in
// the middle of by doing this, but it's easier than trying to figure out where the inlined code might return to.
- StackFrameSP return_frame_sp (m_thread.GetFrameWithConcreteFrameIndex(1));
+ StackFrameSP return_frame_sp = m_thread.GetFrameWithStackID (m_stack_id);
if (return_frame_sp)
{
@@ -73,11 +73,7 @@ ThreadPlanStepThrough::ThreadPlanStepThrough (Thread &thread, bool stop_others)
ThreadPlanStepThrough::~ThreadPlanStepThrough ()
{
- if (m_backstop_bkpt_id != LLDB_INVALID_BREAK_ID)
- {
- m_thread.GetProcess()->GetTarget().RemoveBreakpointByID (m_backstop_bkpt_id);
- m_backstop_bkpt_id = LLDB_INVALID_BREAK_ID;
- }
+ ClearBackstopBreakpoint ();
}
void
@@ -161,6 +157,13 @@ ThreadPlanStepThrough::ShouldStop (Event *event_ptr)
if (IsPlanComplete())
return true;
+ // First, did we hit the backstop breakpoint?
+ if (HitOurBackstopBreakpoint())
+ {
+ SetPlanComplete(false);
+ return true;
+ }
+
// If we don't have a sub-plan, then we're also done (can't see how we would ever get here
// without a plan, but just in case.
@@ -170,20 +173,27 @@ ThreadPlanStepThrough::ShouldStop (Event *event_ptr)
return true;
}
- // First, did we hit the backstop breakpoint?
- if (HitOurBackstopBreakpoint())
- {
- SetPlanComplete();
- return true;
- }
-
-
// If the current sub plan is not done, we don't want to stop. Actually, we probably won't
// ever get here in this state, since we generally won't get asked any questions if out
// current sub-plan is not done...
if (!m_sub_plan_sp->IsPlanComplete())
+ return false;
+
+ // If our current sub plan failed, then let's just run to our backstop. If we can't do that then just stop.
+ if (!m_sub_plan_sp->PlanSucceeded())
+ {
+ if (m_backstop_bkpt_id != LLDB_INVALID_BREAK_ID)
+ {
+ m_sub_plan_sp.reset();
return false;
-
+ }
+ else
+ {
+ SetPlanComplete(false);
+ return true;
+ }
+ }
+
// Next see if there is a specific step through plan at our current pc (these might
// chain, for instance stepping through a dylib trampoline to the objc dispatch function...)
LookForPlanToStepThroughFromCurrentPC();
@@ -208,7 +218,7 @@ ThreadPlanStepThrough::StopOthers ()
StateType
ThreadPlanStepThrough::GetPlanRunState ()
{
- return eStateStepping;
+ return eStateRunning;
}
bool
@@ -224,14 +234,21 @@ ThreadPlanStepThrough::WillStop ()
return true;
}
+void
+ThreadPlanStepThrough::ClearBackstopBreakpoint ()
+{
+ if (m_backstop_bkpt_id != LLDB_INVALID_BREAK_ID)
+ {
+ m_thread.GetProcess()->GetTarget().RemoveBreakpointByID (m_backstop_bkpt_id);
+ m_backstop_bkpt_id = LLDB_INVALID_BREAK_ID;
+ }
+}
+
bool
ThreadPlanStepThrough::MischiefManaged ()
{
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
- // ShouldStop will call HappyToStopHere, which will set the plan to complete if
- // we're done. So we can just check that here.
-
if (!IsPlanComplete())
{
return false;
@@ -240,12 +257,9 @@ ThreadPlanStepThrough::MischiefManaged ()
{
if (log)
log->Printf("Completed step through step plan.");
+
+ ClearBackstopBreakpoint ();
ThreadPlan::MischiefManaged ();
- if (m_backstop_bkpt_id != LLDB_INVALID_BREAK_ID)
- {
- m_thread.GetProcess()->GetTarget().RemoveBreakpointByID (m_backstop_bkpt_id);
- m_backstop_bkpt_id = LLDB_INVALID_BREAK_ID;
- }
return true;
}
}
@@ -262,7 +276,7 @@ ThreadPlanStepThrough::HitOurBackstopBreakpoint()
{
StackID cur_frame_zero_id = m_thread.GetStackFrameAtIndex(0)->GetStackID();
- if (cur_frame_zero_id == m_stack_id)
+ if (cur_frame_zero_id == m_return_stack_id)
{
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
if (log)
OpenPOWER on IntegriCloud