[lldb] Add stop_description Python property to SBThread (#151568)

Add `stop_description` as a Python convenience property to `SBThread`.
This commit is contained in:
Dave Lee 2025-07-31 13:10:04 -07:00 committed by GitHub
parent 2737d013a0
commit 68b9bb5e9b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 31 additions and 29 deletions

View File

@ -45,6 +45,9 @@ STRING_EXTENSION_OUTSIDE(SBThread)
frames.append(frame)
return frames
def get_stop_description(self):
return self.GetStopDescription(1024)
def get_stop_reason_data(self):
return [
self.GetStopReasonDataAtIndex(idx)
@ -69,6 +72,7 @@ STRING_EXTENSION_OUTSIDE(SBThread)
name = property(GetName, None, doc='''A read only property that returns the name of this thread as a string.''')
queue = property(GetQueueName, None, doc='''A read only property that returns the dispatch queue name of this thread as a string.''')
queue_id = property(GetQueueID, None, doc='''A read only property that returns the dispatch queue id of this thread as an integer.''')
stop_description = property(get_stop_description, None, doc='''A read only property that returns a string describing the reason this thread stopped.''')
stop_reason = property(GetStopReason, None, doc='''A read only property that returns an lldb enumeration value (see enumerations that start with "lldb.eStopReason") that represents the reason this thread stopped.''')
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.''')

View File

@ -50,11 +50,11 @@ class TestStepOverWatchpoint(TestBase):
lldb.eStopReasonWatchpoint,
STOPPED_DUE_TO_WATCHPOINT,
)
self.assertEqual(thread.GetStopDescription(20), "watchpoint 1")
self.assertEqual(thread.stop_description, "watchpoint 1")
process.Continue()
self.assertState(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
self.assertEqual(thread.GetStopDescription(20), "step over")
self.assertEqual(thread.stop_description, "step over")
self.step_inst_for_watchpoint(1)
@ -89,11 +89,11 @@ class TestStepOverWatchpoint(TestBase):
lldb.eStopReasonWatchpoint,
STOPPED_DUE_TO_WATCHPOINT,
)
self.assertEqual(thread.GetStopDescription(20), "watchpoint 1")
self.assertEqual(thread.stop_description, "watchpoint 1")
process.Continue()
self.assertState(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
self.assertEqual(thread.GetStopDescription(20), "step over")
self.assertEqual(thread.stop_description, "step over")
self.step_inst_for_watchpoint(1)
@ -106,7 +106,7 @@ class TestStepOverWatchpoint(TestBase):
if stop_reason == lldb.eStopReasonWatchpoint:
self.assertFalse(watchpoint_hit, "Watchpoint already hit.")
expected_stop_desc = "watchpoint %d" % wp_id
actual_stop_desc = self.thread().GetStopDescription(20)
actual_stop_desc = self.thread().stop_description
self.assertEqual(
actual_stop_desc, expected_stop_desc, "Watchpoint ID didn't match."
)

View File

@ -35,7 +35,7 @@ class TestWatchpointCount(TestBase):
self.assertStopReason(
stop_reason, lldb.eStopReasonWatchpoint, "watchpoint for x1 not hit"
)
stop_reason_descr = thread.GetStopDescription(256)
stop_reason_descr = thread.stop_description
self.assertEqual(stop_reason_descr, "watchpoint 1")
process.Continue()
@ -43,5 +43,5 @@ class TestWatchpointCount(TestBase):
self.assertStopReason(
stop_reason, lldb.eStopReasonWatchpoint, "watchpoint for x2 not hit"
)
stop_reason_descr = thread.GetStopDescription(256)
stop_reason_descr = thread.stop_description
self.assertEqual(stop_reason_descr, "watchpoint 2")

View File

@ -594,7 +594,7 @@ class TestGDBRemoteClient(GDBRemoteTestBase):
process = self.connect(target)
self.assertEqual(process.threads[0].GetStopReason(), lldb.eStopReasonSignal)
self.assertEqual(process.threads[0].GetStopDescription(100), "signal SIGBUS")
self.assertEqual(process.threads[0].stop_description, "signal SIGBUS")
def test_signal_lldb_old(self):
class MyResponder(MockGDBServerResponder):
@ -620,7 +620,7 @@ class TestGDBRemoteClient(GDBRemoteTestBase):
process = self.connect(target)
self.assertEqual(process.threads[0].GetStopReason(), lldb.eStopReasonSignal)
self.assertEqual(process.threads[0].GetStopDescription(100), "signal SIGUSR1")
self.assertEqual(process.threads[0].stop_description, "signal SIGUSR1")
def test_signal_lldb(self):
class MyResponder(MockGDBServerResponder):
@ -643,7 +643,7 @@ class TestGDBRemoteClient(GDBRemoteTestBase):
process = self.connect(target)
self.assertEqual(process.threads[0].GetStopReason(), lldb.eStopReasonSignal)
self.assertEqual(process.threads[0].GetStopDescription(100), "signal SIGUSR1")
self.assertEqual(process.threads[0].stop_description, "signal SIGUSR1")
def do_siginfo_test(self, platform, target_yaml, raw_data, expected):
class MyResponder(MockGDBServerResponder):

View File

@ -123,5 +123,5 @@ class TestOSPluginStepping(TestBase):
os_thread = self.get_os_thread()
self.assertTrue(os_thread.IsValid(), "The OS thread is back after continue")
self.assertIn(
"step out", os_thread.GetStopDescription(100), "Completed step out plan"
"step out", os_thread.stop_description, "Completed step out plan"
)

View File

@ -117,7 +117,7 @@ class MiniDumpNewTestCase(TestBase):
self.assertEqual(self.process.GetNumThreads(), 1)
thread = self.process.GetThreadAtIndex(0)
self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonSignal)
stop_description = thread.GetStopDescription(256)
stop_description = thread.stop_description
self.assertIn("SIGSEGV", stop_description)
@skipIfLLVMTargetMissing("X86")
@ -153,7 +153,7 @@ class MiniDumpNewTestCase(TestBase):
self.assertEqual(self.process.GetNumThreads(), 1)
thread = self.process.GetThreadAtIndex(0)
self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonNone)
stop_description = thread.GetStopDescription(256)
stop_description = thread.stop_description
self.assertEqual(stop_description, "")
def test_snapshot_minidump_null_exn_code(self):
@ -164,7 +164,7 @@ class MiniDumpNewTestCase(TestBase):
self.assertEqual(self.process.GetNumThreads(), 1)
thread = self.process.GetThreadAtIndex(0)
self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonNone)
stop_description = thread.GetStopDescription(256)
stop_description = thread.stop_description
self.assertEqual(stop_description, "")
def check_register_unsigned(self, set, name, expected):
@ -198,7 +198,7 @@ class MiniDumpNewTestCase(TestBase):
self.assertEqual(self.process.GetNumThreads(), 1)
thread = self.process.GetThreadAtIndex(0)
self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonNone)
stop_description = thread.GetStopDescription(256)
stop_description = thread.stop_description
self.assertEqual(stop_description, "")
registers = thread.GetFrameAtIndex(0).GetRegisters()
# Verify the GPR registers are all correct
@ -261,7 +261,7 @@ class MiniDumpNewTestCase(TestBase):
self.assertEqual(self.process.GetNumThreads(), 1)
thread = self.process.GetThreadAtIndex(0)
self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonNone)
stop_description = thread.GetStopDescription(256)
stop_description = thread.stop_description
self.assertEqual(stop_description, "")
registers = thread.GetFrameAtIndex(0).GetRegisters()
# Verify the GPR registers are all correct
@ -522,7 +522,7 @@ class MiniDumpNewTestCase(TestBase):
for i in range(2):
thread = self.process.GetThreadAtIndex(i)
self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonSignal)
stop_description = thread.GetStopDescription(256)
stop_description = thread.stop_description
self.assertIn("SIGSEGV", stop_description)
def test_breakpoint_on_minidump(self):
@ -539,7 +539,7 @@ class MiniDumpNewTestCase(TestBase):
process = target.LoadCore(core)
self.assertTrue(process, VALID_PROCESS)
thread = process.GetThreadAtIndex(0)
stop_reason = thread.GetStopDescription(256)
stop_reason = thread.stop_description
self.assertIn("breakpoint 1.1", stop_reason)
finally:
if os.path.isfile(core):

View File

@ -32,7 +32,7 @@ class MiniDumpTestCase(TestBase):
self.assertEqual(self.process.GetNumThreads(), 1)
thread = self.process.GetThreadAtIndex(0)
self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonException)
stop_description = thread.GetStopDescription(256)
stop_description = thread.stop_description
self.assertIn("0xc0000005", stop_description)
def test_modules_in_mini_dump(self):

View File

@ -204,9 +204,7 @@ class StackCoreScriptedThread(ScriptedThread):
if self.is_stopped:
if "arm64" in self.scripted_process.arch:
stop_reason["type"] = lldb.eStopReasonException
stop_reason["data"][
"desc"
] = self.corefile_thread.GetStopDescription(100)
stop_reason["data"]["desc"] = self.corefile_thread.stop_description
elif self.scripted_process.arch == "x86_64":
stop_reason["type"] = lldb.eStopReasonSignal
stop_reason["data"]["signal"] = signal.SIGTRAP

View File

@ -41,7 +41,7 @@ class StepScriptedTestCase(TestBase):
frame = thread.GetFrameAtIndex(0)
self.assertEqual("main", frame.GetFunctionName())
stop_desc = thread.GetStopDescription(1000)
stop_desc = thread.stop_description
self.assertIn("Stepping out from", stop_desc, "Got right description")
def run_until_branch_instruction(self):
@ -153,7 +153,7 @@ class StepScriptedTestCase(TestBase):
self.assertTrue(foo_val.GetValueDidChange(), "Foo changed")
# And we should have a reasonable stop description:
desc = thread.GetStopDescription(1000)
desc = thread.stop_description
self.assertIn("Stepped until foo changed", desc, "Got right stop description")
def test_stop_others_from_command(self):

View File

@ -49,7 +49,7 @@ class TsanMultipleTestCase(TestBase):
stop_description = (
self.dbg.GetSelectedTarget()
.process.GetSelectedThread()
.GetStopDescription(100)
.stop_description
)
self.assertTrue(

View File

@ -61,7 +61,7 @@ class TestAbortWithPayload(TestBase):
self.assertEqual(thread, sel_thread, "Selected the original thread")
# Make sure the stop reason is right:
self.assertEqual(
thread.GetStopDescription(100),
thread.stop_description,
"abort with payload or reason",
"Description was right",
)

View File

@ -44,7 +44,7 @@ class TestCorefileExceptionReason(TestBase):
self.runCmd("fr v")
self.assertEqual(
thread.GetStopDescription(256), "ESR_EC_DABORT_EL0 (fault address: 0x0)"
thread.stop_description, "ESR_EC_DABORT_EL0 (fault address: 0x0)"
)
if self.TraceOn():

View File

@ -17,7 +17,7 @@ class TestBreakpointIllegal(TestBase):
)
self.runCmd("thread step-inst")
# we need to step more, as some compilers do not set appropriate debug info.
while cur_thread.GetStopDescription(256) == "instruction step into":
while cur_thread.stop_description == "instruction step into":
self.runCmd("thread step-inst")
# The stop reason of the thread should be illegal opcode.
self.expect(
@ -34,7 +34,7 @@ class TestBreakpointIllegal(TestBase):
)
self.runCmd("thread step-inst")
# we need to step more, as some compilers do not set appropriate debug info.
while cur_thread.GetStopDescription(256) == "instruction step into":
while cur_thread.stop_description == "instruction step into":
self.runCmd("thread step-inst")
# The stop reason of the thread should be illegal opcode.
self.expect(