Author: jingham Date: Tue Aug 5 20:49:59 2014 New Revision: 214946 URL: http://llvm.org/viewvc/llvm-project?rev=214946&view=rev Log: 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> Modified: lldb/trunk/include/lldb/Target/ThreadPlanStepRange.h lldb/trunk/include/lldb/lldb-enumerations.h lldb/trunk/source/Target/ThreadPlanShouldStopHere.cpp lldb/trunk/source/Target/ThreadPlanStepInRange.cpp lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp lldb/trunk/source/Target/ThreadPlanStepRange.cpp Modified: lldb/trunk/include/lldb/Target/ThreadPlanStepRange.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanStepRange.h?rev=214946&r1=214945&r2=214946&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/ThreadPlanStepRange.h (original) +++ lldb/trunk/include/lldb/Target/ThreadPlanStepRange.h Tue Aug 5 20:49:59 2014 @@ -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. Modified: lldb/trunk/include/lldb/lldb-enumerations.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-enumerations.h?rev=214946&r1=214945&r2=214946&view=diff ============================================================================== --- lldb/trunk/include/lldb/lldb-enumerations.h (original) +++ lldb/trunk/include/lldb/lldb-enumerations.h Tue Aug 5 20:49:59 2014 @@ -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; Modified: lldb/trunk/source/Target/ThreadPlanShouldStopHere.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanShouldStopHere.cpp?rev=214946&r1=214945&r2=214946&view=diff ============================================================================== --- lldb/trunk/source/Target/ThreadPlanShouldStopHere.cpp (original) +++ lldb/trunk/source/Target/ThreadPlanShouldStopHere.cpp Tue Aug 5 20:49:59 2014 @@ -82,7 +82,8 @@ ThreadPlanShouldStopHere::DefaultShouldS 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()) { Modified: lldb/trunk/source/Target/ThreadPlanStepInRange.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepInRange.cpp?rev=214946&r1=214945&r2=214946&view=diff ============================================================================== --- lldb/trunk/source/Target/ThreadPlanStepInRange.cpp (original) +++ lldb/trunk/source/Target/ThreadPlanStepInRange.cpp Tue Aug 5 20:49:59 2014 @@ -190,7 +190,7 @@ ThreadPlanStepInRange::ShouldStop (Event 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 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::DefaultShouldStop 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()) Modified: lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp?rev=214946&r1=214945&r2=214946&view=diff ============================================================================== --- lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp (original) +++ lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp Tue Aug 5 20:49:59 2014 @@ -90,6 +90,10 @@ ThreadPlanStepOverRange::SetupAvoidNoDeb 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 Modified: lldb/trunk/source/Target/ThreadPlanStepRange.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepRange.cpp?rev=214946&r1=214945&r2=214946&view=diff ============================================================================== --- lldb/trunk/source/Target/ThreadPlanStepRange.cpp (original) +++ lldb/trunk/source/Target/ThreadPlanStepRange.cpp Tue Aug 5 20:49:59 2014 @@ -50,6 +50,7 @@ ThreadPlanStepRange::ThreadPlanStepRange 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 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::CompareCurrentFrame } 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; } _______________________________________________ lldb-commits mailing list lldb-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits