@@ -38,6 +38,32 @@ using namespace lldb_private;
38
38
39
39
uint32_t ThreadPlanStepOut::s_default_flag_values = 0 ;
40
40
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
+
41
67
// ThreadPlanStepOut: Step out of the current frame
42
68
ThreadPlanStepOut::ThreadPlanStepOut (
43
69
Thread &thread, SymbolContext *context, bool first_insn, bool stop_others,
@@ -54,34 +80,18 @@ ThreadPlanStepOut::ThreadPlanStepOut(
54
80
m_stop_others(stop_others), m_immediate_step_from_function(nullptr ),
55
81
m_is_swift_error_value(false ),
56
82
m_calculate_return_value(gather_return_value) {
57
- Log *log = GetLog (LLDBLog::Step);
58
83
SetFlagsToDefault ();
59
84
SetupAvoidNoDebug (step_out_avoids_code_without_debug_info);
60
85
61
86
m_step_from_insn = thread.GetRegisterContext ()->GetPC (0 );
62
87
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 );
65
90
StackFrameSP immediate_return_from_sp (thread.GetStackFrameAtIndex (frame_idx));
66
91
67
92
if (!return_frame_sp || !immediate_return_from_sp)
68
93
return ; // we can't do anything here. ValidatePlan() will return false.
69
94
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
-
85
95
m_step_out_to_id = return_frame_sp->GetStackID ();
86
96
m_immediate_step_from_id = immediate_return_from_sp->GetStackID ();
87
97
@@ -135,6 +145,7 @@ ThreadPlanStepOut::ThreadPlanStepOut(
135
145
136
146
// Perform some additional validation on the return address.
137
147
uint32_t permissions = 0 ;
148
+ Log *log = GetLog (LLDBLog::Step);
138
149
if (!m_process.GetLoadAddressPermissions (m_return_addr, permissions)) {
139
150
LLDB_LOGF (log , " ThreadPlanStepOut(%p): Return address (0x%" PRIx64
140
151
" ) permissions not found." , static_cast <void *>(this ),
0 commit comments