Skip to content

Commit 7293455

Browse files
authored
[lldb] Add SBThread.selected_frame property (llvm#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.
1 parent 12f82fb commit 7293455

File tree

5 files changed

+21
-20
lines changed

5 files changed

+21
-20
lines changed

lldb/bindings/interface/SBThreadExtensions.i

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,14 @@ STRING_EXTENSION_OUTSIDE(SBThread)
5151
for idx in range(self.GetStopReasonDataCount())
5252
]
5353

54+
def set_selected_frame(self, frame):
55+
if isinstance(frame, SBFrame):
56+
if frame.thread != self:
57+
raise ValueError("cannot select frame from different thread")
58+
self.SetSelectedFrame(frame.idx)
59+
else:
60+
self.SetSelectedFrame(frame)
61+
5462
id = property(GetThreadID, None, doc='''A read only property that returns the thread ID as an integer.''')
5563
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.''')
5664
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)
6573
stop_reason_data = property(get_stop_reason_data, None, doc='''A read only property that returns the stop reason data as a list.''')
6674
is_suspended = property(IsSuspended, None, doc='''A read only property that returns a boolean value that indicates if this thread is suspended.''')
6775
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.''')
76+
selected_frame = property(GetSelectedFrame, set_selected_frame, doc='''A read/write property that gets and sets the selected frame of this SBThread.''')
6877
%}
6978
#endif
7079
}

lldb/test/API/commands/frame/recognizer/TestFrameRecognizer.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def test_frame_recognizer_1(self):
2020
target, process, thread, _ = lldbutil.run_to_name_breakpoint(
2121
self, "foo", exe_name=exe
2222
)
23-
frame = thread.GetSelectedFrame()
23+
frame = thread.selected_frame
2424

2525
# Clear internal & plugins recognizers that get initialized at launch
2626
self.runCmd("frame recognizer clear")
@@ -166,7 +166,7 @@ def test_frame_recognizer_hiding(self):
166166
self.build()
167167

168168
target, process, thread, _ = lldbutil.run_to_name_breakpoint(self, "nested")
169-
frame = thread.GetSelectedFrame()
169+
frame = thread.selected_frame
170170

171171
# Sanity check.
172172
self.expect(
@@ -229,7 +229,6 @@ def test_frame_recognizer_multi_symbol(self):
229229
target, process, thread, _ = lldbutil.run_to_name_breakpoint(
230230
self, "foo", exe_name=exe
231231
)
232-
frame = thread.GetSelectedFrame()
233232

234233
self.expect(
235234
"frame recognizer info 0",
@@ -239,7 +238,6 @@ def test_frame_recognizer_multi_symbol(self):
239238
target, process, thread, _ = lldbutil.run_to_name_breakpoint(
240239
self, "bar", exe_name=exe
241240
)
242-
frame = thread.GetSelectedFrame()
243241

244242
self.expect(
245243
"frame recognizer info 0",
@@ -374,7 +372,7 @@ def test_frame_recognizer_not_only_first_instruction(self):
374372

375373
opts = lldb.SBVariablesOptions()
376374
opts.SetIncludeRecognizedArguments(True)
377-
frame = thread.GetSelectedFrame()
375+
frame = thread.selected_frame
378376
variables = frame.GetVariables(opts)
379377

380378
self.assertEqual(variables.GetSize(), 2)

lldb/test/API/functionalities/location-list-lookup/TestLocationListLookup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ def check_local_vars(self, process: lldb.SBProcess, check_expr: bool):
2525
# Find `bar` on the stack, then
2626
# make sure we can read out the local
2727
# variables (with both `frame var` and `expr`)
28-
for f in process.GetSelectedThread().frames:
28+
for f in process.selected_thread.frames:
2929
frame_name = f.GetDisplayFunctionName()
3030
if frame_name is not None and frame_name.startswith("Foo::bar"):
3131
argv = f.GetValueForVariablePath("argv").GetChildAtIndex(0)
@@ -34,7 +34,7 @@ def check_local_vars(self, process: lldb.SBProcess, check_expr: bool):
3434
self.assertNotEqual(strm.GetData().find("a.out"), -1)
3535

3636
if check_expr:
37-
process.GetSelectedThread().SetSelectedFrame(f.idx)
37+
process.selected_thread.selected_frame = f
3838
self.expect_expr("this", result_type="Foo *")
3939

4040
@skipIf(oslist=["linux"], archs=["arm"])

lldb/test/API/lang/cpp/std-function-recognizer/TestStdFunctionRecognizer.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,14 @@ def test_up_down(self):
6969
(target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
7070
self, "// break here", lldb.SBFileSpec("main.cpp")
7171
)
72-
frame = thread.GetSelectedFrame()
72+
frame = thread.selected_frame
7373
# up
7474
self.assertIn("foo", frame.GetFunctionName())
7575
start_idx = frame.GetFrameID()
7676
i = 0
7777
while i < thread.GetNumFrames():
7878
self.expect("up")
79-
frame = thread.GetSelectedFrame()
79+
frame = thread.selected_frame
8080
if frame.GetFunctionName() == "main":
8181
break
8282
end_idx = frame.GetFrameID()
@@ -86,7 +86,7 @@ def test_up_down(self):
8686
start_idx = frame.GetFrameID()
8787
for i in range(1, thread.GetNumFrames()):
8888
self.expect("down")
89-
frame = thread.GetSelectedFrame()
89+
frame = thread.selected_frame
9090
if "foo" in frame.GetFunctionName():
9191
break
9292
end_idx = frame.GetFrameID()
@@ -99,11 +99,8 @@ def test_api(self):
9999
(target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
100100
self, "// break here", lldb.SBFileSpec("main.cpp")
101101
)
102-
frame = thread.GetSelectedFrame()
103102
num_hidden = 0
104-
for i in range(1, thread.GetNumFrames()):
105-
thread.SetSelectedFrame(i)
106-
frame = thread.GetSelectedFrame()
103+
for frame in thread.frames:
107104
if frame.IsHidden():
108105
num_hidden += 1
109106

lldb/test/API/lang/objc/print-obj/TestPrintObj.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,9 @@ def test_print_obj(self):
6969
# We want to traverse the frame to the one corresponding to blocked.m to
7070
# issue our 'po lock_me' command.
7171

72-
depth = other_thread.GetNumFrames()
73-
for i in range(depth):
74-
frame = other_thread.GetFrameAtIndex(i)
75-
name = frame.GetFunctionName()
76-
if name == "main":
77-
other_thread.SetSelectedFrame(i)
72+
for frame in other_thread.frames:
73+
if frame.name == "main":
74+
other_thread.selected_frame = frame
7875
if self.TraceOn():
7976
print("selected frame:" + lldbutil.get_description(frame))
8077
break

0 commit comments

Comments
 (0)