[Lldb-commits] [lldb] r163044 - in /lldb/trunk: include/lldb/Target/ source/Plugins/Process/gdb-remote/ source/Target/

Jim Ingham jingham at apple.com
Fri Aug 31 18:02:42 PDT 2012


Author: jingham
Date: Fri Aug 31 20:02:41 2012
New Revision: 163044

URL: http://llvm.org/viewvc/llvm-project?rev=163044&view=rev
Log:
Initial check-in of "fancy" inlined stepping.  Doesn't do anything useful unless you switch LLDB_FANCY_INLINED_STEPPING to true.  With that
on, basic inlined stepping works, including step-over of inlined functions.  But for some as yet mysterious reason i386 debugging gets an
assert and dies immediately.  So for now its off.

Modified:
    lldb/trunk/include/lldb/Target/StackFrame.h
    lldb/trunk/include/lldb/Target/StackFrameList.h
    lldb/trunk/include/lldb/Target/Thread.h
    lldb/trunk/include/lldb/Target/ThreadList.h
    lldb/trunk/include/lldb/Target/ThreadPlanStepInRange.h
    lldb/trunk/include/lldb/Target/ThreadPlanStepOverRange.h
    lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
    lldb/trunk/source/Target/Process.cpp
    lldb/trunk/source/Target/StackFrame.cpp
    lldb/trunk/source/Target/StackFrameList.cpp
    lldb/trunk/source/Target/Thread.cpp
    lldb/trunk/source/Target/ThreadList.cpp
    lldb/trunk/source/Target/ThreadPlanStepInRange.cpp
    lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp

Modified: lldb/trunk/include/lldb/Target/StackFrame.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StackFrame.h?rev=163044&r1=163043&r2=163044&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/StackFrame.h (original)
+++ lldb/trunk/include/lldb/Target/StackFrame.h Fri Aug 31 20:02:41 2012
@@ -130,10 +130,7 @@
     IsInlined ();
 
     uint32_t
-    GetFrameIndex () const
-    {
-        return m_frame_index;
-    }
+    GetFrameIndex () const;
 
     uint32_t
     GetConcreteFrameIndex () const

Modified: lldb/trunk/include/lldb/Target/StackFrameList.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StackFrameList.h?rev=163044&r1=163043&r2=163044&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/StackFrameList.h (original)
+++ lldb/trunk/include/lldb/Target/StackFrameList.h Fri Aug 31 20:02:41 2012
@@ -55,7 +55,19 @@
     // Mark a stack frame as the current frame using the frame index
     bool
     SetSelectedFrameByIndex (uint32_t idx);
-
+    
+    uint32_t
+    GetVisibleStackFrameIndex(uint32_t idx)
+    {
+        if (m_current_inlined_depth < UINT32_MAX)
+            return idx - m_current_inlined_depth;
+        else
+            return idx;
+    }
+    
+    void
+    CalculateCurrentInlinedDepth ();
+    
     void
     SetDefaultFileAndLineToSelectedFrame();
 
@@ -104,6 +116,15 @@
         m_concrete_frames_fetched = UINT32_MAX;
     }
     
+    bool
+    DecrementCurrentInlinedDepth ();
+    
+    void
+    ResetCurrentInlinedDepth();
+
+    uint32_t
+    GetCurrentInlinedDepth ();
+    
     //------------------------------------------------------------------
     // Classes that inherit from StackFrameList can see and modify these
     //------------------------------------------------------------------
@@ -117,6 +138,8 @@
     collection m_frames;
     uint32_t m_selected_frame_idx;
     uint32_t m_concrete_frames_fetched;
+    uint32_t m_current_inlined_depth;
+    lldb::addr_t m_current_inlined_pc;
     bool m_show_inlined_frames;
 
 private:

