[Lldb-commits] [lldb] r123970 - in /lldb/trunk: include/lldb/API/ include/lldb/Target/ source/API/ source/Commands/ source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/ source/Target/

Greg Clayton gclayton at apple.com
Thu Jan 20 22:11:59 PST 2011


Author: gclayton
Date: Fri Jan 21 00:11:58 2011
New Revision: 123970

URL: http://llvm.org/viewvc/llvm-project?rev=123970&view=rev
Log:
Added support for stepping out of a frame. If you have 10 stack frames, and you 
select frame #3, you can then do a step out and be able to go directly to the
frame above frame #3! 

Added StepOverUntil and StepOutOfFrame to the SBThread API to allow more powerful
stepping.


Modified:
    lldb/trunk/include/lldb/API/SBError.h
    lldb/trunk/include/lldb/API/SBFrame.h
    lldb/trunk/include/lldb/API/SBThread.h
    lldb/trunk/include/lldb/Target/Thread.h
    lldb/trunk/include/lldb/Target/ThreadPlanStepOut.h
    lldb/trunk/include/lldb/Target/ThreadPlanStepUntil.h
    lldb/trunk/source/API/SBFrame.cpp
    lldb/trunk/source/API/SBThread.cpp
    lldb/trunk/source/Commands/CommandObjectThread.cpp
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
    lldb/trunk/source/Target/Thread.cpp
    lldb/trunk/source/Target/ThreadPlanStepInRange.cpp
    lldb/trunk/source/Target/ThreadPlanStepInstruction.cpp
    lldb/trunk/source/Target/ThreadPlanStepOut.cpp
    lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp
    lldb/trunk/source/Target/ThreadPlanStepUntil.cpp

Modified: lldb/trunk/include/lldb/API/SBError.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBError.h?rev=123970&r1=123969&r2=123970&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBError.h (original)
+++ lldb/trunk/include/lldb/API/SBError.h Fri Jan 21 00:11:58 2011
@@ -72,17 +72,18 @@
     GetDescription (lldb::SBStream &description) const;
 
 protected:
+
+#ifndef SWIG
     friend class SBArguments;
     friend class SBDebugger;
     friend class SBCommunication;
     friend class SBHostOS;
     friend class SBInputReader;
     friend class SBProcess;
+    friend class SBThread;
     friend class SBTarget;
     friend class SBValue;
 
-#ifndef SWIG
-
     lldb_private::Error *
     get();
 

Modified: lldb/trunk/include/lldb/API/SBFrame.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBFrame.h?rev=123970&r1=123969&r2=123970&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBFrame.h (original)
+++ lldb/trunk/include/lldb/API/SBFrame.h Fri Jan 21 00:11:58 2011
@@ -146,6 +146,9 @@
     lldb_private::StackFrame *
     get() const;
 
+    const lldb::StackFrameSP &
+    get_sp() const;
+    
 #endif
 
 

Modified: lldb/trunk/include/lldb/API/SBThread.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBThread.h?rev=123970&r1=123969&r2=123970&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBThread.h (original)
+++ lldb/trunk/include/lldb/API/SBThread.h Fri Jan 21 00:11:58 2011
@@ -85,8 +85,16 @@
     StepOut ();
 
     void
+    StepOutOfFrame (lldb::SBFrame &frame);
+
+    void
     StepInstruction(bool step_over);
 
+    SBError
+    StepOverUntil (lldb::SBFrame &frame, 
+                   lldb::SBFileSpec &file_spec, 
+                   uint32_t line);
+
     void
     RunToAddress (lldb::addr_t addr);
 

Modified: lldb/trunk/include/lldb/Target/Thread.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Thread.h?rev=123970&r1=123969&r2=123970&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Thread.h (original)
+++ lldb/trunk/include/lldb/Target/Thread.h Fri Jan 21 00:11:58 2011
@@ -481,8 +481,9 @@
                                SymbolContext *addr_context,
                                bool first_insn,
                                bool stop_other_threads,
-                               lldb::Vote stop_vote = lldb::eVoteYes,
-                               lldb::Vote run_vote = lldb::eVoteNoOpinion);
+                               lldb::Vote stop_vote, // = lldb::eVoteYes,
+                               lldb::Vote run_vote, // = lldb::eVoteNoOpinion);
+                               uint32_t frame_idx);
 
     //------------------------------------------------------------------
     /// Gets the plan used to step through the code that steps from a function
