[Lldb-commits] [lldb] r163366 - in /lldb/trunk: include/lldb/Target/ThreadPlanStepInRange.h source/Target/ThreadPlanStepInRange.cpp

Jim Ingham jingham at apple.com
Thu Sep 6 18:11:44 PDT 2012


Author: jingham
Date: Thu Sep  6 20:11:44 2012
New Revision: 163366

URL: http://llvm.org/viewvc/llvm-project?rev=163366&view=rev
Log:
Ensure that the ShouldStopHere plans get called even when doing "virtual" steps.

Modified:
    lldb/trunk/include/lldb/Target/ThreadPlanStepInRange.h
    lldb/trunk/source/Target/ThreadPlanStepInRange.cpp

Modified: lldb/trunk/include/lldb/Target/ThreadPlanStepInRange.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanStepInRange.h?rev=163366&r1=163365&r2=163366&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlanStepInRange.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlanStepInRange.h Thu Sep  6 20:11:44 2012
@@ -80,6 +80,7 @@
     std::auto_ptr<RegularExpression> m_avoid_regexp_ap;
     bool m_step_past_prologue;  // FIXME: For now hard-coded to true, we could put a switch in for this if there's
                                 // demand for that.
+    bool m_virtual_step;        // true if we've just done a "virtual step", i.e. just moved the inline stack depth.
 
     DISALLOW_COPY_AND_ASSIGN (ThreadPlanStepInRange);
 

Modified: lldb/trunk/source/Target/ThreadPlanStepInRange.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepInRange.cpp?rev=163366&r1=163365&r2=163366&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanStepInRange.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanStepInRange.cpp Thu Sep  6 20:11:44 2012
@@ -46,7 +46,8 @@
 ) :
     ThreadPlanStepRange (ThreadPlan::eKindStepInRange, "Step Range stepping in", thread, range, addr_context, stop_others),
     ThreadPlanShouldStopHere (this, ThreadPlanStepInRange::DefaultShouldStopHereCallback, NULL),
-    m_step_past_prologue (true)
+    m_step_past_prologue (true),
+    m_virtual_step (false)
 {
     SetFlagsToDefault ();
 }
@@ -86,113 +87,122 @@
         
     ThreadPlan* new_plan = NULL;
 
-    // Stepping through should be done stopping other threads in general, since we're setting a breakpoint and
-    // continuing...
-    
-    bool stop_others;
-    if (m_stop_others != lldb::eAllThreads)
-        stop_others = true;
-    else
-        stop_others = false;
-        
-    FrameComparison frame_order = CompareCurrentFrameToStartFrame();
-    
-    if (frame_order == eFrameCompareOlder)
+    if (m_virtual_step)
     {
-        // If we're in an older frame then we should stop.
-        //
-        // A caveat to this is if we think the frame is older but we're actually in a trampoline.
-        // I'm going to make the assumption that you wouldn't RETURN to a trampoline.  So if we are
-        // in a trampoline we think the frame is older because the trampoline confused the backtracer.
-        new_plan = m_thread.QueueThreadPlanForStepThrough (m_stack_id, false, stop_others);
-        if (new_plan == NULL)
-            return true;
-        else if (log)
-        {
-            log->Printf("Thought I stepped out, but in fact arrived at a trampoline.");
-        }
-
-    }
-    else if (frame_order == eFrameCompareEqual && 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
-        // both the case of a frame that is younger, or the same as this frame.  
-        // However, if the frame is the same, and we are still in the symbol we started
-        // in, the we don't need to do this.  This first check isn't strictly necessary,
-        // but it is more efficient.
-        
-        // If we're still in the range, keep going, either by running to the next branch breakpoint, or by
-        // stepping.
-        if (InRange())
-        {
-            SetNextBranchBreakpoint();
-            return false;
-        }
-    
-        SetPlanComplete();
-        return true;
+        // If we've just completed a virtual step, all we need to do is check for a ShouldStopHere plan, and otherwise
+        // we're done.
+        new_plan = InvokeShouldStopHereCallback();
     }
