[Lldb-commits] [lldb] r151780 - in /lldb/trunk: include/lldb/Target/StackID.h include/lldb/Target/ThreadPlan.h include/lldb/Target/ThreadPlanStepOut.h include/lldb/Target/ThreadPlanStepRange.h include/lldb/Target/ThreadPlanStepUntil.h include/lldb/lldb-enumerations.h source/Target/StackID.cpp source/Target/ThreadPlan.cpp source/Target/ThreadPlanStepInRange.cpp source/Target/ThreadPlanStepOut.cpp source/Target/ThreadPlanStepOverRange.cpp source/Target/ThreadPlanStepRange.cpp source/Target/ThreadPlanStepUntil.cpp

Jim Ingham jingham at apple.com
Wed Feb 29 16:50:51 PST 2012


Author: jingham
Date: Wed Feb 29 18:50:50 2012
New Revision: 151780

URL: http://llvm.org/viewvc/llvm-project?rev=151780&view=rev
Log:
Convert the thread plans over from using the stack count to do their logic to using StackID's.  This
should be more efficient.

Modified:
    lldb/trunk/include/lldb/Target/StackID.h
    lldb/trunk/include/lldb/Target/ThreadPlan.h
    lldb/trunk/include/lldb/Target/ThreadPlanStepOut.h
    lldb/trunk/include/lldb/Target/ThreadPlanStepRange.h
    lldb/trunk/include/lldb/Target/ThreadPlanStepUntil.h
    lldb/trunk/include/lldb/lldb-enumerations.h
    lldb/trunk/source/Target/StackID.cpp
    lldb/trunk/source/Target/ThreadPlan.cpp
    lldb/trunk/source/Target/ThreadPlanStepInRange.cpp
    lldb/trunk/source/Target/ThreadPlanStepOut.cpp
    lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp
    lldb/trunk/source/Target/ThreadPlanStepRange.cpp
    lldb/trunk/source/Target/ThreadPlanStepUntil.cpp

Modified: lldb/trunk/include/lldb/Target/StackID.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StackID.h?rev=151780&r1=151779&r2=151780&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/StackID.h (original)
+++ lldb/trunk/include/lldb/Target/StackID.h Wed Feb 29 18:50:50 2012
@@ -140,6 +140,8 @@
 
 bool operator== (const StackID& lhs, const StackID& rhs);
 bool operator!= (const StackID& lhs, const StackID& rhs);
+
+// frame_id_1 < frame_id_2 means "frame_id_1 is YOUNGER than frame_id_2"
 bool operator<  (const StackID& lhs, const StackID& rhs);
 
 } // namespace lldb_private

Modified: lldb/trunk/include/lldb/Target/ThreadPlan.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlan.h?rev=151780&r1=151779&r2=151780&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlan.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlan.h Wed Feb 29 18:50:50 2012
@@ -423,7 +423,6 @@
     virtual lldb::StateType
     GetPlanRunState () = 0;
 
-
     Thread &m_thread;
     Vote m_stop_vote;
     Vote m_run_vote;

Modified: lldb/trunk/include/lldb/Target/ThreadPlanStepOut.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanStepOut.h?rev=151780&r1=151779&r2=151780&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlanStepOut.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlanStepOut.h Wed Feb 29 18:50:50 2012
@@ -50,11 +50,12 @@
 
 protected:
     bool QueueInlinedStepPlan (bool queue_now);
-    
+
 private:
     SymbolContext *m_step_from_context;
     lldb::addr_t m_step_from_insn;
-    uint32_t m_stack_depth;
+    StackID  m_step_out_to_id;
+    StackID  m_immediate_step_from_id;
     lldb::break_id_t m_return_bp_id;
     lldb::addr_t m_return_addr;
     bool m_first_insn;

Modified: lldb/trunk/include/lldb/Target/ThreadPlanStepRange.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanStepRange.h?rev=151780&r1=151779&r2=151780&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlanStepRange.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlanStepRange.h Wed Feb 29 18:50:50 2012
@@ -48,15 +48,13 @@
 protected:
 
     bool InRange();
-    bool FrameIsYounger();
-    bool FrameIsOlder();
+    lldb::FrameComparison CompareCurrentFrameToStartFrame();
     bool InSymbol();
     void DumpRanges (Stream *s);
     
     SymbolContext m_addr_context;
     std::vector<AddressRange> m_address_ranges;
     lldb::RunMode m_stop_others;
-    uint32_t m_stack_depth;
     StackID m_stack_id;    // Use the stack ID so we can tell step out from step in.
     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.

Modified: lldb/trunk/include/lldb/Target/ThreadPlanStepUntil.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanStepUntil.h?rev=151780&r1=151779&r2=151780&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlanStepUntil.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlanStepUntil.h Wed Feb 29 18:50:50 2012
@@ -51,7 +51,7 @@
 
 private:
 
-    uint64_t m_stack_depth;
+    StackID m_stack_id;
     lldb::addr_t m_step_from_insn;
     lldb::break_id_t m_return_bp_id;
     lldb::addr_t m_return_addr;

Modified: lldb/trunk/include/lldb/lldb-enumerations.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-enumerations.h?rev=151780&r1=151779&r2=151780&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-enumerations.h (original)
+++ lldb/trunk/include/lldb/lldb-enumerations.h Wed Feb 29 18:50:50 2012
@@ -615,7 +615,20 @@
         eTypeOptionShowOneLiner    = (1u << 5),
         eTypeOptionHideNames       = (1u << 6)
     } 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.
+   //----------------------------------------------------------------------
+   typedef enum FrameComparison
+   {
+       eFrameCompareInvalid,
+       eFrameCompareUnknown,
+       eFrameCompareEqual,
+       eFrameCompareYounger,
+       eFrameCompareOlder
+   } FrameComparison;
+   
 } // namespace lldb
 
 

Modified: lldb/trunk/source/Target/StackID.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackID.cpp?rev=151780&r1=151779&r2=151780&view=diff
==============================================================================
--- lldb/trunk/source/Target/StackID.cpp (original)
+++ lldb/trunk/source/Target/StackID.cpp Wed Feb 29 18:50:50 2012
@@ -75,6 +75,12 @@
     const lldb::addr_t lhs_cfa = lhs.GetCallFrameAddress();
     const lldb::addr_t rhs_cfa = rhs.GetCallFrameAddress();
     
+    // FIXME: We are assuming that the stacks grow downward in memory.  That's not necessary, but true on
+    // all the machines we care about at present.  If this changes, we'll have to deal with that.  The ABI is the
+    // agent who knows this ordering, but the StackID has no access to the ABI.  The most straightforward way
+    // to handle this is to add a "m_grows_downward" bool to the StackID, and set it in the constructor.  
+    // But I'm not going to waste a bool per StackID on this till we need it.
+    
     if (lhs_cfa != rhs_cfa)
         return lhs_cfa < rhs_cfa;
 

Modified: lldb/trunk/source/Target/ThreadPlan.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlan.cpp?rev=151780&r1=151779&r2=151780&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlan.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlan.cpp Wed Feb 29 18:50:50 2012
@@ -101,7 +101,8 @@
         {
             Vote prev_vote = prev_plan->ShouldReportStop (event_ptr);
             if (log)
-                log->Printf ("ThreadPlan::ShouldReportStop() returning previous thread plan vote: %s", GetVoteAsCString (prev_vote));
+                log->Printf ("ThreadPlan::ShouldReportStop() returning previous thread plan vote: %s", 
+                             GetVoteAsCString (prev_vote));
             return prev_vote;
         }
     }
@@ -153,7 +154,8 @@
             addr_t pc = reg_ctx->GetPC();
             addr_t sp = reg_ctx->GetSP();
             addr_t fp = reg_ctx->GetFP();
