[Lldb-commits] [lldb] r152376 - in /lldb/trunk: include/lldb/ include/lldb/Breakpoint/ include/lldb/Core/ include/lldb/Target/ source/Breakpoint/ source/Core/ source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/ source/Target/

Jim Ingham jingham at apple.com
Thu Mar 8 20:10:48 PST 2012


Author: jingham
Date: Thu Mar  8 22:10:47 2012
New Revision: 152376

URL: http://llvm.org/viewvc/llvm-project?rev=152376&view=rev
Log:
First stage of implementing step by "run to next branch".  Doesn't work yet, is turned off.
<rdar://problem/10975912>

Modified:
    lldb/trunk/include/lldb/Breakpoint/BreakpointSiteList.h
    lldb/trunk/include/lldb/Core/Disassembler.h
    lldb/trunk/include/lldb/Target/ThreadPlan.h
    lldb/trunk/include/lldb/Target/ThreadPlanStepInRange.h
    lldb/trunk/include/lldb/Target/ThreadPlanStepOverRange.h
    lldb/trunk/include/lldb/Target/ThreadPlanStepRange.h
    lldb/trunk/include/lldb/Target/ThreadPlanTracer.h
    lldb/trunk/include/lldb/lldb-forward.h
    lldb/trunk/source/Breakpoint/BreakpointSiteList.cpp
    lldb/trunk/source/Core/Disassembler.cpp
    lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
    lldb/trunk/source/Target/ThreadPlan.cpp
    lldb/trunk/source/Target/ThreadPlanStepInRange.cpp
    lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp
    lldb/trunk/source/Target/ThreadPlanStepRange.cpp

Modified: lldb/trunk/include/lldb/Breakpoint/BreakpointSiteList.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/BreakpointSiteList.h?rev=152376&r1=152375&r2=152376&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Breakpoint/BreakpointSiteList.h (original)
+++ lldb/trunk/include/lldb/Breakpoint/BreakpointSiteList.h Thu Mar  8 22:10:47 2012
@@ -112,6 +112,23 @@
     //------------------------------------------------------------------
     lldb::break_id_t
     FindIDByAddress (lldb::addr_t addr);
+    
+    //------------------------------------------------------------------
+    /// Returns whether the breakpoint site \a bp_site_id has \a bp_id
+    //  as one of its owners.
+    ///
+    /// @param[in] bp_site_id
+    ///   The breakpoint site id to query.
+    ///
+    /// @param[in] bp_id
+    ///   The breakpoint id to look for in \a bp_site_id.
+    ///
+    /// @result
+    ///   True if \a bp_site_id exists in the site list AND \a bp_id is one of the
+    ///   owners of that site.
+    //------------------------------------------------------------------
+    bool
+    BreakpointSiteContainsBreakpoint (lldb::break_id_t bp_site_id, lldb::break_id_t bp_id);
 
     //------------------------------------------------------------------
     /// Returns a shared pointer to the breakpoint site with index \a i.

Modified: lldb/trunk/include/lldb/Core/Disassembler.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Disassembler.h?rev=152376&r1=152375&r2=152376&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Disassembler.h (original)
+++ lldb/trunk/include/lldb/Core/Disassembler.h Thu Mar  8 22:10:47 2012
@@ -163,6 +163,12 @@
 
     lldb::InstructionSP
     GetInstructionAtIndex (uint32_t idx) const;
+    
+    uint32_t
+    GetIndexOfNextBranchInstruction(uint32_t start) const;
+    
+    uint32_t
+    GetIndexOfInstructionAtLoadAddress (lldb::addr_t load_addr, Target &target);
 
     void
     Clear();

Modified: lldb/trunk/include/lldb/Target/ThreadPlan.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlan.h?rev=152376&r1=152375&r2=152376&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlan.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlan.h Thu Mar  8 22:10:47 2012
@@ -18,6 +18,8 @@
 #include "lldb/lldb-private.h"
 #include "lldb/Core/UserID.h"
 #include "lldb/Host/Mutex.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
 #include "lldb/Target/Thread.h"
 #include "lldb/Target/ThreadPlanTracer.h"
 #include "lldb/Target/StopInfo.h"
