diff options
| author | jimingham <jingham@apple.com> | 2024-07-03 10:45:20 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-07-03 10:45:20 -0700 |
| commit | 845dee36ba4161df153ba05009cea615e20eda5a (patch) | |
| tree | d222daf105b1ddb3196be682a786ef3be6da716e /lldb/test/API/python_api | |
| parent | 77d131eddb6ca9060c844fae9cb78779fa70c8f0 (diff) | |
| download | llvm-845dee36ba4161df153ba05009cea615e20eda5a.zip llvm-845dee36ba4161df153ba05009cea615e20eda5a.tar.gz llvm-845dee36ba4161df153ba05009cea615e20eda5a.tar.bz2 | |
SBThread::StepInstruction shouldn't discard other plans (#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.
Diffstat (limited to 'lldb/test/API/python_api')
| -rw-r--r-- | lldb/test/API/python_api/thread/TestThreadAPI.py | 51 | ||||
| -rw-r--r-- | lldb/test/API/python_api/thread/main.cpp | 10 |
2 files changed, 61 insertions, 0 deletions
diff --git a/lldb/test/API/python_api/thread/TestThreadAPI.py b/lldb/test/API/python_api/thread/TestThreadAPI.py index 0fe91c8..d5fc775 100644 --- a/lldb/test/API/python_api/thread/TestThreadAPI.py +++ b/lldb/test/API/python_api/thread/TestThreadAPI.py @@ -52,6 +52,11 @@ class ThreadAPITestCase(TestBase): self.build() self.validate_negative_indexing() + def test_StepInstruction(self): + """Test that StepInstruction preserves the plan stack.""" + self.build() + self.step_instruction_in_called_function() + def setUp(self): # Call super's setUp(). TestBase.setUp(self) @@ -303,3 +308,49 @@ class ThreadAPITestCase(TestBase): neg_range = range(thread.num_frames, 0, -1) for pos, neg in zip(pos_range, neg_range): self.assertEqual(thread.frame[pos].idx, thread.frame[-neg].idx) + + def step_instruction_in_called_function(self): + main_file_spec = lldb.SBFileSpec("main.cpp") + target, process, thread, bkpt = lldbutil.run_to_source_breakpoint( + self, "Set break point at this line", main_file_spec + ) + options = lldb.SBExpressionOptions() + options.SetIgnoreBreakpoints(False) + + call_me_bkpt = target.BreakpointCreateBySourceRegex( + "Set a breakpoint in call_me", main_file_spec + ) + self.assertGreater( + call_me_bkpt.GetNumLocations(), 0, "Got at least one location in call_me" + ) + # Now run the expression, this will fail because we stopped at a breakpoint: + self.runCmd("expr -i 0 -- call_me(true)", check=False) + # Now we should be stopped in call_me: + self.assertEqual( + thread.frames[0].name, "call_me(bool)", "Stopped in call_me(bool)" + ) + # Now do a various API steps. These should not cause the expression context to get unshipped: + thread.StepInstruction(False) + self.assertEqual( + thread.frames[0].name, + "call_me(bool)", + "Still in call_me(bool) after StepInstruction", + ) + thread.StepInstruction(True) + self.assertEqual( + thread.frames[0].name, + "call_me(bool)", + "Still in call_me(bool) after NextInstruction", + ) + thread.StepInto() + self.assertEqual( + thread.frames[0].name, + "call_me(bool)", + "Still in call_me(bool) after StepInto", + ) + thread.StepOver(False) + self.assertEqual( + thread.frames[0].name, + "call_me(bool)", + "Still in call_me(bool) after StepOver", + ) diff --git a/lldb/test/API/python_api/thread/main.cpp b/lldb/test/API/python_api/thread/main.cpp index dde740a..d4b0ad2 100644 --- a/lldb/test/API/python_api/thread/main.cpp +++ b/lldb/test/API/python_api/thread/main.cpp @@ -5,8 +5,18 @@ char my_char = 'u'; int my_int = 0; +void +call_me(bool should_spin) { + int counter = 0; + if (should_spin) { + while (1) + counter++; // Set a breakpoint in call_me + } +} + int main (int argc, char const *argv[]) { + call_me(false); for (int i = 0; i < 3; ++i) { printf("my_char='%c'\n", my_char); ++my_char; |