@@ -527,9 +528,10 @@
 
     virtual ThreadPlan *
     QueueThreadPlanForStepUntil (bool abort_other_plans,
-                               lldb::addr_t *address_list,
-                               size_t num_addresses,
-                               bool stop_others);
+                                 lldb::addr_t *address_list,
+                                 size_t num_addresses,
+                                 bool stop_others,
+                                 uint32_t frame_idx);
 
     virtual ThreadPlan *
     QueueThreadPlanForCallFunction (bool abort_other_plans,

Modified: lldb/trunk/include/lldb/Target/ThreadPlanStepOut.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanStepOut.h?rev=123970&r1=123969&r2=123970&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlanStepOut.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlanStepOut.h Fri Jan 21 00:11:58 2011
@@ -40,13 +40,14 @@
                        bool first_insn,
                        bool stop_others,
                        lldb::Vote stop_vote,
-                       lldb::Vote run_vote);
+                       lldb::Vote run_vote,
+                       uint32_t frame_idx);
 protected:
 
 private:
     SymbolContext *m_step_from_context;
     lldb::addr_t m_step_from_insn;
-    uint64_t m_stack_depth;
+    uint32_t m_stack_depth;
     lldb::break_id_t m_return_bp_id;
     lldb::addr_t m_return_addr;
     bool m_first_insn;
@@ -58,7 +59,8 @@
                                        bool first_insn,
                                        bool stop_others,
                                        lldb::Vote stop_vote,
-                                       lldb::Vote run_vote);
+                                       lldb::Vote run_vote,
+                                       uint32_t frame_idx);
 
     // Need an appropriate marker for the current stack so we can tell step out
     // from step in.

Modified: lldb/trunk/include/lldb/Target/ThreadPlanStepUntil.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanStepUntil.h?rev=123970&r1=123969&r2=123970&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlanStepUntil.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlanStepUntil.h Fri Jan 21 00:11:58 2011
@@ -45,7 +45,8 @@
     ThreadPlanStepUntil (Thread &thread,
                          lldb::addr_t *address_list,
                          size_t num_addresses,
-                         bool stop_others);
+                         bool stop_others,
+                         uint32_t frame_idx = 0);
     void AnalyzeStop(void);
 
 private:
@@ -67,9 +68,10 @@
 
     friend ThreadPlan *
     Thread::QueueThreadPlanForStepUntil (bool abort_other_plans,
-                                       lldb::addr_t *address_list,
-                                       size_t num_addresses,
-                                       bool stop_others);
+                                         lldb::addr_t *address_list,
+                                         size_t num_addresses,
+                                         bool stop_others,
+                                         uint32_t frame_idx);
 
     // Need an appropriate marker for the current stack so we can tell step out
     // from step in.

Modified: lldb/trunk/source/API/SBFrame.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBFrame.cpp?rev=123970&r1=123969&r2=123970&view=diff
==============================================================================
--- lldb/trunk/source/API/SBFrame.cpp (original)
+++ lldb/trunk/source/API/SBFrame.cpp Fri Jan 21 00:11:58 2011
@@ -511,6 +511,11 @@
     return m_opaque_sp.get();
 }
 
+const lldb::StackFrameSP &
+SBFrame::get_sp() const
+{
+    return m_opaque_sp;
+}
 
 SBThread
 SBFrame::GetThread () const

Modified: lldb/trunk/source/API/SBThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBThread.cpp?rev=123970&r1=123969&r2=123970&view=diff
==============================================================================
--- lldb/trunk/source/API/SBThread.cpp (original)
+++ lldb/trunk/source/API/SBThread.cpp Fri Jan 21 00:11:58 2011
@@ -492,8 +492,53 @@
         bool abort_other_plans = true;
         bool stop_other_threads = true;
 