Modified: lldb/trunk/include/lldb/Target/Thread.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Thread.h?rev=163044&r1=163043&r2=163044&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Thread.h (original)
+++ lldb/trunk/include/lldb/Target/Thread.h Fri Aug 31 20:02:41 2012
@@ -271,6 +271,18 @@
     virtual lldb::StackFrameSP
     GetFrameWithConcreteFrameIndex (uint32_t unwind_idx);
     
+    bool
+    DecrementCurrentInlinedDepth()
+    {
+        return GetStackFrameList()->DecrementCurrentInlinedDepth();
+    }
+    
+    uint32_t
+    GetCurrentInlinedDepth()
+    {
+        return GetStackFrameList()->DecrementCurrentInlinedDepth();
+    }
+    
     virtual lldb::StackFrameSP
     GetFrameWithStackID (const StackID &stack_id)
     {
@@ -706,6 +718,7 @@
     friend class ThreadPlan;
     friend class ThreadList;
     friend class StackFrameList;
+    friend class StackFrame;
     
     // This is necessary to make sure thread assets get destroyed while the thread is still in good shape
     // to call virtual thread methods.  This must be called by classes that derive from Thread in their destructor.

Modified: lldb/trunk/include/lldb/Target/ThreadList.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadList.h?rev=163044&r1=163043&r2=163044&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadList.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadList.h Fri Aug 31 20:02:41 2012
@@ -92,6 +92,19 @@
     void
     RefreshStateAfterStop ();
 
+    //------------------------------------------------------------------
+    /// The thread list asks tells all the threads it is about to resume.
+    /// If a thread can "resume" without having to resume the target, it
+    /// will return false for WillResume, and then the process will not be
+    /// restarted.
+    ///
+    /// @return
+    ///    \b true instructs the process to resume normally,
+    ///    \b false means start & stopped events will be generated, but
+    ///    the process will not actually run.  The thread must then return
+    ///    the correct StopInfo when asked.
+    ///
+    //------------------------------------------------------------------
     bool
     WillResume ();
 

Modified: lldb/trunk/include/lldb/Target/ThreadPlanStepInRange.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanStepInRange.h?rev=163044&r1=163043&r2=163044&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlanStepInRange.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlanStepInRange.h Fri Aug 31 20:02:41 2012
@@ -52,6 +52,8 @@
     virtual bool
     PlanExplainsStop ();
 
+    virtual bool WillResume (lldb::StateType resume_state, bool current_plan);
+    
 protected:
 
     virtual void

Modified: lldb/trunk/include/lldb/Target/ThreadPlanStepOverRange.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanStepOverRange.h?rev=163044&r1=163043&r2=163044&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlanStepOverRange.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlanStepOverRange.h Fri Aug 31 20:02:41 2012
@@ -35,7 +35,8 @@
     virtual void GetDescription (Stream *s, lldb::DescriptionLevel level);
     virtual bool ShouldStop (Event *event_ptr);
     virtual bool PlanExplainsStop ();
-
+    virtual bool WillResume (lldb::StateType resume_state, bool current_plan);
+    
 protected:
 
 private:
@@ -47,6 +48,7 @@
                                          const SymbolContext &addr_context,
                                          lldb::RunMode stop_others,
                                          bool avoid_code_without_debug_info);
