Skip to content

Commit 71b43b7

Browse files
jiminghamkbluck
authored andcommitted
SBThread::StepInstruction shouldn't discard other plans (llvm#97493)
This was just a typo, none of the external execution control functions should discard other plans. In particular, it means if you stop in a hand-called function and step an instruction, the function call thread plan gets unshipped, popping all the function call frames. I also added a test that asserts the correct behavior. I tested all the stepping operations even though only StepInstruction was wrong.
1 parent df2d8ed commit 71b43b7

File tree

3 files changed

+62
-1
lines changed

3 files changed

+62
-1
lines changed

lldb/source/API/SBThread.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -722,7 +722,7 @@ void SBThread::StepInstruction(bool step_over, SBError &error) {
722722
Thread *thread = exe_ctx.GetThreadPtr();
723723
Status new_plan_status;
724724
ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction(
725-
step_over, true, true, new_plan_status));
725+
step_over, false, true, new_plan_status));
726726

727727
if (new_plan_status.Success())
728728
error = ResumeNewPlan(exe_ctx, new_plan_sp.get());

lldb/test/API/python_api/thread/TestThreadAPI.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ def test_negative_indexing(self):
5252
self.build()
5353
self.validate_negative_indexing()
5454

55+
def test_StepInstruction(self):
56+
"""Test that StepInstruction preserves the plan stack."""
57+
self.build()
58+
self.step_instruction_in_called_function()
59+
5560
def setUp(self):
5661
# Call super's setUp().
5762
TestBase.setUp(self)
@@ -303,3 +308,49 @@ def validate_negative_indexing(self):
303308
neg_range = range(thread.num_frames, 0, -1)
304309
for pos, neg in zip(pos_range, neg_range):
305310
self.assertEqual(thread.frame[pos].idx, thread.frame[-neg].idx)
311+
312+
def step_instruction_in_called_function(self):
313+
main_file_spec = lldb.SBFileSpec("main.cpp")
314+
target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
315+
self, "Set break point at this line", main_file_spec
316+
)
317+
options = lldb.SBExpressionOptions()
318+
options.SetIgnoreBreakpoints(False)
319+
320+
call_me_bkpt = target.BreakpointCreateBySourceRegex(
321+
"Set a breakpoint in call_me", main_file_spec
322+
)
323+
self.assertGreater(
324+
call_me_bkpt.GetNumLocations(), 0, "Got at least one location in call_me"
325+
)
326+
# Now run the expression, this will fail because we stopped at a breakpoint:
327+
self.runCmd("expr -i 0 -- call_me(true)", check=False)
328+
# Now we should be stopped in call_me:
329+
self.assertEqual(
330+
thread.frames[0].name, "call_me(bool)", "Stopped in call_me(bool)"
331+
)
332+
# Now do a various API steps. These should not cause the expression context to get unshipped:
333+
thread.StepInstruction(False)
334+
self.assertEqual(
335+
thread.frames[0].name,
336+
"call_me(bool)",
337+
"Still in call_me(bool) after StepInstruction",
338+
)
339+
thread.StepInstruction(True)
340+
self.assertEqual(
341+
thread.frames[0].name,
342+
"call_me(bool)",
343+
"Still in call_me(bool) after NextInstruction",
344+
)
345+
thread.StepInto()
346+
self.assertEqual(
347+
thread.frames[0].name,
348+
"call_me(bool)",
349+
"Still in call_me(bool) after StepInto",
350+
)
351+
thread.StepOver(False)
352+
self.assertEqual(
353+
thread.frames[0].name,
354+
"call_me(bool)",
355+
"Still in call_me(bool) after StepOver",
356+
)

lldb/test/API/python_api/thread/main.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,18 @@
55
char my_char = 'u';
66
int my_int = 0;
77

8+
void
9+
call_me(bool should_spin) {
10+
int counter = 0;
11+
if (should_spin) {
12+
while (1)
13+
counter++; // Set a breakpoint in call_me
14+
}
15+
}
16+
817
int main (int argc, char const *argv[])
918
{
19+
call_me(false);
1020
for (int i = 0; i < 3; ++i) {
1121
printf("my_char='%c'\n", my_char);
1222
++my_char;

0 commit comments

Comments
 (0)