@@ -223,8 +225,11 @@
     ///   A const char * pointer to the thread plan's name.
     //------------------------------------------------------------------
     const char *
-    GetName () const;
-
+    GetName () const
+    {
+        return m_name.c_str();
+    }
+    
     //------------------------------------------------------------------
     /// Returns the Thread that is using this thread plan.
     ///
@@ -232,10 +237,28 @@
     ///   A  pointer to the thread plan's owning thread.
     //------------------------------------------------------------------
     Thread &
-    GetThread();
+    GetThread()
+    {
+        return m_thread;
+    }
 
     const Thread &
-    GetThread() const;
+    GetThread() const
+    {
+        return m_thread;
+    }
+    
+    Target &
+    GetTarget()
+    {
+        return m_thread.GetProcess()->GetTarget();
+    }
+
+    const Target &
+    GetTarget() const
+    {
+        return m_thread.GetProcess()->GetTarget();
+    }
 
     //------------------------------------------------------------------
     /// Print a description of this thread to the stream \a s.
@@ -332,10 +355,16 @@
     MischiefManaged ();
 
     bool
-    GetPrivate ();
+    GetPrivate ()
+    {
+        return m_plan_private;
+    }
 
     void
-    SetPrivate (bool input);
+    SetPrivate (bool input)
+    {
+        m_plan_private = input;
+    }
 
     virtual void
     DidPush();
@@ -345,7 +374,10 @@
 
     // This pushes \a plan onto the plan stack of the current plan's thread.
     void
-    PushPlan (lldb::ThreadPlanSP &thread_plan_sp);
+    PushPlan (lldb::ThreadPlanSP &thread_plan_sp)
+    {
+        m_thread.PushPlan (thread_plan_sp);
+    }
     
     ThreadPlanKind GetKind() const
     {
@@ -403,7 +435,10 @@
     // GetPreviousPlan protected, but only friend ThreadPlan to thread.
 
     ThreadPlan *
-    GetPreviousPlan ();
+    GetPreviousPlan ()
+    {
+        return m_thread.GetPreviousPlan (this);
+    }
     
     // This forwards the private Thread::GetPrivateStopReason which is generally what
     // ThreadPlan's need to know.

Modified: lldb/trunk/include/lldb/Target/ThreadPlanStepInRange.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanStepInRange.h?rev=152376&r1=152375&r2=152376&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlanStepInRange.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlanStepInRange.h Thu Mar  8 22:10:47 2012
@@ -43,9 +43,6 @@
 
     void SetAvoidRegexp(const char *name);
     
-    virtual bool
-    PlanExplainsStop ();
-
     static ThreadPlan *
     DefaultShouldStopHereCallback (ThreadPlan *current_plan, Flags &flags, void *baton);
 

Modified: lldb/trunk/include/lldb/Target/ThreadPlanStepOverRange.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanStepOverRange.h?rev=152376&r1=152375&r2=152376&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlanStepOverRange.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlanStepOverRange.h Thu Mar  8 22:10:47 2012
@@ -33,7 +33,6 @@
                              
     virtual ~ThreadPlanStepOverRange ();
 
-    virtual bool PlanExplainsStop ();
     virtual void GetDescription (Stream *s, lldb::DescriptionLevel level);
     virtual bool ShouldStop (Event *event_ptr);
     virtual bool

Modified: lldb/trunk/include/lldb/Target/ThreadPlanStepRange.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanStepRange.h?rev=152376&r1=152375&r2=152376&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlanStepRange.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlanStepRange.h Thu Mar  8 22:10:47 2012
@@ -42,6 +42,9 @@
     virtual lldb::StateType GetPlanRunState ();
     virtual bool WillStop ();
     virtual bool MischiefManaged ();
+    virtual bool PlanExplainsStop ();
+    virtual void DidPush ();
+
 
     void AddRange(const AddressRange &new_range);
 
@@ -52,15 +55,35 @@
     bool InSymbol();
     void DumpRanges (Stream *s);
     
-    SymbolContext m_addr_context;
+    Disassembler *
+    GetDisassembler ();
+
+    InstructionList *
+    GetInstructionsForAddress(lldb::addr_t addr, size_t &range_index, size_t &insn_offset);
+    
+    // Pushes a plan to proceed through the next section of instructions in the range - usually just a RunToAddress
+    // plan to run to the next branch.  Returns true if it pushed such a plan.  If there was no available 'quick run'
+    // plan, then just single step.
+    bool
+    SetNextBranchBreakpoint ();
+    
+    void
+    ClearNextBranchBreakpoint();
+    
+    bool
+    NextRangeBreakpointExplainsStop (lldb::StopInfoSP stop_info_sp);
+    
+    SymbolContext             m_addr_context;
     std::vector<AddressRange> m_address_ranges;
-    lldb::RunMode m_stop_others;
-    StackID m_stack_id;    // Use the stack ID so we can tell step out from step in.
-    bool m_no_more_plans;  // Need this one so we can tell if we stepped into a call, but can't continue,
-                           // in which case we are done.
-    bool m_first_run_event;  // We want to broadcast only one running event, our first.
+    lldb::RunMode             m_stop_others;
+    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.
+    bool                      m_first_run_event; // We want to broadcast only one running event, our first.
+    lldb::BreakpointSP        m_next_branch_bp_sp;
 
 private:
+    std::vector<lldb::DisassemblerSP> m_instruction_ranges;
     DISALLOW_COPY_AND_ASSIGN (ThreadPlanStepRange);
 
 };

