Skip to content

Commit 0048ac1

Browse files
[lldb] Add ability to inspect backing threads with thread info (llvm#129275)
When OS plugins are present, it can be helpful to query information about the backing thread behind an OS thread, if it exists. There is no mechanism to do so prior to this commit. As a first step, this commit enhances `thread info` with a `--backing-thread` flag, causing the command to use the backing thread of the selected thread, if it exists. (cherry picked from commit 11b9466)
1 parent 541d218 commit 0048ac1

File tree

3 files changed

+36
-0
lines changed

3 files changed

+36
-0
lines changed

lldb/source/Commands/CommandObjectThread.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1283,6 +1283,7 @@ class CommandObjectThreadInfo : public CommandObjectIterateOverThreads {
12831283
void OptionParsingStarting(ExecutionContext *execution_context) override {
12841284
m_json_thread = false;
12851285
m_json_stopinfo = false;
1286+
m_backing_thread = false;
12861287
}
12871288

12881289
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
@@ -1299,6 +1300,10 @@ class CommandObjectThreadInfo : public CommandObjectIterateOverThreads {
12991300
m_json_stopinfo = true;
13001301
break;
13011302

1303+
case 'b':
1304+
m_backing_thread = true;
1305+
break;
1306+
13021307
default:
13031308
llvm_unreachable("Unimplemented option");
13041309
}
@@ -1311,6 +1316,7 @@ class CommandObjectThreadInfo : public CommandObjectIterateOverThreads {
13111316

13121317
bool m_json_thread;
13131318
bool m_json_stopinfo;
1319+
bool m_backing_thread;
13141320
};
13151321

13161322
CommandObjectThreadInfo(CommandInterpreter &interpreter)
@@ -1347,6 +1353,8 @@ class CommandObjectThreadInfo : public CommandObjectIterateOverThreads {
13471353
}
13481354

13491355
Thread *thread = thread_sp.get();
1356+
if (m_options.m_backing_thread && thread->GetBackingThread())
1357+
thread = thread->GetBackingThread().get();
13501358

13511359
Stream &strm = result.GetOutputStream();
13521360
if (!thread->GetDescription(strm, eDescriptionLevelFull,

lldb/source/Commands/Options.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1115,6 +1115,9 @@ let Command = "thread info" in {
11151115
" JSON format.">;
11161116
def thread_info_stop_info : Option<"stop-info", "s">, Desc<"Display the "
11171117
"extended stop info in JSON format.">;
1118+
def thread_info_backing_thread : Option<"backing-thread", "b">,
1119+
Desc<"If this is an OS plugin thread, query the backing thread instead; has"
1120+
" no effect otherwise.">;
11181121
}
11191122

11201123
let Command = "thread return" in {

lldb/test/API/functionalities/plugins/python_os_plugin/TestPythonOSPlugin.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,26 @@ def run_python_os_funcionality(self):
131131
"Make sure there is no thread 0x333333333 after we unload the python OS plug-in",
132132
)
133133

134+
tid_regex = re.compile(r"tid = ((0x)?[0-9a-fA-F]+)")
135+
136+
def get_tid_from_thread_info_command(self, thread, use_backing_thread):
137+
interp = self.dbg.GetCommandInterpreter()
138+
result = lldb.SBCommandReturnObject()
139+
140+
backing_thread_arg = ""
141+
if use_backing_thread:
142+
backing_thread_arg = "--backing-thread"
143+
144+
interp.HandleCommand(
145+
"thread info {0} {1}".format(thread.GetIndexID(), backing_thread_arg),
146+
result,
147+
True,
148+
)
149+
self.assertTrue(result.Succeeded(), "failed to run thread info")
150+
match = self.tid_regex.search(result.GetOutput())
151+
self.assertNotEqual(match, None)
152+
return int(match.group(1), 0)
153+
134154
def run_python_os_step(self):
135155
"""Test that the Python operating system plugin works correctly and allows single stepping of a virtual thread that is backed by a real thread"""
136156

@@ -209,6 +229,11 @@ def run_python_os_step(self):
209229
# it to
210230
thread.StepOver()
211231

232+
tid_os = self.get_tid_from_thread_info_command(thread, False)
233+
self.assertEqual(tid_os, 0x111111111)
234+
tid_real = self.get_tid_from_thread_info_command(thread, True)
235+
self.assertNotEqual(tid_os, tid_real)
236+
212237
frame = thread.GetFrameAtIndex(0)
213238
self.assertTrue(
214239
frame.IsValid(), "Make sure we get a frame from thread 0x111111111"

0 commit comments

Comments
 (0)