-            log->Printf("%s Thread #%u: tid = 0x%4.4llx, pc = 0x%8.8llx, sp = 0x%8.8llx, fp = 0x%8.8llx, plan = '%s', state = %s, stop others = %d", 
+            log->Printf("%s Thread #%u: tid = 0x%4.4llx, pc = 0x%8.8llx, sp = 0x%8.8llx, fp = 0x%8.8llx, "
+                        "plan = '%s', state = %s, stop others = %d", 
                         __FUNCTION__,
                         m_thread.GetIndexID(), 
                         m_thread.GetID(),  

Modified: lldb/trunk/source/Target/ThreadPlanStepInRange.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepInRange.cpp?rev=151780&r1=151779&r2=151780&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanStepInRange.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanStepInRange.cpp Wed Feb 29 18:50:50 2012
@@ -130,7 +130,9 @@
     else
         stop_others = false;
         
-    if (FrameIsOlder())
+    FrameComparison frame_order = CompareCurrentFrameToStartFrame();
+    
+    if (frame_order == eFrameCompareOlder)
     {
         // If we're in an older frame then we should stop.
         //
@@ -146,7 +148,7 @@
         }
 
     }
-    else if (!FrameIsYounger() && InSymbol())
+    else if (frame_order != eFrameCompareYounger && InSymbol())
     {
         // If we are not in a place we should step through, we're done.
         // One tricky bit here is that some stubs don't push a frame, so we have to check
@@ -174,13 +176,13 @@
     
     // If not, give the "should_stop" callback a chance to push a plan to get us out of here.
     // But only do that if we actually have stepped in.
-    if (!new_plan && FrameIsYounger())
+    if (!new_plan && frame_order == eFrameCompareYounger)
         new_plan = InvokeShouldStopHereCallback();
 
     // If we've stepped in and we are going to stop here, check to see if we were asked to
     // run past the prologue, and if so do that.
     
-    if (new_plan == NULL && FrameIsYounger() && m_step_past_prologue)
+    if (new_plan == NULL && frame_order == eFrameCompareYounger && m_step_past_prologue)
     {
         lldb::StackFrameSP curr_frame = m_thread.GetStackFrameAtIndex(0);
         if (curr_frame)

Modified: lldb/trunk/source/Target/ThreadPlanStepOut.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepOut.cpp?rev=151780&r1=151779&r2=151780&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanStepOut.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanStepOut.cpp Wed Feb 29 18:50:50 2012
@@ -30,7 +30,6 @@
 //----------------------------------------------------------------------
 // ThreadPlanStepOut: Step out of the current frame
 //----------------------------------------------------------------------
-
 ThreadPlanStepOut::ThreadPlanStepOut
 (
     Thread &thread,
@@ -58,7 +57,10 @@
     StackFrameSP return_frame_sp (m_thread.GetStackFrameAtIndex(frame_idx + 1));
     StackFrameSP immediate_return_from_sp (m_thread.GetStackFrameAtIndex (frame_idx));
     
-    m_stack_depth = m_thread.GetStackFrameCount() - frame_idx;
+    m_step_out_to_id = return_frame_sp->GetStackID();
+    m_immediate_step_from_id = immediate_return_from_sp->GetStackID();
+    
+    StackID frame_zero_id = m_thread.GetStackFrameAtIndex(0)->GetStackID();
 
     // If the frame directly below the one we are returning to is inlined, we have to be
     // a little more careful.  It is non-trivial to determine the real "return code address" for
@@ -69,7 +71,13 @@
         {
             // First queue a plan that gets us to this inlined frame, and when we get there we'll queue a second
             // plan that walks us out of this frame.
-            m_step_out_plan_sp.reset (new ThreadPlanStepOut(m_thread, NULL, false, stop_others, eVoteNoOpinion, eVoteNoOpinion, frame_idx - 1));
+            m_step_out_plan_sp.reset (new ThreadPlanStepOut(m_thread, 
+                                                            NULL, 
+                                                            false,
+                                                            stop_others, 
+                                                            eVoteNoOpinion, 
+                                                            eVoteNoOpinion, 
+                                                            frame_idx - 1));
             m_step_out_plan_sp->SetOkayToDiscard(true);
         }
         else
@@ -127,14 +135,13 @@
     else
     {
         if (m_step_out_plan_sp)
-            s->Printf ("Stepping out to inlined frame at depth: %d so we can walk through it.", m_stack_depth);
+            s->Printf ("Stepping out to inlined frame so we can walk through it.");
         else if (m_step_through_inline_plan_sp)
             s->Printf ("Stepping out by stepping through inlined function.");
         else
-            s->Printf ("Stepping out from address 0x%llx to return address 0x%llx at depth: %d using breakpoint site %d",
+            s->Printf ("Stepping out from address 0x%llx to return address 0x%llx using breakpoint site %d",
                        (uint64_t)m_step_from_insn,
                        (uint64_t)m_return_addr,
-                       m_stack_depth,
                        m_return_bp_id);
     }
 }
@@ -194,8 +201,27 @@
             BreakpointSiteSP site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByID (stop_info_sp->GetValue()));
             if (site_sp && site_sp->IsBreakpointAtThisSite (m_return_bp_id))
             {
-                const uint32_t num_frames = m_thread.GetStackFrameCount();
-                if (m_stack_depth > num_frames)
+                bool done;
+                
+                StackID frame_zero_id = m_thread.GetStackFrameAtIndex(0)->GetStackID();
+                
+                if (m_step_out_to_id == frame_zero_id)
+                    done = true;
+                else if (m_step_out_to_id < frame_zero_id)
+                {
+                    // Either we stepped past the breakpoint, or the stack ID calculation
+                    // was incorrect and we should probably stop.
+                    done = true;
+                }
+                else
+                {
+                    if (m_immediate_step_from_id < frame_zero_id)
+                        done = true;
+                    else
+                        done = false;
+                }
+                    
+                if (done)
                 {
                     CalculateReturnValue();
                     SetPlanComplete();
@@ -228,10 +254,17 @@
 ThreadPlanStepOut::ShouldStop (Event *event_ptr)
 {
         if (IsPlanComplete())
-        {
             return true;
-        }
-        else if (m_stack_depth > m_thread.GetStackFrameCount())
+        
+        bool done;
+        
+        StackID frame_zero_id = m_thread.GetStackFrameAtIndex(0)->GetStackID();
+        if (frame_zero_id < m_step_out_to_id)
+            done = false;
+        else
+            done = true;
+            
+        if (done)
         {
             CalculateReturnValue();
             SetPlanComplete();

Modified: lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp?rev=151780&r1=151779&r2=151780&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp Wed Feb 29 18:50:50 2012
@@ -114,8 +114,10 @@
         stop_others = false;
 
     ThreadPlan* new_plan = NULL;
-
-    if (FrameIsOlder())
+    
+    FrameComparison frame_order = CompareCurrentFrameToStartFrame();
+    
+    if (frame_order == eFrameCompareOlder)
     {
         // If we're in an older frame then we should stop.
         //
@@ -129,15 +131,32 @@
         if (new_plan != NULL && log)
             log->Printf("Thought I stepped out, but in fact arrived at a trampoline.");
     }
-    else if (FrameIsYounger())
+    else if (frame_order == eFrameCompareYounger)
     {
-        new_plan = m_thread.QueueThreadPlanForStepOut (false, 
-                                                       NULL, 
-                                                       true, 
-                                                       stop_others, 
-                                                       eVoteNo, 
-                                                       eVoteNoOpinion,
-                                                       0);
+        // Make sure we really are in a new frame.  Do that by unwinding and seeing if the
+        // start function really is our start function...
+        StackFrameSP older_frame_sp = m_thread.GetStackFrameAtIndex(1);
+        
+        // But if we can't even unwind one frame we should just get out of here & stop...
+        if (older_frame_sp)
+        {
+            const SymbolContext &older_context = older_frame_sp->GetSymbolContext(eSymbolContextEverything);
+            if (older_context == m_addr_context)
+            {
+                new_plan = m_thread.QueueThreadPlanForStepOut (false, 
+                                                           NULL, 
+                                                           true, 
+                                                           stop_others, 
+                                                           eVoteNo, 
+                                                           eVoteNoOpinion,
+                                                           0);
+            }
+            else 
+            {
+                new_plan = m_thread.QueueThreadPlanForStepThrough (false, stop_others);
+                
+            }
+        }
     }
     else if (!InSymbol())
     {

Modified: lldb/trunk/source/Target/ThreadPlanStepRange.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepRange.cpp?rev=151780&r1=151779&r2=151780&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanStepRange.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanStepRange.cpp Wed Feb 29 18:50:50 2012
@@ -43,13 +43,11 @@
     m_addr_context (addr_context),
     m_address_ranges (),
     m_stop_others (stop_others),
-    m_stack_depth (0),
     m_stack_id (),
     m_no_more_plans (false),
     m_first_run_event (true)
 {
     AddRange(range);
-    m_stack_depth = m_thread.GetStackFrameCount();
     m_stack_id = m_thread.GetStackFrameAtIndex(0)->GetStackID();
 }
 
@@ -199,58 +197,26 @@
 // Ideally we should remember the whole stack frame list, and then compare that
 // to the current list.
 
-bool
-ThreadPlanStepRange::FrameIsYounger ()
+lldb::FrameComparison
+ThreadPlanStepRange::CompareCurrentFrameToStartFrame()
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    FrameComparison frame_order;
     
-    // FIXME: Might be better to do this by storing the FrameID we started in and seeing if that is still above
-    // us on the stack.  Counting the whole stack could be expensive.
+    StackID cur_frame_id = m_thread.GetStackFrameAtIndex(0)->GetStackID();
     
-    uint32_t current_depth = m_thread.GetStackFrameCount();
-    if (current_depth == m_stack_depth)
-    {
-        if (log)
-            log->Printf ("Step range FrameIsYounger still in start function.");
-        return false;
-    }
-    else if (current_depth < m_stack_depth)
-    {
-        if (log)
-            log->Printf ("Step range FrameIsYounger stepped out: start depth: %d current depth %d.", m_stack_depth, current_depth);
-        return false;
-    }
-    else
-    {
-        if (log)
-            log->Printf ("Step range FrameIsYounger stepped in: start depth: %d current depth %d.", m_stack_depth, current_depth);
-        return true;
-    }
-}
-
-bool
-ThreadPlanStepRange::FrameIsOlder ()
-{
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
-    uint32_t current_depth = m_thread.GetStackFrameCount();
-    if (current_depth == m_stack_depth)
+    if (cur_frame_id == m_stack_id)
     {
-        if (log)
-            log->Printf ("Step range FrameIsOlder still in start function.");
-        return false;
+        frame_order = eFrameCompareEqual;
     }
-    else if (current_depth < m_stack_depth)
+    else if (cur_frame_id < m_stack_id)
     {
-        if (log)
-            log->Printf ("Step range FrameIsOlder stepped out: start depth: %d current depth %d.", m_stack_depth, current_depth);
-        return true;
+        frame_order = eFrameCompareYounger;
     }
     else
     {
-        if (log)
-            log->Printf ("Step range FrameIsOlder stepped in: start depth: %d current depth %d.", m_stack_depth, current_depth);
-        return false;
+        frame_order = eFrameCompareOlder;
     }
+    return frame_order;
 }
 
 bool
@@ -285,15 +251,19 @@
         {
             done = false;
         }
-        else if (!FrameIsOlder())
+        else 
         {
-            if (m_no_more_plans)
-                done = true;
+            FrameComparison frame_order = CompareCurrentFrameToStartFrame();
+            if (frame_order != eFrameCompareOlder)
+            {
+                if (m_no_more_plans)
+                    done = true;
+                else
+                    done = false;
+            }
             else
-                done = false;
+                done = true;
         }
-        else
-            done = true;
     }
 
     if (done)

Modified: lldb/trunk/source/Target/ThreadPlanStepUntil.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepUntil.cpp?rev=151780&r1=151779&r2=151780&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanStepUntil.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanStepUntil.cpp Wed Feb 29 18:50:50 2012
@@ -41,15 +41,14 @@
     uint32_t frame_idx
 ) :
     ThreadPlan (ThreadPlan::eKindStepUntil, "Step until", thread, eVoteNoOpinion, eVoteNoOpinion),
-    m_stack_depth (0),
     m_step_from_insn (LLDB_INVALID_ADDRESS),
-    m_return_bp_id(LLDB_INVALID_BREAK_ID),
+    m_return_bp_id (LLDB_INVALID_BREAK_ID),
     m_return_addr (LLDB_INVALID_ADDRESS),
-    m_stepped_out(false),
-    m_should_stop(false),
+    m_stepped_out (false),
+    m_should_stop (false),
     m_ran_analyze (false),
-    m_explains_stop(false),
-    m_until_points(),
+    m_explains_stop (false),
+    m_until_points (),
     m_stop_others (stop_others)
 {
 
@@ -79,7 +78,7 @@
             }
         }
 
-        m_stack_depth = m_thread.GetStackFrameCount() - frame_idx;
+        m_stack_id = m_thread.GetStackFrameAtIndex(frame_idx)->GetStackID();
 
         // Now set breakpoints on all our return addresses:
         for (int i = 0; i < num_addresses; i++)
@@ -207,7 +206,15 @@
                     // If there was another breakpoint here, then we don't explain the stop, but we won't
                     // mark ourselves Completed, because maybe that breakpoint will continue, and then
                     // we'll finish the "until".
-                    if (m_stack_depth > m_thread.GetStackFrameCount())
+                    bool done;
+                    StackID cur_frame_zero_id;
+                    
+                    if (m_stack_id < cur_frame_zero_id)
+                        done = true;
+                    else 
+                        done = false;
+                    
+                    if (done)
                     {
                         m_stepped_out = true;
                         SetPlanComplete();
@@ -230,7 +237,36 @@
                         if (this_site->IsBreakpointAtThisSite ((*pos).second))
                         {
                             // If we're at the right stack depth, then we're done.
-                            if (m_stack_depth == m_thread.GetStackFrameCount())
+                            
+                            bool done;
+                            StackID frame_zero_id = m_thread.GetStackFrameAtIndex(0)->GetStackID();
+                            
+                            if (frame_zero_id == m_stack_id)
+                                done = true;
+                            else if (frame_zero_id < m_stack_id)
+                                done = false;
+                            else
+                            {
+                                StackFrameSP older_frame_sp = m_thread.GetStackFrameAtIndex(1);
+        
+                                // But if we can't even unwind one frame we should just get out of here & stop...
+                                if (older_frame_sp)
+                                {
+                                    const SymbolContext &older_context 
+                                        = older_frame_sp->GetSymbolContext(eSymbolContextEverything);
+                                    SymbolContext stack_context;
+                                    m_stack_id.GetSymbolContextScope()->CalculateSymbolContext(&stack_context);
+                                    
+                                    if (older_context == stack_context)
+                                        done = true;
+                                    else
+                                        done = false;
+                                }
+                                else
+                                    done = false;
+                            }
+                            
+                            if (done)
                                 SetPlanComplete();
                             else
                                 m_should_stop = false;





More information about the lldb-commits mailing list