[Lldb-commits] [lldb] 845dee3 - SBThread::StepInstruction shouldn't discard other plans (#97493)

via lldb-commits lldb-commits at lists.llvm.org
Wed Jul 3 10:45:23 PDT 2024


Author: jimingham
Date: 2024-07-03T10:45:20-07:00
New Revision: 845dee36ba4161df153ba05009cea615e20eda5a

URL: https://github.com/llvm/llvm-project/commit/845dee36ba4161df153ba05009cea615e20eda5a
DIFF: https://github.com/llvm/llvm-project/commit/845dee36ba4161df153ba05009cea615e20eda5a.diff

LOG: 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.

Added: 
    

Modified: 
    lldb/source/API/SBThread.cpp
    lldb/test/API/python_api/thread/TestThreadAPI.py
    lldb/test/API/python_api/thread/main.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/source/API/SBThread.cpp b/lldb/source/API/SBThread.cpp
index ac3e2cd25daa9..53643362421d4 100644
--- a/lldb/source/API/SBThread.cpp
+++ b/lldb/source/API/SBThread.cpp
@@ -722,7 +722,7 @@ void SBThread::StepInstruction(bool step_over, SBError &error) {
   Thread *thread = exe_ctx.GetThreadPtr();
   Status new_plan_status;
   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction(
-      step_over, true, true, new_plan_status));
+      step_over, false, true, new_plan_status));
 
   if (new_plan_status.Success())
     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());

diff  --git a/lldb/test/API/python_api/thread/TestThreadAPI.py b/lldb/test/API/python_api/thread/TestThreadAPI.py
index 0fe91c88c325e..d5fc77532d859 100644
--- a/lldb/test/API/python_api/thread/TestThreadAPI.py
+++ b/lldb/test/API/python_api/thread/TestThreadAPI.py
@@ -52,6 +52,11 @@ def test_negative_indexing(self):
         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 @@ def validate_negative_indexing(self):
         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 dde740a1b6bf6..d4b0ad2372c3d 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;


        


More information about the lldb-commits mailing list