-        m_opaque_sp->QueueThreadPlanForStepOut (abort_other_plans, NULL, false, stop_other_threads, eVoteYes, eVoteNoOpinion);
+        m_opaque_sp->QueueThreadPlanForStepOut (abort_other_plans, 
+                                                NULL, 
+                                                false, 
+                                                stop_other_threads, 
+                                                eVoteYes, 
+                                                eVoteNoOpinion,
+                                                0);
+        
+        Process &process = m_opaque_sp->GetProcess();
+        process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
+        Error error (process.Resume());
+        if (error.Success())
+        {
+            // If we are doing synchronous mode, then wait for the
+            // process to stop yet again!
+            if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
+                process.WaitForProcessToStop (NULL);
+        }
+    }
+}
+
+void
+SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame)
+{
+    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
 
+    if (log)
+    {
+        SBStream frame_desc_strm;
+        sb_frame.GetDescription (frame_desc_strm);
+        log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", m_opaque_sp.get(), sb_frame.get(), frame_desc_strm.GetData());
+    }
+
+    if (m_opaque_sp)
+    {
+        Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
+        bool abort_other_plans = true;
+        bool stop_other_threads = true;
+
+        m_opaque_sp->QueueThreadPlanForStepOut (abort_other_plans, 
+                                                NULL, 
+                                                false, 
+                                                stop_other_threads, 
+                                                eVoteYes, 
+                                                eVoteNoOpinion,
+                                                sb_frame->GetFrameIndex());
+        
         Process &process = m_opaque_sp->GetProcess();
         process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
         Error error (process.Resume());
@@ -559,9 +604,141 @@
                 process.WaitForProcessToStop (NULL);
         }
     }
+}
+
+SBError
+SBThread::StepOverUntil (lldb::SBFrame &sb_frame, 
+                         lldb::SBFileSpec &sb_file_spec, 
+                         uint32_t line)
+{
+    SBError sb_error;
+    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+    char path[PATH_MAX];
 
+    if (log)
+    {
+        SBStream frame_desc_strm;
+        sb_frame.GetDescription (frame_desc_strm);
+        sb_file_spec->GetPath (path, sizeof(path));
+        log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)", 
+                     m_opaque_sp.get(), 
+                     sb_frame.get(), 
+                     frame_desc_strm.GetData(),
+                     path, line);
+    }
+    
+    if (m_opaque_sp)
+    {
+        Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
+
+        if (line == 0)
+        {
+            sb_error.SetErrorString("invalid line argument");
+            return sb_error;
+        }
+        
+        StackFrameSP frame_sp;
+        if (sb_frame.IsValid())
+            frame_sp = sb_frame.get_sp();
+        else
+        {
+            frame_sp = m_opaque_sp->GetSelectedFrame ();
+            if (!frame_sp)
+                frame_sp = m_opaque_sp->GetStackFrameAtIndex (0);
+        }
+    
+        SymbolContext frame_sc;
+        if (!frame_sp)        
+        {
+            sb_error.SetErrorString("no valid frames in thread to step");
+            return sb_error;
+        }
+
+        // If we have a frame, get its line
+        frame_sc = frame_sp->GetSymbolContext (eSymbolContextCompUnit  |
+                                               eSymbolContextFunction  | 
+                                               eSymbolContextLineEntry | 
+                                               eSymbolContextSymbol    );
+                                               
+        if (frame_sc.comp_unit == NULL)
+        {
+            sb_error.SetErrorStringWithFormat("frame %u doesn't have debug information", frame_sp->GetFrameIndex());
+            return sb_error;
+        }
+        
+        FileSpec step_file_spec;
+        if (sb_file_spec.IsValid())
+        {
+            // The file spec passed in was valid, so use it
+            step_file_spec = sb_file_spec.ref();
+        }
+        else
+        {
+            if (frame_sc.line_entry.IsValid())
+                step_file_spec = frame_sc.line_entry.file;
+            else
+            {
+                sb_error.SetErrorString("invalid file argument or no file for frame");
+                return sb_error;
+            }
+        }
+    
+        std::vector<addr_t> step_over_until_addrs;
+        const bool abort_other_plans = true;
+        const bool stop_other_threads = true;
+        const bool check_inlines = true;
+        const bool exact = false;
+
+        SymbolContextList sc_list;
+        const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec, line, check_inlines, exact, eSymbolContextLineEntry, sc_list);
+        if (num_matches > 0)
+        {
+            SymbolContext sc;
+            for (uint32_t i=0; i<num_matches; ++i)
+            {
+                if (sc_list.GetContextAtIndex(i, sc))
+                {
+                    addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(&m_opaque_sp->GetProcess().GetTarget());
+                    if (step_addr != LLDB_INVALID_ADDRESS)
+                    {
+                        step_over_until_addrs.push_back(step_addr);
+                    }
+                }
+            }
+        }
+
+        if (step_over_until_addrs.empty())
+        {
+            step_file_spec.GetPath (path, sizeof(path));
+            sb_error.SetErrorStringWithFormat("No line entries for %s:u", path, line);
+        }
+        else
+        {
+            m_opaque_sp->QueueThreadPlanForStepUntil (abort_other_plans, 
+                                                      &step_over_until_addrs[0],
+                                                      step_over_until_addrs.size(),
+                                                      stop_other_threads,
+                                                      frame_sp->GetFrameIndex());      
+
+            m_opaque_sp->GetProcess().GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
+            sb_error.ref() = m_opaque_sp->GetProcess().Resume();
+            if (sb_error->Success())
+            {
+                // If we are doing synchronous mode, then wait for the
+                // process to stop yet again!
+                if (m_opaque_sp->GetProcess().GetTarget().GetDebugger().GetAsyncExecution () == false)
+                    m_opaque_sp->GetProcess().WaitForProcessToStop (NULL);
+            }
+        }
+    }
+    else
+    {
+        sb_error.SetErrorString("this SBThread object is invalid");
+    }
+    return sb_error;
 }
 
