summaryrefslogtreecommitdiffstats
path: root/lldb/source/Target/ThreadPlanStepOut.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Target/ThreadPlanStepOut.cpp')
-rw-r--r--lldb/source/Target/ThreadPlanStepOut.cpp30
1 files changed, 27 insertions, 3 deletions
diff --git a/lldb/source/Target/ThreadPlanStepOut.cpp b/lldb/source/Target/ThreadPlanStepOut.cpp
index f2db6e4b6f4..9acc17c7622 100644
--- a/lldb/source/Target/ThreadPlanStepOut.cpp
+++ b/lldb/source/Target/ThreadPlanStepOut.cpp
@@ -48,18 +48,36 @@ ThreadPlanStepOut::ThreadPlanStepOut(
m_return_addr(LLDB_INVALID_ADDRESS), m_stop_others(stop_others),
m_immediate_step_from_function(nullptr),
m_calculate_return_value(gather_return_value) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
SetFlagsToDefault();
SetupAvoidNoDebug(step_out_avoids_code_without_debug_info);
m_step_from_insn = m_thread.GetRegisterContext()->GetPC(0);
- StackFrameSP return_frame_sp(m_thread.GetStackFrameAtIndex(frame_idx + 1));
+ uint32_t return_frame_index = frame_idx + 1;
+ StackFrameSP return_frame_sp(
+ m_thread.GetStackFrameAtIndex(return_frame_index));
StackFrameSP immediate_return_from_sp(
m_thread.GetStackFrameAtIndex(frame_idx));
if (!return_frame_sp || !immediate_return_from_sp)
return; // we can't do anything here. ValidatePlan() will return false.
+ // While stepping out, behave as-if artificial frames are not present.
+ while (return_frame_sp->IsArtificial()) {
+ m_stepped_past_frames.push_back(return_frame_sp);
+
+ ++return_frame_index;
+ return_frame_sp = m_thread.GetStackFrameAtIndex(return_frame_index);
+
+ // We never expect to see an artificial frame without a regular ancestor.
+ // If this happens, log the issue and defensively refuse to step out.
+ if (!return_frame_sp) {
+ LLDB_LOG(log, "Can't step out of frame with artificial ancestors");
+ return;
+ }
+ }
+
m_step_out_to_id = return_frame_sp->GetStackID();
m_immediate_step_from_id = immediate_return_from_sp->GetStackID();
@@ -67,7 +85,7 @@ ThreadPlanStepOut::ThreadPlanStepOut(
// have to be a little more careful. It is non-trivial to determine the real
// "return code address" for an inlined frame, so we have to work our way to
// that frame and then step out.
- if (immediate_return_from_sp && immediate_return_from_sp->IsInlined()) {
+ if (immediate_return_from_sp->IsInlined()) {
if (frame_idx > 0) {
// First queue a plan that gets us to this inlined frame, and when we get
// there we'll queue a second plan that walks us out of this frame.
@@ -82,7 +100,7 @@ ThreadPlanStepOut::ThreadPlanStepOut(
// just do that now.
QueueInlinedStepPlan(false);
}
- } else if (return_frame_sp) {
+ } else {
// Find the return address and set a breakpoint there:
// FIXME - can we do this more securely if we know first_insn?
@@ -198,6 +216,12 @@ void ThreadPlanStepOut::GetDescription(Stream *s,
s->Printf(" using breakpoint site %d", m_return_bp_id);
}
}
+
+ s->Printf("\n");
+ for (StackFrameSP frame_sp : m_stepped_past_frames) {
+ s->Printf("Stepped out past: ");
+ frame_sp->DumpUsingSettingsFormat(s);
+ }
}
bool ThreadPlanStepOut::ValidatePlan(Stream *error) {
OpenPOWER on IntegriCloud