Modified: lldb/trunk/include/lldb/Target/ThreadPlanTracer.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanTracer.h?rev=152376&r1=152375&r2=152376&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlanTracer.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlanTracer.h Thu Mar  8 22:10:47 2012
@@ -90,6 +90,8 @@
     Stream *
     GetLogStream ();
     
+    
+    
     virtual void Log();
     
 private:

Modified: lldb/trunk/include/lldb/lldb-forward.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-forward.h?rev=152376&r1=152375&r2=152376&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-forward.h (original)
+++ lldb/trunk/include/lldb/lldb-forward.h Thu Mar  8 22:10:47 2012
@@ -99,6 +99,7 @@
 class   InputReader;
 class   InstanceSettings;
 class   Instruction;
+class   InstructionList;
 class   LanguageRuntime;
 class   LineTable;
 class   Listener;

Modified: lldb/trunk/source/Breakpoint/BreakpointSiteList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/BreakpointSiteList.cpp?rev=152376&r1=152375&r2=152376&view=diff
==============================================================================
--- lldb/trunk/source/Breakpoint/BreakpointSiteList.cpp (original)
+++ lldb/trunk/source/Breakpoint/BreakpointSiteList.cpp Thu Mar  8 22:10:47 2012
@@ -164,6 +164,16 @@
     return found_sp;
 }
 
+bool
+BreakpointSiteList::BreakpointSiteContainsBreakpoint (lldb::break_id_t bp_site_id, lldb::break_id_t bp_id)
+{
+    collection::const_iterator pos = GetIDConstIterator(bp_site_id);
+    if (pos != m_bp_site_list.end())
+        pos->second->IsBreakpointAtThisSite (bp_id);
+
+    return false;
+}
+
 void
 BreakpointSiteList::Dump (Stream *s) const
 {

Modified: lldb/trunk/source/Core/Disassembler.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Disassembler.cpp?rev=152376&r1=152375&r2=152376&view=diff
==============================================================================
--- lldb/trunk/source/Core/Disassembler.cpp (original)
+++ lldb/trunk/source/Core/Disassembler.cpp Thu Mar  8 22:10:47 2012
@@ -902,6 +902,40 @@
         m_instructions.push_back(inst_sp);
 }
 
