@@ -31,6 +31,32 @@ using namespace lldb_private;
31
31
32
32
uint32_t ThreadPlanStepOut::s_default_flag_values = 0 ;
33
33
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
+
34
60
// ThreadPlanStepOut: Step out of the current frame
35
61
ThreadPlanStepOut::ThreadPlanStepOut (
36
62
Thread &thread, SymbolContext *context, bool first_insn, bool stop_others,
@@ -44,34 +70,18 @@ ThreadPlanStepOut::ThreadPlanStepOut(
44
70
m_return_addr(LLDB_INVALID_ADDRESS), m_stop_others(stop_others),
45
71
m_immediate_step_from_function(nullptr ),
46
72
m_calculate_return_value(gather_return_value) {
47
- Log *log = GetLog (LLDBLog::Step);
48
73
SetFlagsToDefault ();
49
74
SetupAvoidNoDebug (step_out_avoids_code_without_debug_info);
50
75
51
76
m_step_from_insn = thread.GetRegisterContext ()->GetPC (0 );
52
77
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 );
55
80
StackFrameSP immediate_return_from_sp (thread.GetStackFrameAtIndex (frame_idx));
56
81
57
82
if (!return_frame_sp || !immediate_return_from_sp)
58
83
return ; // we can't do anything here. ValidatePlan() will return false.
59
84
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
-
75
85
m_step_out_to_id = return_frame_sp->GetStackID ();
76
86
m_immediate_step_from_id = immediate_return_from_sp->GetStackID ();
77
87
@@ -125,6 +135,7 @@ ThreadPlanStepOut::ThreadPlanStepOut(
125
135
126
136
// Perform some additional validation on the return address.
127
137
uint32_t permissions = 0 ;
138
+ Log *log = GetLog (LLDBLog::Step);
128
139
if (!m_process.GetLoadAddressPermissions (m_return_addr, permissions)) {
129
140
LLDB_LOGF (log , " ThreadPlanStepOut(%p): Return address (0x%" PRIx64
130
141
" ) permissions not found." , static_cast <void *>(this ),
0 commit comments