@@ -38,6 +38,32 @@ using namespace lldb_private;
3838
3939uint32_t ThreadPlanStepOut::s_default_flag_values = 0 ;
4040
41+ // / Computes the target frame this plan should step out to.
42+ static StackFrameSP
43+ ComputeTargetFrame (Thread &thread, uint32_t start_frame_idx,
44+ std::vector<StackFrameSP> &skipped_frames) {
45+ uint32_t frame_idx = start_frame_idx + 1 ;
46+ StackFrameSP return_frame_sp = thread.GetStackFrameAtIndex (frame_idx);
47+ if (!return_frame_sp)
48+ return nullptr ;
49+
50+ while (return_frame_sp->IsArtificial () || return_frame_sp->IsHidden ()) {
51+ skipped_frames.push_back (return_frame_sp);
52+
53+ frame_idx++;
54+ return_frame_sp = thread.GetStackFrameAtIndex (frame_idx);
55+
56+ // We never expect to see an artificial frame without a regular ancestor.
57+ // Defensively refuse to step out.
58+ if (!return_frame_sp) {
59+ LLDB_LOG (GetLog (LLDBLog::Step),
60+ " Can't step out of frame with artificial ancestors" );
61+ return nullptr ;
62+ }
63+ }
64+ return return_frame_sp;
65+ }
66+
4167// ThreadPlanStepOut: Step out of the current frame
4268ThreadPlanStepOut::ThreadPlanStepOut (
4369 Thread &thread, SymbolContext *context, bool first_insn, bool stop_others,
@@ -54,34 +80,18 @@ ThreadPlanStepOut::ThreadPlanStepOut(
5480 m_stop_others(stop_others), m_immediate_step_from_function(nullptr ),
5581 m_is_swift_error_value(false ),
5682 m_calculate_return_value(gather_return_value) {
57- Log *log = GetLog (LLDBLog::Step);
5883 SetFlagsToDefault ();
5984 SetupAvoidNoDebug (step_out_avoids_code_without_debug_info);
6085
6186 m_step_from_insn = thread.GetRegisterContext ()->GetPC (0 );
6287
63- uint32_t return_frame_index = frame_idx + 1 ;
64- StackFrameSP return_frame_sp (thread. GetStackFrameAtIndex (return_frame_index) );
88+ StackFrameSP return_frame_sp =
89+ ComputeTargetFrame (thread, frame_idx, m_stepped_past_frames );
6590 StackFrameSP immediate_return_from_sp (thread.GetStackFrameAtIndex (frame_idx));
6691
6792 if (!return_frame_sp || !immediate_return_from_sp)
6893 return ; // we can't do anything here. ValidatePlan() will return false.
6994
70- // While stepping out, behave as-if artificial frames are not present.
71- while (return_frame_sp->IsArtificial () || return_frame_sp->IsHidden ()) {
72- m_stepped_past_frames.push_back (return_frame_sp);
73-
74- ++return_frame_index;
75- return_frame_sp = thread.GetStackFrameAtIndex (return_frame_index);
76-
77- // We never expect to see an artificial frame without a regular ancestor.
78- // If this happens, log the issue and defensively refuse to step out.
79- if (!return_frame_sp) {
80- LLDB_LOG (log, " Can't step out of frame with artificial ancestors" );
81- return ;
82- }
83- }
84-
8595 m_step_out_to_id = return_frame_sp->GetStackID ();
8696 m_immediate_step_from_id = immediate_return_from_sp->GetStackID ();
8797
@@ -135,6 +145,7 @@ ThreadPlanStepOut::ThreadPlanStepOut(
135145
136146 // Perform some additional validation on the return address.
137147 uint32_t permissions = 0 ;
148+ Log *log = GetLog (LLDBLog::Step);
138149 if (!m_process.GetLoadAddressPermissions (m_return_addr, permissions)) {
139150 LLDB_LOGF (log, " ThreadPlanStepOut(%p): Return address (0x%" PRIx64
140151 " ) permissions not found." , static_cast <void *>(this ),
0 commit comments