+
 bool
 SBThread::Suspend()
 {
@@ -606,10 +783,10 @@
     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
     if (log)
     {
-        SBStream sstr;
-        process.GetDescription (sstr);
+        SBStream frame_desc_strm;
+        process.GetDescription (frame_desc_strm);
         log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s", m_opaque_sp.get(),
-                     process.get(), sstr.GetData());
+                     process.get(), frame_desc_strm.GetData());
     }
 
     return process;
@@ -647,10 +824,10 @@
 
     if (log)
     {
-        SBStream sstr;
-        sb_frame.GetDescription (sstr);
+        SBStream frame_desc_strm;
+        sb_frame.GetDescription (frame_desc_strm);
         log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s", 
-                     m_opaque_sp.get(), idx, sb_frame.get(), sstr.GetData());
+                     m_opaque_sp.get(), idx, sb_frame.get(), frame_desc_strm.GetData());
     }
 
     return sb_frame;
@@ -670,10 +847,10 @@
 
     if (log)
     {
-        SBStream sstr;
-        sb_frame.GetDescription (sstr);
+        SBStream frame_desc_strm;
+        sb_frame.GetDescription (frame_desc_strm);
         log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s", 
-                     m_opaque_sp.get(), sb_frame.get(), sstr.GetData());
+                     m_opaque_sp.get(), sb_frame.get(), frame_desc_strm.GetData());
     }
 
     return sb_frame;
@@ -698,10 +875,10 @@
 
     if (log)
     {
-        SBStream sstr;
-        sb_frame.GetDescription (sstr);
+        SBStream frame_desc_strm;
+        sb_frame.GetDescription (frame_desc_strm);
         log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s", 
-                     m_opaque_sp.get(), idx, sb_frame.get(), sstr.GetData());
+                     m_opaque_sp.get(), idx, sb_frame.get(), frame_desc_strm.GetData());
     }
     return sb_frame;
 }

Modified: lldb/trunk/source/Commands/CommandObjectThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectThread.cpp?rev=123970&r1=123969&r2=123970&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectThread.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectThread.cpp Fri Jan 21 00:11:58 2011
@@ -729,7 +729,13 @@
             {
                 ThreadPlan *new_plan;
 
-                new_plan = thread->QueueThreadPlanForStepOut (abort_other_plans, NULL, false, bool_stop_other_threads, eVoteYes, eVoteNoOpinion);
+                new_plan = thread->QueueThreadPlanForStepOut (abort_other_plans, 
+                                                              NULL, 
+                                                              false, 
+                                                              bool_stop_other_threads, 
+                                                              eVoteYes, 
+                                                              eVoteNoOpinion, 
+                                                              thread->GetSelectedFrameIndex());
                 // FIXME: This will keep the step plan on the thread stack when we hit a breakpoint while stepping over.
                 // Maybe there should be a parameter to control this.
                 new_plan->SetOkayToDiscard(false);
@@ -1208,7 +1214,7 @@
                     index_ptr++;
                 }
 
