[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