+uint32_t
+InstructionList::GetIndexOfNextBranchInstruction(uint32_t start) const
+{
+    size_t num_instructions = m_instructions.size();
+    
+    uint32_t next_branch = UINT32_MAX;
+    for (size_t i = start; i < num_instructions; i++)
+    {
+        if (m_instructions[i]->DoesBranch())
+        {
+            next_branch = i;
+            break;
+        }
+    }
+    return next_branch;
+}
+
+uint32_t
+InstructionList::GetIndexOfInstructionAtLoadAddress (lldb::addr_t load_addr, Target &target)
+{
+    Address address;
+    address.SetLoadAddress(load_addr, &target);
+    uint32_t num_instructions = m_instructions.size();
+    uint32_t index = UINT32_MAX;
+    for (int i = 0; i < num_instructions; i++)
+    {
+        if (m_instructions[i]->GetAddress() == address)
+        {
+            index = i;
+            break;
+        }
+    }
+    return index;
+}
 
 size_t
 Disassembler::ParseInstructions

Modified: lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp?rev=152376&r1=152375&r2=152376&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp Thu Mar  8 22:10:47 2012
@@ -364,27 +364,7 @@
         return false;
     
     uint64_t break_site_id = stop_reason->GetValue();
-    lldb::BreakpointSiteSP bp_site_sp = m_process->GetBreakpointSiteList().FindByID(break_site_id);
+    return m_process->GetBreakpointSiteList().BreakpointSiteContainsBreakpoint(break_site_id,
+                                                                               m_cxx_exception_bp_sp->GetID());
     
-    if (!bp_site_sp)
-        return false;
-    
-    uint32_t num_owners = bp_site_sp->GetNumberOfOwners();
-    
-    break_id_t  cxx_exception_bid;
-    
-    if (!m_cxx_exception_bp_sp)
-        return false;
-        
-    cxx_exception_bid = m_cxx_exception_bp_sp->GetID();
-        
-    for (uint32_t i = 0; i < num_owners; i++)
-    {
-        break_id_t bid = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint().GetID();
-        
-        if (bid == cxx_exception_bid)
-            return true;
-    }
-    
-    return false;
 }

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp?rev=152376&r1=152375&r2=152376&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp Thu Mar  8 22:10:47 2012
@@ -328,29 +328,8 @@
         return false;
     
     uint64_t break_site_id = stop_reason->GetValue();
-    lldb::BreakpointSiteSP bp_site_sp = m_process->GetBreakpointSiteList().FindByID(break_site_id);
-    
-    if (!bp_site_sp)
-        return false;
-    
-    uint32_t num_owners = bp_site_sp->GetNumberOfOwners();
-    
-    break_id_t  objc_exception_bid;
-    
-    if (!m_objc_exception_bp_sp)
-        return false;
-
-    objc_exception_bid = m_objc_exception_bp_sp->GetID();
-    
-    for (uint32_t i = 0; i < num_owners; i++)
-    {
-        break_id_t bid = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint().GetID();
-        
-        if (bid == objc_exception_bid)
-            return true;
-    }
-    
-    return false;
+    return m_process->GetBreakpointSiteList().BreakpointSiteContainsBreakpoint (break_site_id,
+                                                                                m_objc_exception_bp_sp->GetID());
 }
 
 bool

Modified: lldb/trunk/source/Target/ThreadPlan.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlan.cpp?rev=152376&r1=152375&r2=152376&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlan.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlan.cpp Thu Mar  8 22:10:47 2012
@@ -48,25 +48,6 @@
 {
 }
 
