[Lldb-commits] [lldb] r163366 - in /lldb/trunk: include/lldb/Target/ThreadPlanStepInRange.h source/Target/ThreadPlanStepInRange.cpp
Jim Ingham
jingham at apple.com
Thu Sep 6 18:11:44 PDT 2012
Author: jingham
Date: Thu Sep 6 20:11:44 2012
New Revision: 163366
URL: http://llvm.org/viewvc/llvm-project?rev=163366&view=rev
Log:
Ensure that the ShouldStopHere plans get called even when doing "virtual" steps.
Modified:
lldb/trunk/include/lldb/Target/ThreadPlanStepInRange.h
lldb/trunk/source/Target/ThreadPlanStepInRange.cpp
Modified: lldb/trunk/include/lldb/Target/ThreadPlanStepInRange.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanStepInRange.h?rev=163366&r1=163365&r2=163366&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlanStepInRange.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlanStepInRange.h Thu Sep 6 20:11:44 2012
@@ -80,6 +80,7 @@
std::auto_ptr<RegularExpression> m_avoid_regexp_ap;
bool m_step_past_prologue; // FIXME: For now hard-coded to true, we could put a switch in for this if there's
// demand for that.
+ bool m_virtual_step; // true if we've just done a "virtual step", i.e. just moved the inline stack depth.
DISALLOW_COPY_AND_ASSIGN (ThreadPlanStepInRange);
Modified: lldb/trunk/source/Target/ThreadPlanStepInRange.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepInRange.cpp?rev=163366&r1=163365&r2=163366&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanStepInRange.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanStepInRange.cpp Thu Sep 6 20:11:44 2012
@@ -46,7 +46,8 @@
) :
ThreadPlanStepRange (ThreadPlan::eKindStepInRange, "Step Range stepping in", thread, range, addr_context, stop_others),
ThreadPlanShouldStopHere (this, ThreadPlanStepInRange::DefaultShouldStopHereCallback, NULL),
- m_step_past_prologue (true)
+ m_step_past_prologue (true),
+ m_virtual_step (false)
{
SetFlagsToDefault ();
}
@@ -86,113 +87,122 @@
ThreadPlan* new_plan = NULL;
- // Stepping through should be done stopping other threads in general, since we're setting a breakpoint and
- // continuing...
-
- bool stop_others;
- if (m_stop_others != lldb::eAllThreads)
- stop_others = true;
- else
- stop_others = false;
-
- FrameComparison frame_order = CompareCurrentFrameToStartFrame();
-
- if (frame_order == eFrameCompareOlder)
+ if (m_virtual_step)
{
- // If we're in an older frame then we should stop.
- //
- // A caveat to this is if we think the frame is older but we're actually in a trampoline.
- // I'm going to make the assumption that you wouldn't RETURN to a trampoline. So if we are
- // in a trampoline we think the frame is older because the trampoline confused the backtracer.
- new_plan = m_thread.QueueThreadPlanForStepThrough (m_stack_id, false, stop_others);
- if (new_plan == NULL)
- return true;
- else if (log)
- {
- log->Printf("Thought I stepped out, but in fact arrived at a trampoline.");
- }
-
- }
- 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
- // both the case of a frame that is younger, or the same as this frame.
- // 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've just completed a virtual step, all we need to do is check for a ShouldStopHere plan, and otherwise
+ // we're done.
+ new_plan = InvokeShouldStopHereCallback();
}
-
- // 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)
- new_plan = m_thread.QueueThreadPlanForStepThrough (m_stack_id, false, stop_others);
-
- if (log)
+ else
{
- if (new_plan != NULL)
- log->Printf ("Found a step through plan: %s", new_plan->GetName());
+ // Stepping through should be done stopping other threads in general, since we're setting a breakpoint and
+ // continuing...
+
+ bool stop_others;
+ if (m_stop_others != lldb::eAllThreads)
+ stop_others = true;
else
- log->Printf ("No step through plan found.");
- }
-
- // If not, give the "should_stop" callback a chance to push a plan to get us out of here.
- // But only do that if we actually have stepped in.
- if (!new_plan && frame_order == eFrameCompareYounger)
- new_plan = InvokeShouldStopHereCallback();
-
- // If we've stepped in and we are going to stop here, check to see if we were asked to
- // run past the prologue, and if so do that.
-
- if (new_plan == NULL && frame_order == eFrameCompareYounger && m_step_past_prologue)
- {
- lldb::StackFrameSP curr_frame = m_thread.GetStackFrameAtIndex(0);
- if (curr_frame)
- {
- size_t bytes_to_skip = 0;
- lldb::addr_t curr_addr = m_thread.GetRegisterContext()->GetPC();
- Address func_start_address;
-
- SymbolContext sc = curr_frame->GetSymbolContext (eSymbolContextFunction | eSymbolContextSymbol);
+ stop_others = false;
- if (sc.function)
+ FrameComparison frame_order = CompareCurrentFrameToStartFrame();
+
+ if (frame_order == eFrameCompareOlder)
+ {
+ // If we're in an older frame then we should stop.
+ //
+ // A caveat to this is if we think the frame is older but we're actually in a trampoline.
+ // I'm going to make the assumption that you wouldn't RETURN to a trampoline. So if we are
+ // in a trampoline we think the frame is older because the trampoline confused the backtracer.
+ new_plan = m_thread.QueueThreadPlanForStepThrough (m_stack_id, false, stop_others);
+ if (new_plan == NULL)
+ return true;
+ else if (log)
{
- func_start_address = sc.function->GetAddressRange().GetBaseAddress();
- if (curr_addr == func_start_address.GetLoadAddress(m_thread.CalculateTarget().get()))
- bytes_to_skip = sc.function->GetPrologueByteSize();
+ log->Printf("Thought I stepped out, but in fact arrived at a trampoline.");
}
- else if (sc.symbol)
+
+ }
+ 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
+ // both the case of a frame that is younger, or the same as this frame.
+ // 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())
{
- func_start_address = sc.symbol->GetAddress();
- if (curr_addr == func_start_address.GetLoadAddress(m_thread.CalculateTarget().get()))
- bytes_to_skip = sc.symbol->GetPrologueByteSize();
+ SetNextBranchBreakpoint();
+ return false;
}
-
- if (bytes_to_skip != 0)
+
+ 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)
+ new_plan = m_thread.QueueThreadPlanForStepThrough (m_stack_id, false, stop_others);
+
+ if (log)
+ {
+ if (new_plan != NULL)
+ log->Printf ("Found a step through plan: %s", new_plan->GetName());
+ else
+ log->Printf ("No step through plan found.");
+ }
+
+ // If not, give the "should_stop" callback a chance to push a plan to get us out of here.
+ // But only do that if we actually have stepped in.
+ if (!new_plan && frame_order == eFrameCompareYounger)
+ new_plan = InvokeShouldStopHereCallback();
+
+ // If we've stepped in and we are going to stop here, check to see if we were asked to
+ // run past the prologue, and if so do that.
+
+ if (new_plan == NULL && frame_order == eFrameCompareYounger && m_step_past_prologue)
+ {
+ lldb::StackFrameSP curr_frame = m_thread.GetStackFrameAtIndex(0);
+ if (curr_frame)
{
- func_start_address.Slide (bytes_to_skip);
- log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
- if (log)
- log->Printf ("Pushing past prologue ");
-
- new_plan = m_thread.QueueThreadPlanForRunToAddress(false, func_start_address,true);
+ size_t bytes_to_skip = 0;
+ lldb::addr_t curr_addr = m_thread.GetRegisterContext()->GetPC();
+ Address func_start_address;
+
+ SymbolContext sc = curr_frame->GetSymbolContext (eSymbolContextFunction | eSymbolContextSymbol);
+
+ if (sc.function)
+ {
+ func_start_address = sc.function->GetAddressRange().GetBaseAddress();
+ if (curr_addr == func_start_address.GetLoadAddress(m_thread.CalculateTarget().get()))
+ bytes_to_skip = sc.function->GetPrologueByteSize();
+ }
+ else if (sc.symbol)
+ {
+ func_start_address = sc.symbol->GetAddress();
+ if (curr_addr == func_start_address.GetLoadAddress(m_thread.CalculateTarget().get()))
+ bytes_to_skip = sc.symbol->GetPrologueByteSize();
+ }
+
+ if (bytes_to_skip != 0)
+ {
+ func_start_address.Slide (bytes_to_skip);
+ log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
+ if (log)
+ log->Printf ("Pushing past prologue ");
+
+ new_plan = m_thread.QueueThreadPlanForRunToAddress(false, func_start_address,true);
+ }
}
}
- }
+ }
if (new_plan == NULL)
{
@@ -306,6 +316,9 @@
// 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.
+ if (m_virtual_step)
+ return true;
+
StopInfoSP stop_info_sp = GetPrivateStopReason();
if (stop_info_sp)
{
@@ -347,6 +360,10 @@
log->Printf ("ThreadPlanStepInRange::WillResume: returning false, inline_depth: %d",
m_thread.GetCurrentInlinedDepth());
SetStopInfo(StopInfo::CreateStopReasonToTrace(m_thread));
+
+ // FIXME: Maybe it would be better to create a InlineStep stop reason, but then
+ // the whole rest of the world would have to handle that stop reason.
+ m_virtual_step = true;
}
return !step_without_resume;
}
More information about the lldb-commits
mailing list