[Lldb-commits] [lldb] r163044 - in /lldb/trunk: include/lldb/Target/ source/Plugins/Process/gdb-remote/ source/Target/
Jim Ingham
jingham at apple.com
Fri Aug 31 18:02:42 PDT 2012
Author: jingham
Date: Fri Aug 31 20:02:41 2012
New Revision: 163044
URL: http://llvm.org/viewvc/llvm-project?rev=163044&view=rev
Log:
Initial check-in of "fancy" inlined stepping. Doesn't do anything useful unless you switch LLDB_FANCY_INLINED_STEPPING to true. With that
on, basic inlined stepping works, including step-over of inlined functions. But for some as yet mysterious reason i386 debugging gets an
assert and dies immediately. So for now its off.
Modified:
lldb/trunk/include/lldb/Target/StackFrame.h
lldb/trunk/include/lldb/Target/StackFrameList.h
lldb/trunk/include/lldb/Target/Thread.h
lldb/trunk/include/lldb/Target/ThreadList.h
lldb/trunk/include/lldb/Target/ThreadPlanStepInRange.h
lldb/trunk/include/lldb/Target/ThreadPlanStepOverRange.h
lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
lldb/trunk/source/Target/Process.cpp
lldb/trunk/source/Target/StackFrame.cpp
lldb/trunk/source/Target/StackFrameList.cpp
lldb/trunk/source/Target/Thread.cpp
lldb/trunk/source/Target/ThreadList.cpp
lldb/trunk/source/Target/ThreadPlanStepInRange.cpp
lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp
Modified: lldb/trunk/include/lldb/Target/StackFrame.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StackFrame.h?rev=163044&r1=163043&r2=163044&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/StackFrame.h (original)
+++ lldb/trunk/include/lldb/Target/StackFrame.h Fri Aug 31 20:02:41 2012
@@ -130,10 +130,7 @@
IsInlined ();
uint32_t
- GetFrameIndex () const
- {
- return m_frame_index;
- }
+ GetFrameIndex () const;
uint32_t
GetConcreteFrameIndex () const
Modified: lldb/trunk/include/lldb/Target/StackFrameList.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StackFrameList.h?rev=163044&r1=163043&r2=163044&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/StackFrameList.h (original)
+++ lldb/trunk/include/lldb/Target/StackFrameList.h Fri Aug 31 20:02:41 2012
@@ -55,7 +55,19 @@
// Mark a stack frame as the current frame using the frame index
bool
SetSelectedFrameByIndex (uint32_t idx);
-
+
+ uint32_t
+ GetVisibleStackFrameIndex(uint32_t idx)
+ {
+ if (m_current_inlined_depth < UINT32_MAX)
+ return idx - m_current_inlined_depth;
+ else
+ return idx;
+ }
+
+ void
+ CalculateCurrentInlinedDepth ();
+
void
SetDefaultFileAndLineToSelectedFrame();
@@ -104,6 +116,15 @@
m_concrete_frames_fetched = UINT32_MAX;
}
+ bool
+ DecrementCurrentInlinedDepth ();
+
+ void
+ ResetCurrentInlinedDepth();
+
+ uint32_t
+ GetCurrentInlinedDepth ();
+
//------------------------------------------------------------------
// Classes that inherit from StackFrameList can see and modify these
//------------------------------------------------------------------
@@ -117,6 +138,8 @@
collection m_frames;
uint32_t m_selected_frame_idx;
uint32_t m_concrete_frames_fetched;
+ uint32_t m_current_inlined_depth;
+ lldb::addr_t m_current_inlined_pc;
bool m_show_inlined_frames;
private:
Modified: lldb/trunk/include/lldb/Target/Thread.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Thread.h?rev=163044&r1=163043&r2=163044&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Thread.h (original)
+++ lldb/trunk/include/lldb/Target/Thread.h Fri Aug 31 20:02:41 2012
@@ -271,6 +271,18 @@
virtual lldb::StackFrameSP
GetFrameWithConcreteFrameIndex (uint32_t unwind_idx);
+ bool
+ DecrementCurrentInlinedDepth()
+ {
+ return GetStackFrameList()->DecrementCurrentInlinedDepth();
+ }
+
+ uint32_t
+ GetCurrentInlinedDepth()
+ {
+ return GetStackFrameList()->DecrementCurrentInlinedDepth();
+ }
+
virtual lldb::StackFrameSP
GetFrameWithStackID (const StackID &stack_id)
{
@@ -706,6 +718,7 @@
friend class ThreadPlan;
friend class ThreadList;
friend class StackFrameList;
+ friend class StackFrame;
// This is necessary to make sure thread assets get destroyed while the thread is still in good shape
// to call virtual thread methods. This must be called by classes that derive from Thread in their destructor.
Modified: lldb/trunk/include/lldb/Target/ThreadList.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadList.h?rev=163044&r1=163043&r2=163044&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadList.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadList.h Fri Aug 31 20:02:41 2012
@@ -92,6 +92,19 @@
void
RefreshStateAfterStop ();
+ //------------------------------------------------------------------
+ /// The thread list asks tells all the threads it is about to resume.
+ /// If a thread can "resume" without having to resume the target, it
+ /// will return false for WillResume, and then the process will not be
+ /// restarted.
+ ///
+ /// @return
+ /// \b true instructs the process to resume normally,
+ /// \b false means start & stopped events will be generated, but
+ /// the process will not actually run. The thread must then return
+ /// the correct StopInfo when asked.
+ ///
+ //------------------------------------------------------------------
bool
WillResume ();
Modified: lldb/trunk/include/lldb/Target/ThreadPlanStepInRange.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanStepInRange.h?rev=163044&r1=163043&r2=163044&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlanStepInRange.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlanStepInRange.h Fri Aug 31 20:02:41 2012
@@ -52,6 +52,8 @@
virtual bool
PlanExplainsStop ();
+ virtual bool WillResume (lldb::StateType resume_state, bool current_plan);
+
protected:
virtual void
Modified: lldb/trunk/include/lldb/Target/ThreadPlanStepOverRange.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanStepOverRange.h?rev=163044&r1=163043&r2=163044&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlanStepOverRange.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlanStepOverRange.h Fri Aug 31 20:02:41 2012
@@ -35,7 +35,8 @@
virtual void GetDescription (Stream *s, lldb::DescriptionLevel level);
virtual bool ShouldStop (Event *event_ptr);
virtual bool PlanExplainsStop ();
-
+ virtual bool WillResume (lldb::StateType resume_state, bool current_plan);
+
protected:
private:
@@ -47,6 +48,7 @@
const SymbolContext &addr_context,
lldb::RunMode stop_others,
bool avoid_code_without_debug_info);
+ bool m_first_resume;
DISALLOW_COPY_AND_ASSIGN (ThreadPlanStepOverRange);
Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp?rev=163044&r1=163043&r2=163044&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp Fri Aug 31 20:02:41 2012
@@ -83,11 +83,16 @@
bool
ThreadGDBRemote::WillResume (StateType resume_state)
{
- ClearStackFrames();
// Call the Thread::WillResume first. If we stop at a signal, the stop info
// class for signal will set the resume signal that we need below. The signal
// stuff obeys the Process::UnixSignal defaults.
- Thread::WillResume(resume_state);
+ // If the thread's WillResume returns false, that means that we aren't going to actually resume,
+ // in which case we should not do the rest of our "resume" work.
+
+ if (!Thread::WillResume(resume_state))
+ return false;
+
+ ClearStackFrames();
int signo = GetResumeSignal();
lldb::LogSP log(lldb_private::GetLogIfAnyCategoriesSet (GDBR_LOG_THREAD));
Modified: lldb/trunk/source/Target/Process.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=163044&r1=163043&r2=163044&view=diff
==============================================================================
--- lldb/trunk/source/Target/Process.cpp (original)
+++ lldb/trunk/source/Target/Process.cpp Fri Aug 31 20:02:41 2012
@@ -2975,7 +2975,13 @@
}
else
{
- error.SetErrorStringWithFormat("Process::WillResume() thread list returned false after WillResume");
+ // Somebody wanted to run without running. So generate a continue & a stopped event,
+ // and let the world handle them.
+ if (log)
+ log->Printf ("Process::PrivateResume() asked to simulate a start & stop.");
+
+ SetPrivateState(eStateRunning);
+ SetPrivateState(eStateStopped);
}
}
else if (log)
Modified: lldb/trunk/source/Target/StackFrame.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrame.cpp?rev=163044&r1=163043&r2=163044&view=diff
==============================================================================
--- lldb/trunk/source/Target/StackFrame.cpp (original)
+++ lldb/trunk/source/Target/StackFrame.cpp Fri Aug 31 20:02:41 2012
@@ -197,6 +197,16 @@
return m_id;
}
+uint32_t
+StackFrame::GetFrameIndex () const
+{
+ ThreadSP thread_sp = GetThread();
+ if (thread_sp)
+ return thread_sp->GetStackFrameList()->GetVisibleStackFrameIndex(m_frame_index);
+ else
+ return m_frame_index;
+}
+
void
StackFrame::SetSymbolContextScope (SymbolContextScope *symbol_scope)
{
Modified: lldb/trunk/source/Target/StackFrameList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrameList.cpp?rev=163044&r1=163043&r2=163044&view=diff
==============================================================================
--- lldb/trunk/source/Target/StackFrameList.cpp (original)
+++ lldb/trunk/source/Target/StackFrameList.cpp Fri Aug 31 20:02:41 2012
@@ -21,6 +21,7 @@
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/Unwind.h"
@@ -45,8 +46,15 @@
m_frames (),
m_selected_frame_idx (0),
m_concrete_frames_fetched (0),
+ m_current_inlined_depth (UINT32_MAX),
+ m_current_inlined_pc (LLDB_INVALID_ADDRESS),
m_show_inlined_frames (show_inline_frames)
{
+ if (prev_frames_sp)
+ {
+ m_current_inlined_depth = prev_frames_sp->m_current_inlined_depth;
+ m_current_inlined_pc = prev_frames_sp->m_current_inlined_pc;
+ }
}
//----------------------------------------------------------------------
@@ -57,6 +65,140 @@
}
void
+StackFrameList::CalculateCurrentInlinedDepth()
+{
+ uint32_t cur_inlined_depth = GetCurrentInlinedDepth();
+ if (cur_inlined_depth == UINT32_MAX)
+ {
+ ResetCurrentInlinedDepth();
+ }
+}
+
+uint32_t
+StackFrameList::GetCurrentInlinedDepth ()
+{
+ if (m_show_inlined_frames)
+ {
+ lldb::addr_t cur_pc = m_thread.GetRegisterContext()->GetPC();
+ if (cur_pc != m_current_inlined_pc)
+ {
+ m_current_inlined_pc = LLDB_INVALID_ADDRESS;
+ m_current_inlined_depth = UINT32_MAX;
+ }
+ return m_current_inlined_depth;
+ }
+ else
+ {
+ return UINT32_MAX;
+ }
+}
+
+static const bool LLDB_FANCY_INLINED_STEPPING = false;
+
+void
+StackFrameList::ResetCurrentInlinedDepth ()
+{
+ if (LLDB_FANCY_INLINED_STEPPING && m_show_inlined_frames)
+ {
+ GetFramesUpTo(0);
+ if (!m_frames[0]->IsInlined())
+ {
+ m_current_inlined_depth = UINT32_MAX;
+ m_current_inlined_pc = LLDB_INVALID_ADDRESS;
+ }
+ else
+ {
+ // We only need to do something special about inlined blocks when we
+ // are at the beginning of an inlined function:
+ // FIXME: We probably also have to do something special if the PC is at the END
+ // of an inlined function, which coincides with the end of either its containing
+ // function or another inlined function.
+
+ lldb::addr_t curr_pc = m_thread.GetRegisterContext()->GetPC();
+ Block *block_ptr = m_frames[0]->GetFrameBlock();
+ if (block_ptr)
+ {
+ Address pc_as_address;
+ pc_as_address.SetLoadAddress(curr_pc, &(m_thread.GetProcess()->GetTarget()));
+ AddressRange containing_range;
+ if (block_ptr->GetRangeContainingAddress(pc_as_address, containing_range))
+ {
+ if (pc_as_address == containing_range.GetBaseAddress())
+ {
+ // If we got here because of a breakpoint hit, then set the inlined depth depending on where
+ // the breakpoint was set.
+ // If we got here because of a crash, then set the inlined depth to the deepest most block.
+ // Otherwise, we stopped here naturally as the result of a step, so set ourselves in the
+ // containing frame of the whole set of nested inlines, so the user can then "virtually"
+ // step into the frames one by one, or next over the whole mess.
+ // Note: We don't have to handle being somewhere in the middle of the stack here, since
+ // ResetCurrentInlinedDepth doesn't get called if there is a valid inlined depth set.
+ StopInfoSP stop_info_sp = m_thread.GetStopInfo();
+ if (stop_info_sp)
+ {
+ switch (stop_info_sp->GetStopReason())
+ {
+ case eStopReasonBreakpoint:
+ {
+
+ }
+ break;
+ case eStopReasonWatchpoint:
+ case eStopReasonException:
+ case eStopReasonSignal:
+ // In all these cases we want to stop in the deepest most frame.
+ m_current_inlined_pc = curr_pc;
+ m_current_inlined_depth = 0;
+ break;
+ default:
+ {
+ // Otherwise, we should set ourselves at the container of the inlining, so that the
+ // user can descend into them.
+ // So first we check whether we have more than one inlined block sharing this PC:
+ int num_inlined_functions = 0;
+
+ for (Block *container_ptr = block_ptr->GetInlinedParent();
+ container_ptr != NULL;
+ container_ptr = container_ptr->GetInlinedParent())
+ {
+ if (!container_ptr->GetRangeContainingAddress(pc_as_address, containing_range))
+ break;
+ if (pc_as_address != containing_range.GetBaseAddress())
+ break;
+
+ num_inlined_functions++;
+ }
+ m_current_inlined_pc = curr_pc;
+ m_current_inlined_depth = num_inlined_functions + 1;
+
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+bool
+StackFrameList::DecrementCurrentInlinedDepth ()
+{
+ if (m_show_inlined_frames)
+ {
+ uint32_t current_inlined_depth = GetCurrentInlinedDepth();
+ if (current_inlined_depth != UINT32_MAX)
+ {
+ if (current_inlined_depth > 0)
+ m_current_inlined_depth--;
+ return true;
+ }
+ }
+ return false;
+}
+
+void
StackFrameList::GetFramesUpTo(uint32_t end_idx)
{
// We've already gotten more frames than asked for, or we've already finished unwinding, return.
@@ -70,6 +212,22 @@
#if defined (DEBUG_STACK_FRAMES)
StreamFile s(stdout, false);
#endif
+ // If we are hiding some frames from the outside world, we need to add those onto the total count of
+ // frames to fetch. However, we don't need ot do that if end_idx is 0 since in that case we always
+ // get the first concrete frame and all the inlined frames below it...
+
+ uint32_t inlined_depth = 0;
+ if (end_idx > 0)
+ {
+ inlined_depth = GetCurrentInlinedDepth();
+ if (inlined_depth != UINT32_MAX)
+ {
+ if (end_idx > 0)
+ end_idx += inlined_depth;
+ }
+ else
+ inlined_depth = 0;
+ }
StackFrameSP unwind_frame_sp;
do
@@ -98,7 +256,7 @@
unwind_frame_sp.reset (new StackFrame (m_thread.shared_from_this(),
m_frames.size(),
- idx,
+ idx,
m_thread.m_reg_context_sp,
cfa,
pc,
@@ -246,7 +404,12 @@
if (can_create)
GetFramesUpTo (UINT32_MAX);
- return m_frames.size();
+
+ uint32_t inlined_depth = GetCurrentInlinedDepth();
+ if (inlined_depth == UINT32_MAX)
+ return m_frames.size();
+ else
+ return m_frames.size() - inlined_depth;
}
void
@@ -278,6 +441,10 @@
{
StackFrameSP frame_sp;
Mutex::Locker locker (m_mutex);
+ uint32_t inlined_depth = GetCurrentInlinedDepth();
+ if (inlined_depth != UINT32_MAX)
+ idx += inlined_depth;
+
if (idx < m_frames.size())
frame_sp = m_frames[idx];
@@ -396,6 +563,9 @@
if (pos->get() == frame)
{
m_selected_frame_idx = std::distance (begin, pos);
+ uint32_t inlined_depth = GetCurrentInlinedDepth();
+ if (inlined_depth != UINT32_MAX)
+ m_selected_frame_idx -= inlined_depth;
break;
}
}
Modified: lldb/trunk/source/Target/Thread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Thread.cpp?rev=163044&r1=163043&r2=163044&view=diff
==============================================================================
--- lldb/trunk/source/Target/Thread.cpp (original)
+++ lldb/trunk/source/Target/Thread.cpp Fri Aug 31 20:02:41 2012
@@ -349,15 +349,22 @@
// plans in case a plan needs to do any special business before it runs.
ThreadPlan *plan_ptr = GetCurrentPlan();
- plan_ptr->WillResume(resume_state, true);
+ bool need_to_resume = plan_ptr->WillResume(resume_state, true);
while ((plan_ptr = GetPreviousPlan(plan_ptr)) != NULL)
{
plan_ptr->WillResume (resume_state, false);
}
- m_actual_stop_info_sp.reset();
- return true;
+ // If the WillResume for the plan says we are faking a resume, then it will have set an appropriate stop info.
+ // In that case, don't reset it here.
+
+ if (need_to_resume)
+ {
+ m_actual_stop_info_sp.reset();
+ }
+
+ return need_to_resume;
}
void
@@ -409,7 +416,10 @@
GetRegisterContext()->GetPC());
return false;
}
-
+
+ // Adjust the stack frame's current inlined depth if it is needed.
+ GetStackFrameList()->CalculateCurrentInlinedDepth();
+
if (log)
{
log->Printf ("Thread::%s for tid = 0x%4.4llx, pc = 0x%16.16llx",
Modified: lldb/trunk/source/Target/ThreadList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadList.cpp?rev=163044&r1=163043&r2=163044&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadList.cpp (original)
+++ lldb/trunk/source/Target/ThreadList.cpp Fri Aug 31 20:02:41 2012
@@ -362,7 +362,6 @@
// Run through the threads and perform their momentary actions.
// But we only do this for threads that are running, user suspended
// threads stay where they are.
- bool success = true;
Mutex::Locker locker(m_threads_mutex);
m_process->UpdateThreadListIfNeeded();
@@ -449,6 +448,8 @@
}
+ bool need_to_resume = true;
+
if (immediate_thread_sp)
{
for (pos = m_threads.begin(); pos != end; ++pos)
@@ -471,7 +472,8 @@
run_state = thread_sp->GetCurrentPlan()->RunState();
else
run_state = eStateSuspended;
- thread_sp->WillResume(run_state);
+ if (!thread_sp->WillResume(run_state))
+ need_to_resume = false;
}
}
else
@@ -497,13 +499,16 @@
{
ThreadSP thread_sp(*pos);
if (thread_sp == thread_to_run)
- thread_sp->WillResume(thread_sp->GetCurrentPlan()->RunState());
+ {
+ if (!thread_sp->WillResume(thread_sp->GetCurrentPlan()->RunState()))
+ need_to_resume = false;
+ }
else
thread_sp->WillResume (eStateSuspended);
}
}
- return success;
+ return need_to_resume;
}
void
Modified: lldb/trunk/source/Target/ThreadPlanStepInRange.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepInRange.cpp?rev=163044&r1=163043&r2=163044&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanStepInRange.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanStepInRange.cpp Fri Aug 31 20:02:41 2012
@@ -256,12 +256,12 @@
{
bool should_step_out = false;
StackFrame *frame = current_plan->GetThread().GetStackFrameAtIndex(0).get();
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
if (flags.Test(eAvoidNoDebug))
{
if (!frame->HasDebugInformation())
{
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
if (log)
log->Printf ("Stepping out of frame with no debug info");
@@ -306,7 +306,6 @@
// The only variation is that if we are doing "step by running to next branch" in which case
// if we hit our branch breakpoint we don't set the plan to complete.
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
StopInfoSP stop_info_sp = GetPrivateStopReason();
if (stop_info_sp)
{
@@ -320,9 +319,12 @@
case eStopReasonWatchpoint:
case eStopReasonSignal:
case eStopReasonException:
- if (log)
- log->PutCString ("ThreadPlanStepInRange got asked if it explains the stop for some reason other than step.");
- SetPlanComplete(false);
+ {
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+ if (log)
+ log->PutCString ("ThreadPlanStepInRange got asked if it explains the stop for some reason other than step.");
+ SetPlanComplete(false);
+ }
break;
default:
break;
@@ -330,3 +332,25 @@
}
return true;
}
+
+bool
+ThreadPlanStepInRange::WillResume (lldb::StateType resume_state, bool current_plan)
+{
+ if (resume_state == eStateStepping && current_plan)
+ {
+ // See if we are about to step over a virtual inlined call.
+ bool step_without_resume = m_thread.DecrementCurrentInlinedDepth();
+ if (step_without_resume)
+ {
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+ if (log)
+ log->Printf ("ThreadPlanStepInRange::WillResume: returning false, inline_depth: %d",
+ m_thread.GetCurrentInlinedDepth());
+ SetStopInfo(StopInfo::CreateStopReasonToTrace(m_thread));
+ }
+ return !step_without_resume;
+ }
+ else
+ return ThreadPlan::WillResume(resume_state, current_plan);
+
+}
Modified: lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp?rev=163044&r1=163043&r2=163044&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp Fri Aug 31 20:02:41 2012
@@ -17,6 +17,8 @@
#include "lldb/lldb-private-log.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Stream.h"
+#include "lldb/Symbol/Block.h"
+#include "lldb/Symbol/Function.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Target.h"
@@ -40,7 +42,8 @@
const SymbolContext &addr_context,
lldb::RunMode stop_others
) :
- ThreadPlanStepRange (ThreadPlan::eKindStepOverRange, "Step range stepping over", thread, range, addr_context, stop_others)
+ ThreadPlanStepRange (ThreadPlan::eKindStepOverRange, "Step range stepping over", thread, range, addr_context, stop_others),
+ m_first_resume(true)
{
}
@@ -116,7 +119,7 @@
// in so I left out the target check. And sometimes the module comes in as the .o file from the
// inlined range, so I left that out too...
- bool older_ctx_is_equivalent = false;
+ bool older_ctx_is_equivalent = true;
if (m_addr_context.comp_unit)
{
if (m_addr_context.comp_unit == older_context.comp_unit)
@@ -126,10 +129,6 @@
if (m_addr_context.block && m_addr_context.block == older_context.block)
{
older_ctx_is_equivalent = true;
- if (m_addr_context.line_entry.IsValid() && LineEntry::Compare(m_addr_context.line_entry, older_context.line_entry) != 0)
- {
- older_ctx_is_equivalent = false;
- }
}
}
}
@@ -213,6 +212,9 @@
switch (reason)
{
+ case eStopReasonTrace:
+ return true;
+ break;
case eStopReasonBreakpoint:
if (NextRangeBreakpointExplainsStop(stop_info_sp))
return true;
@@ -222,13 +224,63 @@
case eStopReasonWatchpoint:
case eStopReasonSignal:
case eStopReasonException:
+ default:
if (log)
log->PutCString ("ThreadPlanStepInRange got asked if it explains the stop for some reason other than step.");
return false;
break;
- default:
- break;
}
}
return true;
}
+
+bool
+ThreadPlanStepOverRange::WillResume (lldb::StateType resume_state, bool current_plan)
+{
+ if (resume_state != eStateSuspended && m_first_resume)
+ {
+ m_first_resume = false;
+ if (resume_state == eStateStepping && current_plan)
+ {
+ // See if we are about to step over an inlined call in the middle of the inlined stack, if so figure
+ // out its extents and reset our range to step over that.
+ bool in_inlined_stack = m_thread.DecrementCurrentInlinedDepth();
+ if (in_inlined_stack)
+ {
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+ if (log)
+ log->Printf ("ThreadPlanStepInRange::WillResume: adjusting range to the frame at inlined depth %d.",
+ m_thread.GetCurrentInlinedDepth());
+ StackFrameSP stack_sp = m_thread.GetStackFrameAtIndex(0);
+ if (stack_sp)
+ {
+ Block *frame_block = stack_sp->GetFrameBlock();
+ lldb::addr_t curr_pc = m_thread.GetRegisterContext()->GetPC();
+ AddressRange my_range;
+ if (frame_block->GetRangeContainingLoadAddress(curr_pc, m_thread.GetProcess()->GetTarget(), my_range))
+ {
+ m_address_ranges.clear();
+ m_address_ranges.push_back(my_range);
+ if (log)
+ {
+ StreamString s;
+ const InlineFunctionInfo *inline_info = frame_block->GetInlinedFunctionInfo();
+ const char *name;
+ if (inline_info)
+ name = inline_info->GetName().AsCString();
+ else
+ name = "<unknown-notinlined>";
+
+ s.Printf ("Stepping over inlined function \"%s\" in inlined stack: ", name);
+ DumpRanges(&s);
+ log->PutCString(s.GetData());
+ }
+ }
+
+ }
+ }
+ }
+ }
+
+ return ThreadPlan::WillResume(resume_state, current_plan);
+}
More information about the lldb-commits
mailing list