-const char *
-ThreadPlan::GetName () const
-{
-    return m_name.c_str();
-}
-
-Thread &
-ThreadPlan::GetThread()
-{
-    return m_thread;
-}
-
-
-const Thread &
-ThreadPlan::GetThread() const
-{
-    return m_thread;
-}
-
 bool
 ThreadPlan::IsPlanComplete ()
 {
@@ -187,30 +168,6 @@
 {
 }
 
-void
-ThreadPlan::PushPlan (ThreadPlanSP &thread_plan_sp)
-{
-    m_thread.PushPlan (thread_plan_sp);
-}
-
-ThreadPlan *
-ThreadPlan::GetPreviousPlan ()
-{
-    return m_thread.GetPreviousPlan (this);
-}
-
-void
-ThreadPlan::SetPrivate (bool input)
-{
-    m_plan_private = input;
-}
-
-bool
-ThreadPlan::GetPrivate (void)
-{
-    return m_plan_private;
-}
-
 bool
 ThreadPlan::OkayToDiscard()
 {

Modified: lldb/trunk/source/Target/ThreadPlanStepInRange.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepInRange.cpp?rev=152376&r1=152375&r2=152376&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanStepInRange.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanStepInRange.cpp Thu Mar  8 22:10:47 2012
@@ -68,37 +68,6 @@
 }
 
 bool
-ThreadPlanStepInRange::PlanExplainsStop ()
-{
-    // We always explain a stop.  Either we've just done a single step, in which
-    // case we'll do our ordinary processing, or we stopped for some
-    // reason that isn't handled by our sub-plans, in which case we want to just stop right
-    // away.
-    
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
-    StopInfoSP stop_info_sp = GetPrivateStopReason();
-    if (stop_info_sp)
-    {
-        StopReason reason = stop_info_sp->GetStopReason();
-
-        switch (reason)
-        {
-        case eStopReasonBreakpoint:
-        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();
-            break;
-        default:
-            break;
-        }
-    }
-    return true;
-}
-
-bool
 ThreadPlanStepInRange::ShouldStop (Event *event_ptr)
 {
     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
@@ -115,10 +84,6 @@
     if (IsPlanComplete())
         return true;
         
-    // If we're still in the range, keep going.
-    if (InRange())
-        return false;
-
     ThreadPlan* new_plan = NULL;
 
     // Stepping through should be done stopping other threads in general, since we're setting a breakpoint and
@@ -148,7 +113,7 @@
         }
 
     }
-    else if (frame_order != eFrameCompareYounger && InSymbol())
+    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
@@ -156,11 +121,22 @@
         // 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 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)

Modified: lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp?rev=152376&r1=152375&r2=152376&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp Thu Mar  8 22:10:47 2012
@@ -63,31 +63,6 @@
 }
 
 bool
-ThreadPlanStepOverRange::PlanExplainsStop ()
-{
-    // We don't explain signals or breakpoints (breakpoints that handle stepping in or
-    // out will be handled by a child plan.
-    StopInfoSP stop_info_sp = GetPrivateStopReason();
-    if (stop_info_sp)
-    {
-        StopReason reason = stop_info_sp->GetStopReason();
-
-        switch (reason)
-        {
-        case eStopReasonBreakpoint:
-        case eStopReasonWatchpoint:
-        case eStopReasonSignal:
-        case eStopReasonException:
-            return false;
-        default:
-            return true;
-        }
-    }
-    return true;
-}
-
-
-bool
 ThreadPlanStepOverRange::ShouldStop (Event *event_ptr)
 {
     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
@@ -100,10 +75,6 @@
         log->Printf("ThreadPlanStepOverRange reached %s.", s.GetData());
     }
     
-    // If we're still in the range, keep going.
-    if (InRange())
-        return false;
-
     // If we're out of the range but in the same frame or in our caller's frame
     // then we should stop.
     // When stepping out we only step if we are forcing running one thread.
@@ -158,15 +129,29 @@
             }
         }
     }
