Skip to content

Commit 64ed390

Browse files
authored
[lldb] Fix stepping out if the return address is not allowed to stop at (#161982)
When a thread reaches a breakpoint at the return address set by `ThreadPlanStepOut`, `ThreadPlanStepOut::ShouldStop()` calls `ThreadPlanShouldStopHere::InvokeShouldStopHereCallback()`, and if it returns `false`, `ThreadPlanShouldStopHere::QueueStepOutFromHerePlan()` is called to queue a new plan to skip the corresponding range. Once the new plan finishes, `ThreadPlanStepOut::ShouldStop()` should recheck the stop condition; however, there is no code path in the method that sets `done` to `true`. Before #126838, if `done` was `false`, the method checked if a suitable frame had been reached. After the patch, the check is only performed at a breakpoint; thus, the execution continues. This patch causes `ThreadPlanStepOut::ShouldStop()` to recheck the stop condition when `m_step_out_further_plan_sp` completes.
1 parent 2ff3db0 commit 64ed390

File tree

4 files changed

+52
-2
lines changed

4 files changed

+52
-2
lines changed

lldb/source/Target/ThreadPlanStepOut.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -397,9 +397,10 @@ bool ThreadPlanStepOut::ShouldStop(Event *event_ptr) {
397397
else
398398
return m_step_through_inline_plan_sp->ShouldStop(event_ptr);
399399
} else if (m_step_out_further_plan_sp) {
400-
if (m_step_out_further_plan_sp->MischiefManaged())
400+
if (m_step_out_further_plan_sp->MischiefManaged()) {
401401
m_step_out_further_plan_sp.reset();
402-
else
402+
done = true;
403+
} else
403404
return m_step_out_further_plan_sp->ShouldStop(event_ptr);
404405
}
405406

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
C_SOURCES := main.c
2+
3+
include Makefile.rules
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
"""
2+
Test stepping out of a function when the return location is an unsuitable
3+
stopping point.
4+
"""
5+
6+
7+
import lldb
8+
from lldbsuite.test.decorators import *
9+
from lldbsuite.test.lldbtest import *
10+
from lldbsuite.test import lldbutil
11+
12+
13+
class ThreadStepOutLine0TestCase(TestBase):
14+
def test(self):
15+
self.build()
16+
target, process, thread, _ = lldbutil.run_to_source_breakpoint(
17+
self, "// Set breakpoint here", lldb.SBFileSpec("main.c")
18+
)
19+
correct_stepped_out_line = line_number("main.c", "// Should stop here")
20+
return_statement_line = line_number("main.c", "// Ran too far")
21+
safety_bp = target.BreakpointCreateByLocation(
22+
lldb.SBFileSpec("main.c"), return_statement_line
23+
)
24+
self.assertTrue(safety_bp.IsValid())
25+
26+
error = lldb.SBError()
27+
thread.StepOut(error)
28+
self.assertTrue(error.Success())
29+
30+
frame = thread.GetSelectedFrame()
31+
self.assertEqual(
32+
frame.line_entry.GetLine(),
33+
correct_stepped_out_line,
34+
"Step-out lost control of execution, ran too far",
35+
)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
int step_out_of_here(int a) {
2+
return a + 5; // Set breakpoint here
3+
}
4+
5+
int main() {
6+
#line 0
7+
int v = step_out_of_here(3) + 7;
8+
#line 9
9+
v += 11; // Should stop here
10+
return v; // Ran too far
11+
}

0 commit comments

Comments
 (0)