-    
-    // If we get to this point, we're not going to use a previously set "next branch" breakpoint, so delete it:
-    ClearNextBranchBreakpoint();
-    
-    // We may have set the plan up above in the FrameIsOlder section:
-    
-    if (new_plan == NULL)
-        new_plan = m_thread.QueueThreadPlanForStepThrough (m_stack_id, false, stop_others);
-    
-    if (log)
+    else
     {
-        if (new_plan != NULL)
-            log->Printf ("Found a step through plan: %s", new_plan->GetName());
+        // Stepping through should be done stopping other threads in general, since we're setting a breakpoint and
+        // continuing...
+        
+        bool stop_others;
+        if (m_stop_others != lldb::eAllThreads)
+            stop_others = true;
         else
-            log->Printf ("No step through plan found.");
-    }
-    
-    // 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 && 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 && frame_order == eFrameCompareYounger && m_step_past_prologue)
-    {
-        lldb::StackFrameSP curr_frame = m_thread.GetStackFrameAtIndex(0);
-        if (curr_frame)
-        {
-            size_t bytes_to_skip = 0;
-            lldb::addr_t curr_addr = m_thread.GetRegisterContext()->GetPC();
-            Address func_start_address;
-            
-            SymbolContext sc = curr_frame->GetSymbolContext (eSymbolContextFunction | eSymbolContextSymbol);
+            stop_others = false;
             
-            if (sc.function)
+        FrameComparison frame_order = CompareCurrentFrameToStartFrame();
+        
+        if (frame_order == eFrameCompareOlder)
+        {
+            // If we're in an older frame then we should stop.
+            //
+            // A caveat to this is if we think the frame is older but we're actually in a trampoline.
+            // I'm going to make the assumption that you wouldn't RETURN to a trampoline.  So if we are
+            // in a trampoline we think the frame is older because the trampoline confused the backtracer.
+            new_plan = m_thread.QueueThreadPlanForStepThrough (m_stack_id, false, stop_others);
+            if (new_plan == NULL)
+                return true;
+            else if (log)
             {
-                func_start_address = sc.function->GetAddressRange().GetBaseAddress();
-                if (curr_addr == func_start_address.GetLoadAddress(m_thread.CalculateTarget().get()))
-                    bytes_to_skip = sc.function->GetPrologueByteSize();
+                log->Printf("Thought I stepped out, but in fact arrived at a trampoline.");
             }
-            else if (sc.symbol)
+
+        }
+        else if (frame_order == eFrameCompareEqual && 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
+            // both the case of a frame that is younger, or the same as this frame.  
+            // However, if the frame is the same, and we are still in the symbol we started
+            // in, the we don't need to do this.  This first check isn't strictly necessary,
+            // but it is more efficient.
+            
+            // If we're still in the range, keep going, either by running to the next branch breakpoint, or by
+            // stepping.
+            if (InRange())
             {
-                func_start_address = sc.symbol->GetAddress();
-                if (curr_addr == func_start_address.GetLoadAddress(m_thread.CalculateTarget().get()))
-                    bytes_to_skip = sc.symbol->GetPrologueByteSize();
+                SetNextBranchBreakpoint();
+                return false;
             }
-            
-            if (bytes_to_skip != 0)
+        
+            SetPlanComplete();
+            return true;
+        }
+        
+        // If we get to this point, we're not going to use a previously set "next branch" breakpoint, so delete it:
+        ClearNextBranchBreakpoint();
+        
+        // We may have set the plan up above in the FrameIsOlder section:
+        
+        if (new_plan == NULL)
+            new_plan = m_thread.QueueThreadPlanForStepThrough (m_stack_id, false, stop_others);
+        
+        if (log)
+        {
+            if (new_plan != NULL)
+                log->Printf ("Found a step through plan: %s", new_plan->GetName());
+            else
+                log->Printf ("No step through plan found.");
+        }
+        
+        // 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 && 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 && frame_order == eFrameCompareYounger && m_step_past_prologue)
+        {
+            lldb::StackFrameSP curr_frame = m_thread.GetStackFrameAtIndex(0);
+            if (curr_frame)
             {
-                func_start_address.Slide (bytes_to_skip);
-                log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
-                if (log)
-                    log->Printf ("Pushing past prologue ");
-                    
-                new_plan = m_thread.QueueThreadPlanForRunToAddress(false, func_start_address,true);
+                size_t bytes_to_skip = 0;
+                lldb::addr_t curr_addr = m_thread.GetRegisterContext()->GetPC();
+                Address func_start_address;
+                
+                SymbolContext sc = curr_frame->GetSymbolContext (eSymbolContextFunction | eSymbolContextSymbol);
+                
+                if (sc.function)
+                {
+                    func_start_address = sc.function->GetAddressRange().GetBaseAddress();
+                    if (curr_addr == func_start_address.GetLoadAddress(m_thread.CalculateTarget().get()))
+                        bytes_to_skip = sc.function->GetPrologueByteSize();
+                }
+                else if (sc.symbol)
+                {
+                    func_start_address = sc.symbol->GetAddress();
+                    if (curr_addr == func_start_address.GetLoadAddress(m_thread.CalculateTarget().get()))
+                        bytes_to_skip = sc.symbol->GetPrologueByteSize();
+                }
+                
+                if (bytes_to_skip != 0)
+                {
+                    func_start_address.Slide (bytes_to_skip);
+                    log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
+                    if (log)
+                        log->Printf ("Pushing past prologue ");
+                        
+                    new_plan = m_thread.QueueThreadPlanForRunToAddress(false, func_start_address,true);
+                }
             }
         }
-    }
+     }
     
      if (new_plan == NULL)
      {
@@ -306,6 +316,9 @@
     // The only variation is that if we are doing "step by running to next branch" in which case
     // if we hit our branch breakpoint we don't set the plan to complete.
     
+    if (m_virtual_step)
+        return true;
+    
     StopInfoSP stop_info_sp = GetPrivateStopReason();
     if (stop_info_sp)
     {
@@ -347,6 +360,10 @@
                 log->Printf ("ThreadPlanStepInRange::WillResume: returning false, inline_depth: %d",
                              m_thread.GetCurrentInlinedDepth());
             SetStopInfo(StopInfo::CreateStopReasonToTrace(m_thread));
+            
+            // FIXME: Maybe it would be better to create a InlineStep stop reason, but then
+            // the whole rest of the world would have to handle that stop reason.
+            m_virtual_step = true;
         }
         return !step_without_resume;
     }





More information about the lldb-commits mailing list