-                new_plan = thread->QueueThreadPlanForStepUntil (abort_other_plans, &address_list.front(), address_list.size(), m_options.m_stop_others);
+                new_plan = thread->QueueThreadPlanForStepUntil (abort_other_plans, &address_list.front(), address_list.size(), m_options.m_stop_others, thread->GetSelectedFrameIndex ());
                 new_plan->SetOkayToDiscard(false);
             }
             else

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp?rev=123970&r1=123969&r2=123970&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp Fri Jan 21 00:11:58 2011
@@ -129,7 +129,13 @@
                     log->Printf ("Implementation lookup returned msgForward function: 0x%llx, stopping.", target_addr);
 
                 SymbolContext sc = m_thread.GetStackFrameAtIndex(0)->GetSymbolContext(eSymbolContextEverything);
-                m_run_to_sp.reset(new ThreadPlanStepOut(m_thread, &sc, true, m_stop_others, eVoteNoOpinion, eVoteNoOpinion));
+                m_run_to_sp.reset(new ThreadPlanStepOut (m_thread, 
+                                                         &sc, 
+                                                         true, 
+                                                         m_stop_others, 
+                                                         eVoteNoOpinion, 
+                                                         eVoteNoOpinion,
+                                                         0));
                 m_thread.QueueThreadPlan(m_run_to_sp, false);
                 m_run_to_sp->SetPrivate(true);
                 return false;

Modified: lldb/trunk/source/Target/Thread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Thread.cpp?rev=123970&r1=123969&r2=123970&view=diff
==============================================================================
--- lldb/trunk/source/Target/Thread.cpp (original)
+++ lldb/trunk/source/Target/Thread.cpp Fri Jan 21 00:11:58 2011
@@ -661,7 +661,12 @@
 }
 
 ThreadPlan *
-Thread::QueueThreadPlanForStepSingleInstruction (bool step_over, bool abort_other_plans, bool stop_other_threads)
+Thread::QueueThreadPlanForStepSingleInstruction
+(
+    bool step_over, 
+    bool abort_other_plans, 
+    bool stop_other_threads
+)
 {
     ThreadPlanSP thread_plan_sp (new ThreadPlanStepInstruction (*this, step_over, stop_other_threads, eVoteNoOpinion, eVoteNoOpinion));
     QueueThreadPlan (thread_plan_sp, abort_other_plans);
@@ -706,10 +711,24 @@
 }
 
 ThreadPlan *
-Thread::QueueThreadPlanForStepOut (bool abort_other_plans, SymbolContext *addr_context, bool first_insn,
-        bool stop_other_threads, Vote stop_vote, Vote run_vote)
+Thread::QueueThreadPlanForStepOut 
+(
+    bool abort_other_plans, 
+    SymbolContext *addr_context, 
+    bool first_insn,
+    bool stop_other_threads, 
+    Vote stop_vote, 
+    Vote run_vote,
+    uint32_t frame_idx
+)
 {
-    ThreadPlanSP thread_plan_sp (new ThreadPlanStepOut (*this, addr_context, first_insn, stop_other_threads, stop_vote, run_vote));
+    ThreadPlanSP thread_plan_sp (new ThreadPlanStepOut (*this, 
+                                                        addr_context, 
+                                                        first_insn, 
+                                                        stop_other_threads, 
+                                                        stop_vote, 
+                                                        run_vote, 
+                                                        frame_idx));
     QueueThreadPlan (thread_plan_sp, abort_other_plans);
     return thread_plan_sp.get();
 }