+    bool m_first_resume;
 
     DISALLOW_COPY_AND_ASSIGN (ThreadPlanStepOverRange);
 

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp?rev=163044&r1=163043&r2=163044&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp Fri Aug 31 20:02:41 2012
@@ -83,11 +83,16 @@
 bool
 ThreadGDBRemote::WillResume (StateType resume_state)
 {
-    ClearStackFrames();
     // Call the Thread::WillResume first. If we stop at a signal, the stop info
     // class for signal will set the resume signal that we need below. The signal
     // stuff obeys the Process::UnixSignal defaults. 
-    Thread::WillResume(resume_state);
+    // If the thread's WillResume returns false, that means that we aren't going to actually resume,
+    // in which case we should not do the rest of our "resume" work.
+    
+    if (!Thread::WillResume(resume_state))
+        return false;
+    
+    ClearStackFrames();
 
     int signo = GetResumeSignal();
     lldb::LogSP log(lldb_private::GetLogIfAnyCategoriesSet (GDBR_LOG_THREAD));

Modified: lldb/trunk/source/Target/Process.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=163044&r1=163043&r2=163044&view=diff
==============================================================================
--- lldb/trunk/source/Target/Process.cpp (original)
+++ lldb/trunk/source/Target/Process.cpp Fri Aug 31 20:02:41 2012
@@ -2975,7 +2975,13 @@
         }
         else
         {
-            error.SetErrorStringWithFormat("Process::WillResume() thread list returned false after WillResume");
+            // Somebody wanted to run without running.  So generate a continue & a stopped event,
+            // and let the world handle them.
+            if (log)
+                log->Printf ("Process::PrivateResume() asked to simulate a start & stop.");
+            
+            SetPrivateState(eStateRunning);
+            SetPrivateState(eStateStopped);
         }
     }
     else if (log)

Modified: lldb/trunk/source/Target/StackFrame.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrame.cpp?rev=163044&r1=163043&r2=163044&view=diff
==============================================================================
--- lldb/trunk/source/Target/StackFrame.cpp (original)
+++ lldb/trunk/source/Target/StackFrame.cpp Fri Aug 31 20:02:41 2012
@@ -197,6 +197,16 @@
     return m_id;
 }
 
+uint32_t
+StackFrame::GetFrameIndex () const
+{
+    ThreadSP thread_sp = GetThread();
+    if (thread_sp)
+        return thread_sp->GetStackFrameList()->GetVisibleStackFrameIndex(m_frame_index);
+    else
+        return m_frame_index;
+}
+
 void
 StackFrame::SetSymbolContextScope (SymbolContextScope *symbol_scope)
 {

Modified: lldb/trunk/source/Target/StackFrameList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrameList.cpp?rev=163044&r1=163043&r2=163044&view=diff
==============================================================================
--- lldb/trunk/source/Target/StackFrameList.cpp (original)
+++ lldb/trunk/source/Target/StackFrameList.cpp Fri Aug 31 20:02:41 2012
@@ -21,6 +21,7 @@
 #include "lldb/Target/Process.h"
 #include "lldb/Target/RegisterContext.h"
 #include "lldb/Target/StackFrame.h"
+#include "lldb/Target/StopInfo.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Target/Thread.h"
 #include "lldb/Target/Unwind.h"
@@ -45,8 +46,15 @@
     m_frames (),
     m_selected_frame_idx (0),
     m_concrete_frames_fetched (0),
+    m_current_inlined_depth (UINT32_MAX),
+    m_current_inlined_pc (LLDB_INVALID_ADDRESS),
     m_show_inlined_frames (show_inline_frames)
 {
+    if (prev_frames_sp)
+    {
+        m_current_inlined_depth = prev_frames_sp->m_current_inlined_depth;
+        m_current_inlined_pc =    prev_frames_sp->m_current_inlined_pc;
+    }
 }
 
 //----------------------------------------------------------------------
@@ -57,6 +65,140 @@
 }
 
 void
