@@ -31,6 +31,32 @@ using namespace lldb_private;
3131
3232uint32_t ThreadPlanStepOut::s_default_flag_values = 0 ;
3333
34+ // / Computes the target frame this plan should step out to.
35+ static StackFrameSP
36+ ComputeTargetFrame (Thread &thread, uint32_t start_frame_idx,
37+ std::vector<StackFrameSP> &skipped_frames) {
38+ uint32_t frame_idx = start_frame_idx + 1 ;
39+ StackFrameSP return_frame_sp = thread.GetStackFrameAtIndex (frame_idx);
40+ if (!return_frame_sp)
41+ return nullptr ;
42+
43+ while (return_frame_sp->IsArtificial () || return_frame_sp->IsHidden ()) {
44+ skipped_frames.push_back (return_frame_sp);
45+
46+ frame_idx++;
47+ return_frame_sp = thread.GetStackFrameAtIndex (frame_idx);
48+
49+ // We never expect to see an artificial frame without a regular ancestor.
50+ // Defensively refuse to step out.
51+ if (!return_frame_sp) {
52+ LLDB_LOG (GetLog (LLDBLog::Step),
53+ " Can't step out of frame with artificial ancestors" );
54+ return nullptr ;
55+ }
56+ }
57+ return return_frame_sp;
58+ }
59+
3460// ThreadPlanStepOut: Step out of the current frame
3561ThreadPlanStepOut::ThreadPlanStepOut (
3662 Thread &thread, SymbolContext *context, bool first_insn, bool stop_others,
@@ -44,34 +70,18 @@ ThreadPlanStepOut::ThreadPlanStepOut(
4470 m_return_addr(LLDB_INVALID_ADDRESS), m_stop_others(stop_others),
4571 m_immediate_step_from_function(nullptr ),
4672 m_calculate_return_value(gather_return_value) {
47- Log *log = GetLog (LLDBLog::Step);
4873 SetFlagsToDefault ();
4974 SetupAvoidNoDebug (step_out_avoids_code_without_debug_info);
5075
5176 m_step_from_insn = thread.GetRegisterContext ()->GetPC (0 );
5277
53- uint32_t return_frame_index = frame_idx + 1 ;
54- StackFrameSP return_frame_sp (thread. GetStackFrameAtIndex (return_frame_index) );
78+ StackFrameSP return_frame_sp =
79+ ComputeTargetFrame (thread, frame_idx, m_stepped_past_frames );
5580 StackFrameSP immediate_return_from_sp (thread.GetStackFrameAtIndex (frame_idx));
5681
5782 if (!return_frame_sp || !immediate_return_from_sp)
5883 return ; // we can't do anything here. ValidatePlan() will return false.
5984
60- // While stepping out, behave as-if artificial frames are not present.
61- while (return_frame_sp->IsArtificial () || return_frame_sp->IsHidden ()) {
62- m_stepped_past_frames.push_back (return_frame_sp);
63-
64- ++return_frame_index;
65- return_frame_sp = thread.GetStackFrameAtIndex (return_frame_index);
66-
67- // We never expect to see an artificial frame without a regular ancestor.
68- // If this happens, log the issue and defensively refuse to step out.
69- if (!return_frame_sp) {
70- LLDB_LOG (log, " Can't step out of frame with artificial ancestors" );
71- return ;
72- }
73- }
74-
7585 m_step_out_to_id = return_frame_sp->GetStackID ();
7686 m_immediate_step_from_id = immediate_return_from_sp->GetStackID ();
7787
@@ -125,6 +135,7 @@ ThreadPlanStepOut::ThreadPlanStepOut(
125135
126136 // Perform some additional validation on the return address.
127137 uint32_t permissions = 0 ;
138+ Log *log = GetLog (LLDBLog::Step);
128139 if (!m_process.GetLoadAddressPermissions (m_return_addr, permissions)) {
129140 LLDB_LOGF (log, " ThreadPlanStepOut(%p): Return address (0x%" PRIx64
130141 " ) permissions not found." , static_cast <void *>(this ),
0 commit comments