@@ -761,11 +780,12 @@
 
 ThreadPlan *
 Thread::QueueThreadPlanForStepUntil (bool abort_other_plans,
-                                       lldb::addr_t *address_list,
-                                       size_t num_addresses,
-                                       bool stop_other_threads)
+                                     lldb::addr_t *address_list,
+                                     size_t num_addresses,
+                                     bool stop_other_threads,
+                                     uint32_t frame_idx)
 {
-    ThreadPlanSP thread_plan_sp (new ThreadPlanStepUntil (*this, address_list, num_addresses, stop_other_threads));
+    ThreadPlanSP thread_plan_sp (new ThreadPlanStepUntil (*this, address_list, num_addresses, stop_other_threads, frame_idx));
     QueueThreadPlan (thread_plan_sp, abort_other_plans);
     return thread_plan_sp.get();
 

Modified: lldb/trunk/source/Target/ThreadPlanStepInRange.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepInRange.cpp?rev=123970&r1=123969&r2=123970&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanStepInRange.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanStepInRange.cpp Fri Jan 21 00:11:58 2011
@@ -270,9 +270,13 @@
     if (should_step_out)
     {
         // FIXME: Make sure the ThreadPlanForStepOut does the right thing with inlined functions.
-        return current_plan->GetThread().QueueThreadPlanForStepOut (false, NULL, true, 
+        return current_plan->GetThread().QueueThreadPlanForStepOut (false, 
+                                                                    NULL, 
+                                                                    true, 
                                                                     current_plan->StopOthers(), 
-                                                                    eVoteNo, eVoteNoOpinion);
+                                                                    eVoteNo, 
+                                                                    eVoteNoOpinion,
+                                                                    0); // Frame index
     }
 
     return NULL;

Modified: lldb/trunk/source/Target/ThreadPlanStepInstruction.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepInstruction.cpp?rev=123970&r1=123969&r2=123970&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanStepInstruction.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanStepInstruction.cpp Fri Jan 21 00:11:58 2011
@@ -129,7 +129,7 @@
                     s.Address (return_addr, m_thread.GetProcess().GetAddressByteSize());
                     log->Printf("%s.", s.GetData());
                 }
-                m_thread.QueueThreadPlanForStepOut(false, NULL, true, m_stop_other_threads, eVoteNo, eVoteNoOpinion);
+                m_thread.QueueThreadPlanForStepOut(false, NULL, true, m_stop_other_threads, eVoteNo, eVoteNoOpinion, 0);
                 return false;
             }
             else

Modified: lldb/trunk/source/Target/ThreadPlanStepOut.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepOut.cpp?rev=123970&r1=123969&r2=123970&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanStepOut.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanStepOut.cpp Fri Jan 21 00:11:58 2011
@@ -35,7 +35,8 @@
     bool first_insn,
     bool stop_others,
     Vote stop_vote,
-    Vote run_vote
+    Vote run_vote,
+    uint32_t frame_idx
 ) :
     ThreadPlan (ThreadPlan::eKindStepOut, "Step out", thread, stop_vote, run_vote),
     m_step_from_context (context),
@@ -50,24 +51,20 @@
     // Find the return address and set a breakpoint there:
     // FIXME - can we do this more securely if we know first_insn?
 
-    StackFrame *return_frame = m_thread.GetStackFrameAtIndex(1).get();
-    if (return_frame)
+    StackFrameSP return_frame_sp (m_thread.GetStackFrameAtIndex(frame_idx + 1));
+    if (return_frame_sp)
     {
         // TODO: check for inlined frames and do the right thing...
-        m_return_addr = return_frame->GetRegisterContext()->GetPC();
+        m_return_addr = return_frame_sp->GetRegisterContext()->GetPC();
         Breakpoint *return_bp = m_thread.GetProcess().GetTarget().CreateBreakpoint (m_return_addr, true).get();
         if (return_bp != NULL)
         {
             return_bp->SetThreadID(m_thread.GetID());
             m_return_bp_id = return_bp->GetID();
         }
-        else
-        {
-            m_return_bp_id = LLDB_INVALID_BREAK_ID;
-        }
     }
 
-    m_stack_depth = m_thread.GetStackFrameCount();
+    m_stack_depth = m_thread.GetStackFrameCount() - frame_idx;
 }
 
 ThreadPlanStepOut::~ThreadPlanStepOut ()
@@ -116,6 +113,10 @@
             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);
+                    SetPlanComplete();
+
                 // If there was only one owner, then we're done.  But if we also hit some
                 // user breakpoint on our way out, we should mark ourselves as done, but
                 // also not claim to explain the stop, since it is more important to report
@@ -124,7 +125,6 @@
                 if (site_sp->GetNumberOfOwners() == 1)
                     return true;
                 
-                SetPlanComplete();
             }
             return false;
         }