-    else if (!InSymbol())
+    else
     {
-        // This one is a little tricky.  Sometimes we may be in a stub or something similar,
-        // in which case we need to get out of there.  But if we are in a stub then it's 
-        // likely going to be hard to get out from here.  It is probably easiest to step into the
-        // stub, and then it will be straight-forward to step out.        
-        new_plan = m_thread.QueueThreadPlanForStepThrough (false, stop_others);
+        // If we're still in the range, keep going.
+        if (InRange())
+        {
+            SetNextBranchBreakpoint();
+            return false;
+        }
+
+
+        if (!InSymbol())
+        {
+            // This one is a little tricky.  Sometimes we may be in a stub or something similar,
+            // in which case we need to get out of there.  But if we are in a stub then it's 
+            // likely going to be hard to get out from here.  It is probably easiest to step into the
+            // stub, and then it will be straight-forward to step out.        
+            new_plan = m_thread.QueueThreadPlanForStepThrough (false, stop_others);
+        }
     }
 
+    // If we get to this point, we're not going to use a previously set "next branch" breakpoint, so delete it:
+    ClearNextBranchBreakpoint();
+    
     if (new_plan == NULL)
         m_no_more_plans = true;
     else

Modified: lldb/trunk/source/Target/ThreadPlanStepRange.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepRange.cpp?rev=152376&r1=152375&r2=152376&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanStepRange.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanStepRange.cpp Thu Mar  8 22:10:47 2012
@@ -15,14 +15,18 @@
 // Project includes
 
 #include "lldb/lldb-private-log.h"
+#include "lldb/Core/Disassembler.h"
 #include "lldb/Core/Log.h"
 #include "lldb/Core/Stream.h"
 #include "lldb/Symbol/Function.h"
 #include "lldb/Symbol/Symbol.h"
+#include "lldb/Target/ExecutionContext.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/RegisterContext.h"
 #include "lldb/Target/StopInfo.h"
+#include "lldb/Target/Target.h"
 #include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlanRunToAddress.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -53,6 +57,14 @@
 
 ThreadPlanStepRange::~ThreadPlanStepRange ()
 {
+    ClearNextBranchBreakpoint();
+}
+
+void
+ThreadPlanStepRange::DidPush ()
+{
+    // See if we can find a "next range" breakpoint:
+    SetNextBranchBreakpoint();
 }
 
 bool
@@ -79,6 +91,7 @@
     // condense the ranges if they overlap, though I don't think it is likely
     // to be very important.
     m_address_ranges.push_back (new_range);
+    m_instruction_ranges.push_back (DisassemblerSP());
 }
 
 void
@@ -230,6 +243,145 @@
         return false;
 }
 
