[Lldb-commits] [lldb] 7293455 - [lldb] Add SBThread.selected_frame property (#123981)

via lldb-commits lldb-commits at lists.llvm.org
Fri Jan 24 10:02:18 PST 2025


Author: Dave Lee
Date: 2025-01-24T10:02:15-08:00
New Revision: 7293455cf292cfaa263ea04fc1bc2aee4ceab6a6

URL: https://github.com/llvm/llvm-project/commit/7293455cf292cfaa263ea04fc1bc2aee4ceab6a6
DIFF: https://github.com/llvm/llvm-project/commit/7293455cf292cfaa263ea04fc1bc2aee4ceab6a6.diff

LOG: [lldb] Add SBThread.selected_frame property (#123981)

Adds a `selected_frame` property to `SBThread`. The setter accepts either a frame index (like `SetSelectedFrame`), or a frame object.

Updates a few tests to make use of the new `selected_frame`. While doing so I noticed some of the usage could be cleaned up, so I did that too.

Added: 
    

Modified: 
    lldb/bindings/interface/SBThreadExtensions.i
    lldb/test/API/commands/frame/recognizer/TestFrameRecognizer.py
    lldb/test/API/functionalities/location-list-lookup/TestLocationListLookup.py
    lldb/test/API/lang/cpp/std-function-recognizer/TestStdFunctionRecognizer.py
    lldb/test/API/lang/objc/print-obj/TestPrintObj.py

Removed: 
    


################################################################################
diff  --git a/lldb/bindings/interface/SBThreadExtensions.i b/lldb/bindings/interface/SBThreadExtensions.i
index 860a2d765a6695..267faad9d651fb 100644
--- a/lldb/bindings/interface/SBThreadExtensions.i
+++ b/lldb/bindings/interface/SBThreadExtensions.i
@@ -51,6 +51,14 @@ STRING_EXTENSION_OUTSIDE(SBThread)
                 for idx in range(self.GetStopReasonDataCount())
             ]
 
+        def set_selected_frame(self, frame):
+            if isinstance(frame, SBFrame):
+                if frame.thread != self:
+                    raise ValueError("cannot select frame from 
diff erent thread")
+                self.SetSelectedFrame(frame.idx)
+            else:
+                self.SetSelectedFrame(frame)
+
         id = property(GetThreadID, None, doc='''A read only property that returns the thread ID as an integer.''')
         idx = property(GetIndexID, None, doc='''A read only property that returns the thread index ID as an integer. Thread index ID values start at 1 and increment as threads come and go and can be used to uniquely identify threads.''')
         return_value = property(GetStopReturnValue, None, doc='''A read only property that returns an lldb object that represents the return value from the last stop (lldb.SBValue) if we just stopped due to stepping out of a function.''')
@@ -65,6 +73,7 @@ STRING_EXTENSION_OUTSIDE(SBThread)
         stop_reason_data = property(get_stop_reason_data, None, doc='''A read only property that returns the stop reason data as a list.''')
         is_suspended = property(IsSuspended, None, doc='''A read only property that returns a boolean value that indicates if this thread is suspended.''')
         is_stopped = property(IsStopped, None, doc='''A read only property that returns a boolean value that indicates if this thread is stopped but not exited.''')
+        selected_frame = property(GetSelectedFrame, set_selected_frame, doc='''A read/write property that gets and sets the selected frame of this SBThread.''')
     %}
 #endif
 }

diff  --git a/lldb/test/API/commands/frame/recognizer/TestFrameRecognizer.py b/lldb/test/API/commands/frame/recognizer/TestFrameRecognizer.py
index aa2a448087431e..3e9dbfe6d85552 100644
--- a/lldb/test/API/commands/frame/recognizer/TestFrameRecognizer.py
+++ b/lldb/test/API/commands/frame/recognizer/TestFrameRecognizer.py
@@ -20,7 +20,7 @@ def test_frame_recognizer_1(self):
         target, process, thread, _ = lldbutil.run_to_name_breakpoint(
             self, "foo", exe_name=exe
         )
-        frame = thread.GetSelectedFrame()
+        frame = thread.selected_frame
 
         # Clear internal & plugins recognizers that get initialized at launch
         self.runCmd("frame recognizer clear")
@@ -166,7 +166,7 @@ def test_frame_recognizer_hiding(self):
         self.build()
 
         target, process, thread, _ = lldbutil.run_to_name_breakpoint(self, "nested")