@@ -143,9 +143,7 @@
 bool
 ThreadPlanStepOut::ShouldStop (Event *event_ptr)
 {
-    if (IsPlanComplete()
-        || m_thread.GetRegisterContext()->GetPC() == m_return_addr
-        || m_stack_depth > m_thread.GetStackFrameCount())
+    if (IsPlanComplete() || m_stack_depth > m_thread.GetStackFrameCount())
     {
         SetPlanComplete();
         return true;

Modified: lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp?rev=123970&r1=123969&r2=123970&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp Fri Jan 21 00:11:58 2011
@@ -104,7 +104,13 @@
     }
     else if (FrameIsYounger())
     {
-        new_plan = m_thread.QueueThreadPlanForStepOut (false, NULL, true, stop_others, lldb::eVoteNo, lldb::eVoteNoOpinion);
+        new_plan = m_thread.QueueThreadPlanForStepOut (false, 
+                                                       NULL, 
+                                                       true, 
+                                                       stop_others, 
+                                                       lldb::eVoteNo, 
+                                                       lldb::eVoteNoOpinion,
+                                                       0);
     }
     else if (!InSymbol())
     {

Modified: lldb/trunk/source/Target/ThreadPlanStepUntil.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepUntil.cpp?rev=123970&r1=123969&r2=123970&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanStepUntil.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanStepUntil.cpp Fri Jan 21 00:11:58 2011
@@ -37,7 +37,8 @@
     Thread &thread,
     lldb::addr_t *address_list,
     size_t num_addresses,
-    bool stop_others
+    bool stop_others,
+    uint32_t frame_idx
 ) :
     ThreadPlan (ThreadPlan::eKindStepUntil, "Step until", thread, eVoteNoOpinion, eVoteNoOpinion),
     m_stack_depth (0),
@@ -56,40 +57,43 @@
     // Stash away our "until" addresses:
     Target &target = m_thread.GetProcess().GetTarget();
 
-    m_step_from_insn = m_thread.GetRegisterContext()->GetPC(0);
-    lldb::user_id_t thread_id = m_thread.GetID();
-
-    // Find the return address and set a breakpoint there:
-    // FIXME - can we do this more securely if we know first_insn?
-
-    StackFrame *return_frame = m_thread.GetStackFrameAtIndex(1).get();
-    // TODO: add inline functionality
-    m_return_addr = return_frame->GetRegisterContext()->GetPC();
-    Breakpoint *return_bp = target.CreateBreakpoint (m_return_addr, true).get();
-    if (return_bp != NULL)
-    {
-        return_bp->SetThreadID(thread_id);
-        m_return_bp_id = return_bp->GetID();
-    }
-    else
+    StackFrameSP frame_sp (m_thread.GetStackFrameAtIndex (frame_idx));
+    if (frame_sp)
     {
-        m_return_bp_id = LLDB_INVALID_BREAK_ID;
-    }
+        m_step_from_insn = frame_sp->GetStackID().GetPC();
+        lldb::user_id_t thread_id = m_thread.GetID();
 
-    m_stack_depth = m_thread.GetStackFrameCount();
+        // Find the return address and set a breakpoint there:
+        // FIXME - can we do this more securely if we know first_insn?
 
-    // Now set breakpoints on all our return addresses:
-    for (int i = 0; i < num_addresses; i++)
-    {
-        Breakpoint *until_bp = target.CreateBreakpoint (address_list[i], true).get();
-        if (until_bp != NULL)
+        StackFrameSP return_frame_sp (m_thread.GetStackFrameAtIndex(frame_idx + 1));
+        if (return_frame_sp)
         {
-            until_bp->SetThreadID(thread_id);
-            m_until_points[address_list[i]] = until_bp->GetID();
+            // TODO: add inline functionality
+            m_return_addr = return_frame_sp->GetStackID().GetPC();
+            Breakpoint *return_bp = target.CreateBreakpoint (m_return_addr, true).get();
+            if (return_bp != NULL)
+            {
+                return_bp->SetThreadID(thread_id);
+                m_return_bp_id = return_bp->GetID();
+            }
         }
-        else
+
+        m_stack_depth = m_thread.GetStackFrameCount() - frame_idx;
+
+        // Now set breakpoints on all our return addresses:
+        for (int i = 0; i < num_addresses; i++)
         {
-            m_until_points[address_list[i]] = LLDB_INVALID_BREAK_ID;
+            Breakpoint *until_bp = target.CreateBreakpoint (address_list[i], true).get();
+            if (until_bp != NULL)
+            {
+                until_bp->SetThreadID(thread_id);
+                m_until_points[address_list[i]] = until_bp->GetID();
+            }
+            else
+            {
+                m_until_points[address_list[i]] = LLDB_INVALID_BREAK_ID;
+            }
         }
     }
 }





More information about the lldb-commits mailing list