Skip to content

Commit 11b9466

Browse files
[lldb] Add ability to inspect backing threads with thread info (#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.
1 parent 45d0180 commit 11b9466

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
@@ -1270,6 +1270,7 @@ class CommandObjectThreadInfo : public CommandObjectIterateOverThreads {
12701270
void OptionParsingStarting(ExecutionContext *execution_context) override {
12711271
m_json_thread = false;
12721272
m_json_stopinfo = false;
1273+
m_backing_thread = false;
12731274
}
12741275

12751276
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
@@ -1286,6 +1287,10 @@ class CommandObjectThreadInfo : public CommandObjectIterateOverThreads {
12861287
m_json_stopinfo = true;
12871288
break;
12881289

1290+
case 'b':
1291+
m_backing_thread = true;
1292+
break;
1293+
12891294
default:
12901295
llvm_unreachable("Unimplemented option");
12911296
}
@@ -1298,6 +1303,7 @@ class CommandObjectThreadInfo : public CommandObjectIterateOverThreads {
12981303

12991304
bool m_json_thread;
13001305
bool m_json_stopinfo;
1306+
bool m_backing_thread;
13011307
};
13021308

13031309
CommandObjectThreadInfo(CommandInterpreter &interpreter)
@@ -1334,6 +1340,8 @@ class CommandObjectThreadInfo : public CommandObjectIterateOverThreads {
13341340
}
13351341

13361342
Thread *thread = thread_sp.get();
1343+
if (m_options.m_backing_thread && thread->GetBackingThread())
1344+
thread = thread->GetBackingThread().get();
13371345

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

lldb/source/Commands/Options.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,6 +1108,9 @@ let Command = "thread info" in {
11081108
" JSON format.">;
11091109
def thread_info_stop_info : Option<"stop-info", "s">, Desc<"Display the "
11101110
"extended stop info in JSON format.">;
1111+
def thread_info_backing_thread : Option<"backing-thread", "b">,
1112+
Desc<"If this is an OS plugin thread, query the backing thread instead; has"
1113+
" no effect otherwise.">;
11111114
}
11121115

11131116
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)