-        frame = thread.GetSelectedFrame()
+        frame = thread.selected_frame
 
         # Sanity check.
         self.expect(
@@ -229,7 +229,6 @@ def test_frame_recognizer_multi_symbol(self):
         target, process, thread, _ = lldbutil.run_to_name_breakpoint(
             self, "foo", exe_name=exe
         )
-        frame = thread.GetSelectedFrame()
 
         self.expect(
             "frame recognizer info 0",
@@ -239,7 +238,6 @@ def test_frame_recognizer_multi_symbol(self):
         target, process, thread, _ = lldbutil.run_to_name_breakpoint(
             self, "bar", exe_name=exe
         )
-        frame = thread.GetSelectedFrame()
 
         self.expect(
             "frame recognizer info 0",
@@ -374,7 +372,7 @@ def test_frame_recognizer_not_only_first_instruction(self):
 
         opts = lldb.SBVariablesOptions()
         opts.SetIncludeRecognizedArguments(True)
-        frame = thread.GetSelectedFrame()
+        frame = thread.selected_frame
         variables = frame.GetVariables(opts)
 
         self.assertEqual(variables.GetSize(), 2)

diff  --git a/lldb/test/API/functionalities/location-list-lookup/TestLocationListLookup.py b/lldb/test/API/functionalities/location-list-lookup/TestLocationListLookup.py
index 84033daff77308..a97f4fc5e3d799 100644
--- a/lldb/test/API/functionalities/location-list-lookup/TestLocationListLookup.py
+++ b/lldb/test/API/functionalities/location-list-lookup/TestLocationListLookup.py
@@ -25,7 +25,7 @@ def check_local_vars(self, process: lldb.SBProcess, check_expr: bool):
         # Find `bar` on the stack, then
         # make sure we can read out the local
         # variables (with both `frame var` and `expr`)
-        for f in process.GetSelectedThread().frames:
+        for f in process.selected_thread.frames:
             frame_name = f.GetDisplayFunctionName()
             if frame_name is not None and frame_name.startswith("Foo::bar"):
                 argv = f.GetValueForVariablePath("argv").GetChildAtIndex(0)
@@ -34,7 +34,7 @@ def check_local_vars(self, process: lldb.SBProcess, check_expr: bool):
                 self.assertNotEqual(strm.GetData().find("a.out"), -1)
 
                 if check_expr:
-                    process.GetSelectedThread().SetSelectedFrame(f.idx)
+                    process.selected_thread.selected_frame = f
                     self.expect_expr("this", result_type="Foo *")
 
     @skipIf(oslist=["linux"], archs=["arm"])

diff  --git a/lldb/test/API/lang/cpp/std-function-recognizer/TestStdFunctionRecognizer.py b/lldb/test/API/lang/cpp/std-function-recognizer/TestStdFunctionRecognizer.py
index 978bf2066e43b0..f5d0ea41e3114c 100644
--- a/lldb/test/API/lang/cpp/std-function-recognizer/TestStdFunctionRecognizer.py
+++ b/lldb/test/API/lang/cpp/std-function-recognizer/TestStdFunctionRecognizer.py
@@ -69,14 +69,14 @@ def test_up_down(self):
         (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
             self, "// break here", lldb.SBFileSpec("main.cpp")
         )
-        frame = thread.GetSelectedFrame()
+        frame = thread.selected_frame
         # up
         self.assertIn("foo", frame.GetFunctionName())
         start_idx = frame.GetFrameID()
         i = 0
         while i < thread.GetNumFrames():
             self.expect("up")
-            frame = thread.GetSelectedFrame()
+            frame = thread.selected_frame
             if frame.GetFunctionName() == "main":
                 break
         end_idx = frame.GetFrameID()
@@ -86,7 +86,7 @@ def test_up_down(self):
         start_idx = frame.GetFrameID()
         for i in range(1, thread.GetNumFrames()):
             self.expect("down")
-            frame = thread.GetSelectedFrame()
+            frame = thread.selected_frame
             if "foo" in frame.GetFunctionName():
                 break
         end_idx = frame.GetFrameID()
@@ -99,11 +99,8 @@ def test_api(self):
         (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
             self, "// break here", lldb.SBFileSpec("main.cpp")
         )
-        frame = thread.GetSelectedFrame()
         num_hidden = 0
-        for i in range(1, thread.GetNumFrames()):
-            thread.SetSelectedFrame(i)
-            frame = thread.GetSelectedFrame()
+        for frame in thread.frames:
             if frame.IsHidden():
                 num_hidden += 1
 

diff  --git a/lldb/test/API/lang/objc/print-obj/TestPrintObj.py b/lldb/test/API/lang/objc/print-obj/TestPrintObj.py
index 60fc4fbc51cee1..3ad4a09b532063 100644
--- a/lldb/test/API/lang/objc/print-obj/TestPrintObj.py
+++ b/lldb/test/API/lang/objc/print-obj/TestPrintObj.py
@@ -69,12 +69,9 @@ def test_print_obj(self):
         # We want to traverse the frame to the one corresponding to blocked.m to
         # issue our 'po lock_me' command.
 
-        depth = other_thread.GetNumFrames()
-        for i in range(depth):
-            frame = other_thread.GetFrameAtIndex(i)
-            name = frame.GetFunctionName()
-            if name == "main":
-                other_thread.SetSelectedFrame(i)
+        for frame in other_thread.frames:
+            if frame.name == "main":
+                other_thread.selected_frame = frame
                 if self.TraceOn():
                     print("selected frame:" + lldbutil.get_description(frame))
                 break


        


More information about the lldb-commits mailing list