+InstructionList *
+ThreadPlanStepRange::GetInstructionsForAddress(lldb::addr_t addr, size_t &range_index, size_t &insn_offset)
+{
+    size_t num_ranges = m_address_ranges.size();
+    for (size_t i = 0; i < num_ranges; i++)
+    {
+        if (m_address_ranges[i].ContainsLoadAddress(addr, &GetTarget()))
+        {
+            // Some joker added a zero size range to the stepping range...
+            if (m_address_ranges[i].GetByteSize() == 0)
+                return NULL;
+
+            if (!m_instruction_ranges[i])
+            {
+                //Disassemble the address range given:
+                ExecutionContext exe_ctx (m_thread.GetProcess());
+                m_instruction_ranges[i] = Disassembler::DisassembleRange(GetTarget().GetArchitecture(),
+                                                                         NULL,
+                                                                         exe_ctx,
+                                                                         m_address_ranges[i]);
+                
+            }
+            if (!m_instruction_ranges[i])
+                return NULL;
+            else
+            {
+                // Find where we are in the instruction list as well.  If we aren't at an instruction,
+                // return NULL.  In this case, we're probably lost, and shouldn't try to do anything fancy.
+                
+                insn_offset = m_instruction_ranges[i]->GetInstructionList().GetIndexOfInstructionAtLoadAddress(addr, GetTarget());
+                if (insn_offset == UINT32_MAX)
+                    return NULL;
+                else
+                {
+                    range_index = i;
+                    return &m_instruction_ranges[i]->GetInstructionList();
+                }
+            }
+        }
+    }
+    return NULL;
+}
+
+void
+ThreadPlanStepRange::ClearNextBranchBreakpoint()
+{
+    if (m_next_branch_bp_sp)
+    {
+        GetTarget().RemoveBreakpointByID (m_next_branch_bp_sp->GetID());
+        m_next_branch_bp_sp.reset();
+    }
+}
+
+bool
+ThreadPlanStepRange::SetNextBranchBreakpoint ()
+{
+    // Stepping through ranges using breakpoints doesn't work yet, but with this off we fall back to instruction
+    // single stepping.
+    return false;
+    // Always clear the next branch breakpoint, we don't want to leave one of these stranded.
+    ClearNextBranchBreakpoint();
+    lldb::addr_t cur_addr = GetThread().GetRegisterContext()->GetPC();
+    // Find the current address in our address ranges, and fetch the disassembly if we haven't already:
+    size_t pc_index;
+    size_t range_index;
+    InstructionList *instructions = GetInstructionsForAddress (cur_addr, range_index, pc_index);
+    if (instructions == NULL)
+        return false;
+    else
+    {
+        uint32_t branch_index;
+        branch_index = instructions->GetIndexOfNextBranchInstruction (pc_index);
+        
+        Address run_to_address;
+        
+        // If we didn't find a branch, run to the end of the range.
+        if (branch_index == UINT32_MAX)
+        {
+            branch_index = instructions->GetSize() - 2;
+        }
+        if (branch_index - pc_index > 1)
+        {
+            const bool is_internal = true;
+            run_to_address = instructions->GetInstructionAtIndex(branch_index)->GetAddress();
+            m_next_branch_bp_sp = GetTarget().CreateBreakpoint(run_to_address, is_internal);
+            m_next_branch_bp_sp->SetThreadID(m_thread.GetID());
+            return true;
+        }
+    }
+    return false;
+}
+
+bool
+ThreadPlanStepRange::NextRangeBreakpointExplainsStop (lldb::StopInfoSP stop_info_sp)
+{
+    if (!m_next_branch_bp_sp)
+        return false;
+    
+    break_id_t bp_site_id = stop_info_sp->GetValue();
+    BreakpointSiteSP bp_site_sp = m_thread.GetProcess()->GetBreakpointSiteList().FindByID(bp_site_id);
+    if (!bp_site_sp->IsBreakpointAtThisSite (m_next_branch_bp_sp->GetID()))
+        return false;
+    else
+        return bp_site_sp->GetNumberOfOwners() == 1;
+}
+
+bool
+ThreadPlanStepRange::PlanExplainsStop ()
+{
+    // We always explain a stop.  Either we've just done a single step, in which
+    // case we'll do our ordinary processing, or we stopped for some
+    // reason that isn't handled by our sub-plans, in which case we want to just stop right
+    // away.
+    
+    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    StopInfoSP stop_info_sp = GetPrivateStopReason();
+    if (stop_info_sp)
+    {
+        StopReason reason = stop_info_sp->GetStopReason();
+
+        switch (reason)
+        {
+        case eStopReasonBreakpoint:
+            if (NextRangeBreakpointExplainsStop(stop_info_sp))
+                return true;
+        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();
+            break;
+        default:
+            break;
+        }
+    }
+    return true;
+}
+
 bool
 ThreadPlanStepRange::WillStop ()
 {
@@ -239,7 +391,10 @@
 StateType
 ThreadPlanStepRange::GetPlanRunState ()
 {
-    return eStateStepping;
+    if (m_next_branch_bp_sp)
+        return eStateRunning;
+    else
+        return eStateStepping;
 }
 
 bool





More information about the lldb-commits mailing list