+StackFrameList::CalculateCurrentInlinedDepth()
+{
+    uint32_t cur_inlined_depth = GetCurrentInlinedDepth();
+    if (cur_inlined_depth == UINT32_MAX)
+    {
+        ResetCurrentInlinedDepth();
+    }
+}
+
+uint32_t
+StackFrameList::GetCurrentInlinedDepth ()
+{
+    if (m_show_inlined_frames)
+    {
+        lldb::addr_t cur_pc = m_thread.GetRegisterContext()->GetPC();
+        if (cur_pc != m_current_inlined_pc)
+        {
+            m_current_inlined_pc = LLDB_INVALID_ADDRESS;
+            m_current_inlined_depth = UINT32_MAX;
+        }
+        return m_current_inlined_depth;
+    }
+    else
+    {
+        return UINT32_MAX;
+    }
+}
+
+static const bool LLDB_FANCY_INLINED_STEPPING = false;
+
+void
+StackFrameList::ResetCurrentInlinedDepth ()
+{
+    if (LLDB_FANCY_INLINED_STEPPING && m_show_inlined_frames)
+    {        
+        GetFramesUpTo(0);
+        if (!m_frames[0]->IsInlined())
+        {
+            m_current_inlined_depth = UINT32_MAX;
+            m_current_inlined_pc = LLDB_INVALID_ADDRESS;
+        }
+        else
+        {
+            // We only need to do something special about inlined blocks when we
+            // are at the beginning of an inlined function:
+            // FIXME: We probably also have to do something special if the PC is at the END
+            // of an inlined function, which coincides with the end of either its containing
+            // function or another inlined function.
+            
+            lldb::addr_t curr_pc = m_thread.GetRegisterContext()->GetPC();
+            Block *block_ptr = m_frames[0]->GetFrameBlock();
+            if (block_ptr)
+            {
+                Address pc_as_address;
+                pc_as_address.SetLoadAddress(curr_pc, &(m_thread.GetProcess()->GetTarget()));
+                AddressRange containing_range;
+                if (block_ptr->GetRangeContainingAddress(pc_as_address, containing_range))
+                {
+                    if (pc_as_address == containing_range.GetBaseAddress())
+                    {
+                        // If we got here because of a breakpoint hit, then set the inlined depth depending on where
+                        // the breakpoint was set.
+                        // If we got here because of a crash, then set the inlined depth to the deepest most block.
+                        // Otherwise, we stopped here naturally as the result of a step, so set ourselves in the
+                        // containing frame of the whole set of nested inlines, so the user can then "virtually"
+                        // step into the frames one by one, or next over the whole mess.
+                        // Note: We don't have to handle being somewhere in the middle of the stack here, since
+                        // ResetCurrentInlinedDepth doesn't get called if there is a valid inlined depth set.
+                        StopInfoSP stop_info_sp = m_thread.GetStopInfo();
+                        if (stop_info_sp)
+                        {
+                            switch (stop_info_sp->GetStopReason())
+                            {
+                            case eStopReasonBreakpoint:
+                                {
+                            
+                                }
+                                break;
+                            case eStopReasonWatchpoint:
+                            case eStopReasonException:
+                            case eStopReasonSignal:
+                                // In all these cases we want to stop in the deepest most frame.
+                                m_current_inlined_pc = curr_pc;
+                                m_current_inlined_depth = 0;
+                                break;
+                            default:
+                                {
+                                    // Otherwise, we should set ourselves at the container of the inlining, so that the
+                                    // user can descend into them.
+                                    // So first we check whether we have more than one inlined block sharing this PC:
+                                    int num_inlined_functions = 0;
+                                    
+                                    for  (Block *container_ptr = block_ptr->GetInlinedParent();
+                                              container_ptr != NULL;
+                                              container_ptr = container_ptr->GetInlinedParent())
+                                    {
+                                        if (!container_ptr->GetRangeContainingAddress(pc_as_address, containing_range))
+                                            break;
+                                        if (pc_as_address != containing_range.GetBaseAddress())
+                                            break;
+                                        
+                                        num_inlined_functions++;
+                                    }
+                                    m_current_inlined_pc = curr_pc;
+                                    m_current_inlined_depth = num_inlined_functions + 1;
+                                    
+                                }
+                                break;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+bool
+StackFrameList::DecrementCurrentInlinedDepth ()
+{
+    if (m_show_inlined_frames)
+    {
+        uint32_t current_inlined_depth = GetCurrentInlinedDepth();
+        if (current_inlined_depth != UINT32_MAX)
+        {
+            if (current_inlined_depth > 0)
+                m_current_inlined_depth--;
+            return true;
+        }
+    }
+    return false;
+}
+
+void
 StackFrameList::GetFramesUpTo(uint32_t end_idx)
 {
     // We've already gotten more frames than asked for, or we've already finished unwinding, return.
@@ -70,6 +212,22 @@
 #if defined (DEBUG_STACK_FRAMES)
         StreamFile s(stdout, false);
 #endif
+        // If we are hiding some frames from the outside world, we need to add those onto the total count of
+        // frames to fetch.  However, we don't need ot do that if end_idx is 0 since in that case we always
+        // get the first concrete frame and all the inlined frames below it...
+        
+        uint32_t inlined_depth = 0;
+        if (end_idx > 0)
+        {
+            inlined_depth = GetCurrentInlinedDepth();
+            if (inlined_depth != UINT32_MAX)
+            {
+                if (end_idx > 0)
+                    end_idx += inlined_depth;
+            }
+            else
+                inlined_depth = 0;
+        }
         
         StackFrameSP unwind_frame_sp;
         do
@@ -98,7 +256,7 @@
                     
                     unwind_frame_sp.reset (new StackFrame (m_thread.shared_from_this(),
                                                            m_frames.size(), 
-                                                           idx, 
+                                                           idx,
                                                            m_thread.m_reg_context_sp,
                                                            cfa,
                                                            pc,
@@ -246,7 +404,12 @@
 
     if (can_create)
         GetFramesUpTo (UINT32_MAX);
-    return m_frames.size();
+
+    uint32_t inlined_depth = GetCurrentInlinedDepth();
+    if (inlined_depth == UINT32_MAX)
+        return m_frames.size();
+    else
+        return m_frames.size() - inlined_depth;
 }
 
 void
@@ -278,6 +441,10 @@
 {
     StackFrameSP frame_sp;
     Mutex::Locker locker (m_mutex);
+    uint32_t inlined_depth = GetCurrentInlinedDepth();
+    if (inlined_depth != UINT32_MAX)
+        idx += inlined_depth;
+    
     if (idx < m_frames.size())
         frame_sp = m_frames[idx];
 
@@ -396,6 +563,9 @@
         if (pos->get() == frame)
         {
             m_selected_frame_idx = std::distance (begin, pos);
+            uint32_t inlined_depth = GetCurrentInlinedDepth();
+            if (inlined_depth != UINT32_MAX)
+                m_selected_frame_idx -= inlined_depth;
             break;
         }
     }

Modified: lldb/trunk/source/Target/Thread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Thread.cpp?rev=163044&r1=163043&r2=163044&view=diff
==============================================================================
--- lldb/trunk/source/Target/Thread.cpp (original)
+++ lldb/trunk/source/Target/Thread.cpp Fri Aug 31 20:02:41 2012
@@ -349,15 +349,22 @@
     // plans in case a plan needs to do any special business before it runs.
     
     ThreadPlan *plan_ptr = GetCurrentPlan();
-    plan_ptr->WillResume(resume_state, true);
+    bool need_to_resume = plan_ptr->WillResume(resume_state, true);
 
     while ((plan_ptr = GetPreviousPlan(plan_ptr)) != NULL)
     {
         plan_ptr->WillResume (resume_state, false);
     }
     
-    m_actual_stop_info_sp.reset();
-    return true;
+    // If the WillResume for the plan says we are faking a resume, then it will have set an appropriate stop info.
+    // In that case, don't reset it here.
+    
+    if (need_to_resume)
+    {
+        m_actual_stop_info_sp.reset();
+    }
+
+    return need_to_resume;
 }
 
 void
@@ -409,7 +416,10 @@
                          GetRegisterContext()->GetPC());
         return false;
     }
-
+    
+    // Adjust the stack frame's current inlined depth if it is needed.
+    GetStackFrameList()->CalculateCurrentInlinedDepth();
+    
     if (log)
     {
         log->Printf ("Thread::%s for tid = 0x%4.4llx, pc = 0x%16.16llx", 

Modified: lldb/trunk/source/Target/ThreadList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadList.cpp?rev=163044&r1=163043&r2=163044&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadList.cpp (original)
+++ lldb/trunk/source/Target/ThreadList.cpp Fri Aug 31 20:02:41 2012
@@ -362,7 +362,6 @@
     // Run through the threads and perform their momentary actions.
     // But we only do this for threads that are running, user suspended
     // threads stay where they are.
-    bool success = true;
 
     Mutex::Locker locker(m_threads_mutex);
     m_process->UpdateThreadListIfNeeded();
@@ -449,6 +448,8 @@
 
     }
 
+    bool need_to_resume = true;
+    
     if (immediate_thread_sp)
     {
         for (pos = m_threads.begin(); pos != end; ++pos)
@@ -471,7 +472,8 @@
                 run_state = thread_sp->GetCurrentPlan()->RunState();
             else
                 run_state = eStateSuspended;
-            thread_sp->WillResume(run_state);
+            if (!thread_sp->WillResume(run_state))
+                need_to_resume = false;
         }
     }
     else
@@ -497,13 +499,16 @@
         {
             ThreadSP thread_sp(*pos);
             if (thread_sp == thread_to_run)
-                thread_sp->WillResume(thread_sp->GetCurrentPlan()->RunState());
+            {
+                if (!thread_sp->WillResume(thread_sp->GetCurrentPlan()->RunState()))
+                    need_to_resume = false;
+            }
             else
                 thread_sp->WillResume (eStateSuspended);
         }
     }
 
-    return success;
+    return need_to_resume;
 }
 
 void

Modified: lldb/trunk/source/Target/ThreadPlanStepInRange.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepInRange.cpp?rev=163044&r1=163043&r2=163044&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanStepInRange.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanStepInRange.cpp Fri Aug 31 20:02:41 2012
@@ -256,12 +256,12 @@
 {
     bool should_step_out = false;
     StackFrame *frame = current_plan->GetThread().GetStackFrameAtIndex(0).get();
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
 
     if (flags.Test(eAvoidNoDebug))
     {
         if (!frame->HasDebugInformation())
         {
+            LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
             if (log)
                 log->Printf ("Stepping out of frame with no debug info");
 
@@ -306,7 +306,6 @@
     // 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.
     
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
     StopInfoSP stop_info_sp = GetPrivateStopReason();
     if (stop_info_sp)
     {
@@ -320,9 +319,12 @@
         case eStopReasonWatchpoint:
         case eStopReasonSignal:
         case eStopReasonException:
-            if (log)
-                log->PutCString ("ThreadPlanStepInRange got asked if it explains the stop for some reason other than step.");
-            SetPlanComplete(false);
+            {
+                LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+                if (log)
+                    log->PutCString ("ThreadPlanStepInRange got asked if it explains the stop for some reason other than step.");
+                SetPlanComplete(false);
+            }
             break;
         default:
             break;
@@ -330,3 +332,25 @@
     }
     return true;
 }
+
+bool
+ThreadPlanStepInRange::WillResume (lldb::StateType resume_state, bool current_plan)
+{
+    if (resume_state == eStateStepping && current_plan)
+    {
+        // See if we are about to step over a virtual inlined call.
+        bool step_without_resume = m_thread.DecrementCurrentInlinedDepth();
+        if (step_without_resume)
+        {
+            LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+            if (log)
+                log->Printf ("ThreadPlanStepInRange::WillResume: returning false, inline_depth: %d",
+                             m_thread.GetCurrentInlinedDepth());
+            SetStopInfo(StopInfo::CreateStopReasonToTrace(m_thread));
+        }
+        return !step_without_resume;
+    }
+    else
+        return ThreadPlan::WillResume(resume_state, current_plan);
+    
+}

Modified: lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp?rev=163044&r1=163043&r2=163044&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp Fri Aug 31 20:02:41 2012
@@ -17,6 +17,8 @@
 #include "lldb/lldb-private-log.h"
 #include "lldb/Core/Log.h"
 #include "lldb/Core/Stream.h"
+#include "lldb/Symbol/Block.h"
+#include "lldb/Symbol/Function.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/RegisterContext.h"
 #include "lldb/Target/Target.h"
@@ -40,7 +42,8 @@
     const SymbolContext &addr_context,
     lldb::RunMode stop_others
 ) :
-    ThreadPlanStepRange (ThreadPlan::eKindStepOverRange, "Step range stepping over", thread, range, addr_context, stop_others)
+    ThreadPlanStepRange (ThreadPlan::eKindStepOverRange, "Step range stepping over", thread, range, addr_context, stop_others),
+    m_first_resume(true)
 {
 }
 
@@ -116,7 +119,7 @@
             // in so I left out the target check.  And sometimes the module comes in as the .o file from the
             // inlined range, so I left that out too...
             
-            bool older_ctx_is_equivalent = false;
+            bool older_ctx_is_equivalent = true;
             if (m_addr_context.comp_unit)
             {
                 if (m_addr_context.comp_unit == older_context.comp_unit)
@@ -126,10 +129,6 @@
                         if (m_addr_context.block && m_addr_context.block == older_context.block)
                         {
                             older_ctx_is_equivalent = true;
-                            if (m_addr_context.line_entry.IsValid() && LineEntry::Compare(m_addr_context.line_entry, older_context.line_entry) != 0)
-                            {
-                                older_ctx_is_equivalent = false;
-                            }
                         }
                     }
                 }
@@ -213,6 +212,9 @@
 
         switch (reason)
         {
+        case eStopReasonTrace:
+            return true;
+            break;
         case eStopReasonBreakpoint:
             if (NextRangeBreakpointExplainsStop(stop_info_sp))
                 return true;
@@ -222,13 +224,63 @@
         case eStopReasonWatchpoint:
         case eStopReasonSignal:
         case eStopReasonException:
+        default:
             if (log)
                 log->PutCString ("ThreadPlanStepInRange got asked if it explains the stop for some reason other than step.");
             return false;
             break;
-        default:
-            break;
         }
     }
     return true;
 }
+
+bool
+ThreadPlanStepOverRange::WillResume (lldb::StateType resume_state, bool current_plan)
+{
+    if (resume_state != eStateSuspended && m_first_resume)
+    {
+        m_first_resume = false;
+        if (resume_state == eStateStepping && current_plan)
+        {
+            // See if we are about to step over an inlined call in the middle of the inlined stack, if so figure
+            // out its extents and reset our range to step over that.
+            bool in_inlined_stack = m_thread.DecrementCurrentInlinedDepth();
+            if (in_inlined_stack)
+            {
+                LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+                if (log)
+                    log->Printf ("ThreadPlanStepInRange::WillResume: adjusting range to the frame at inlined depth %d.",
+                                 m_thread.GetCurrentInlinedDepth());
+                StackFrameSP stack_sp = m_thread.GetStackFrameAtIndex(0);
+                if (stack_sp)
+                {
+                    Block *frame_block = stack_sp->GetFrameBlock();
+                    lldb::addr_t curr_pc = m_thread.GetRegisterContext()->GetPC();
+                    AddressRange my_range;
+                    if (frame_block->GetRangeContainingLoadAddress(curr_pc, m_thread.GetProcess()->GetTarget(), my_range))
+                    {
+                        m_address_ranges.clear();
+                        m_address_ranges.push_back(my_range);
+                        if (log)
+                        {
+                            StreamString s;
+                            const InlineFunctionInfo *inline_info = frame_block->GetInlinedFunctionInfo();
+                            const char *name;
+                            if (inline_info)
+                                name = inline_info->GetName().AsCString();
+                            else
+                                name = "<unknown-notinlined>";
+                            
+                            s.Printf ("Stepping over inlined function \"%s\" in inlined stack: ", name);
+                            DumpRanges(&s);
+                            log->PutCString(s.GetData());
+                        }
+                    }
+                    
+                }
+            }
+        }
+    }
+    
+    return ThreadPlan::WillResume(resume_state, current_plan);
+}





More information about the lldb-commits mailing list