forked from OSchip/llvm-project
When stepping, handle the case where the step leaves us with
the same parent frame, but different current frame - e.g. when you step past a tail call exit from a function. Apply the same "avoid-no-debug" rules to this case as for a "step-in". <rdar://problem/16189225> llvm-svn: 214946
This commit is contained in:
parent
515c24b7e0
commit
862d1bbdf6
|
@ -77,6 +77,7 @@ protected:
|
|||
std::vector<AddressRange> m_address_ranges;
|
||||
lldb::RunMode m_stop_others;
|
||||
StackID m_stack_id; // Use the stack ID so we can tell step out from step in.
|
||||
StackID m_parent_stack_id; // Use the parent stack ID so we can identify tail calls and the like.
|
||||
bool m_no_more_plans; // Need this one so we can tell if we stepped into a call,
|
||||
// but can't continue, in which case we are done.
|
||||
bool m_first_run_event; // We want to broadcast only one running event, our first.
|
||||
|
|
|
@ -682,14 +682,22 @@ namespace lldb {
|
|||
} TypeOptions;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// This is the return value for frame comparisons. When frame A pushes
|
||||
// frame B onto the stack, frame A is OLDER than frame B.
|
||||
// This is the return value for frame comparisons. If you are comparing frame A to frame B
|
||||
// the following cases arise:
|
||||
// 1) When frame A pushes frame B (or a frame that ends up pushing B) A is Older than B.
|
||||
// 2) When frame A pushed frame B (or if frame A is on the stack but B is not) A is Younger than B
|
||||
// 3) When frame A and frame B have the same StackID, they are Equal.
|
||||
// 4) When frame A and frame B have the same immediate parent frame, but are not equal, the comparision yields
|
||||
// SameParent.
|
||||
// 5) If the two frames are on different threads or processes the comparision is Invalid
|
||||
// 6) If for some reason we can't figure out what went on, we return Unknown.
|
||||
//----------------------------------------------------------------------
|
||||
typedef enum FrameComparison
|
||||
{
|
||||
eFrameCompareInvalid,
|
||||
eFrameCompareUnknown,
|
||||
eFrameCompareEqual,
|
||||
eFrameCompareSameParent,
|
||||
eFrameCompareYounger,
|
||||
eFrameCompareOlder
|
||||
} FrameComparison;
|
||||
|
|
|
@ -82,7 +82,8 @@ ThreadPlanShouldStopHere::DefaultShouldStopHereCallback (ThreadPlan *current_pla
|
|||
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
|
||||
|
||||
if ((operation == eFrameCompareOlder && flags.Test(eStepOutAvoidNoDebug))
|
||||
|| (operation == eFrameCompareYounger && flags.Test(eStepInAvoidNoDebug)))
|
||||
|| (operation == eFrameCompareYounger && flags.Test(eStepInAvoidNoDebug))
|
||||
|| (operation == eFrameCompareSameParent && flags.Test(eStepInAvoidNoDebug)))
|
||||
{
|
||||
if (!frame->HasDebugInformation())
|
||||
{
|
||||
|
|
|
@ -190,7 +190,7 @@ ThreadPlanStepInRange::ShouldStop (Event *event_ptr)
|
|||
|
||||
FrameComparison frame_order = CompareCurrentFrameToStartFrame();
|
||||
|
||||
if (frame_order == eFrameCompareOlder)
|
||||
if (frame_order == eFrameCompareOlder || frame_order == eFrameCompareSameParent)
|
||||
{
|
||||
// If we're in an older frame then we should stop.
|
||||
//
|
||||
|
@ -201,7 +201,7 @@ ThreadPlanStepInRange::ShouldStop (Event *event_ptr)
|
|||
if (!m_sub_plan_sp)
|
||||
{
|
||||
// Otherwise check the ShouldStopHere for step out:
|
||||
m_sub_plan_sp = CheckShouldStopHereAndQueueStepOut(eFrameCompareOlder);
|
||||
m_sub_plan_sp = CheckShouldStopHereAndQueueStepOut(frame_order);
|
||||
if (log)
|
||||
log->Printf ("ShouldStopHere says we should step out of this frame.");
|
||||
}
|
||||
|
@ -402,6 +402,7 @@ ThreadPlanStepInRange::DefaultShouldStopHereCallback (ThreadPlan *current_plan,
|
|||
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
|
||||
|
||||
if ((operation == eFrameCompareYounger && flags.Test(eStepInAvoidNoDebug))
|
||||
|| (operation == eFrameCompareSameParent && flags.Test(eStepOutAvoidNoDebug))
|
||||
|| (operation == eFrameCompareOlder && flags.Test(eStepOutAvoidNoDebug)))
|
||||
{
|
||||
if (!frame->HasDebugInformation())
|
||||
|
|
|
@ -90,6 +90,10 @@ ThreadPlanStepOverRange::SetupAvoidNoDebug(LazyBool step_out_avoids_code_without
|
|||
GetFlags().Set (ThreadPlanShouldStopHere::eStepOutAvoidNoDebug);
|
||||
else
|
||||
GetFlags().Clear (ThreadPlanShouldStopHere::eStepOutAvoidNoDebug);
|
||||
// Step Over plans should always avoid no-debug on step in. Seems like you shouldn't
|
||||
// have to say this, but a tail call looks more like a step in that a step out, so
|
||||
// we want to catch this case.
|
||||
GetFlags().Set (ThreadPlanShouldStopHere::eStepInAvoidNoDebug);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -50,6 +50,7 @@ ThreadPlanStepRange::ThreadPlanStepRange (ThreadPlanKind kind,
|
|||
m_address_ranges (),
|
||||
m_stop_others (stop_others),
|
||||
m_stack_id (),
|
||||
m_parent_stack_id(),
|
||||
m_no_more_plans (false),
|
||||
m_first_run_event (true),
|
||||
m_use_fast_step(false)
|
||||
|
@ -57,6 +58,7 @@ ThreadPlanStepRange::ThreadPlanStepRange (ThreadPlanKind kind,
|
|||
m_use_fast_step = GetTarget().GetUseFastStepping();
|
||||
AddRange(range);
|
||||
m_stack_id = m_thread.GetStackFrameAtIndex(0)->GetStackID();
|
||||
m_parent_stack_id = m_thread.GetStackFrameAtIndex(1)->GetStackID();
|
||||
}
|
||||
|
||||
ThreadPlanStepRange::~ThreadPlanStepRange ()
|
||||
|
@ -270,7 +272,13 @@ ThreadPlanStepRange::CompareCurrentFrameToStartFrame()
|
|||
}
|
||||
else
|
||||
{
|
||||
frame_order = eFrameCompareOlder;
|
||||
StackID cur_parent_id = m_thread.GetStackFrameAtIndex(1)->GetStackID();
|
||||
if (m_parent_stack_id.IsValid()
|
||||
&& cur_parent_id.IsValid()
|
||||
&& m_parent_stack_id == cur_parent_id)
|
||||
frame_order = eFrameCompareSameParent;
|
||||
else
|
||||
frame_order = eFrameCompareOlder;
|
||||
}
|
||||
return frame_order;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue