Skip to content

Commit 97a6e23

Browse files
committed
Add option to pass thread ID to thread select command
1 parent e1f911e commit 97a6e23

File tree

3 files changed

+78
-9
lines changed

3 files changed

+78
-9
lines changed

lldb/source/Commands/CommandObjectThread.cpp

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1129,8 +1129,44 @@ class CommandObjectThreadUntil : public CommandObjectParsed {
11291129

11301130
// CommandObjectThreadSelect
11311131

1132+
#define LLDB_OPTIONS_thread_select
1133+
#include "CommandOptions.inc"
1134+
11321135
class CommandObjectThreadSelect : public CommandObjectParsed {
11331136
public:
1137+
class CommandOptions : public Options {
1138+
public:
1139+
CommandOptions() { OptionParsingStarting(nullptr); }
1140+
1141+
~CommandOptions() override = default;
1142+
1143+
void OptionParsingStarting(ExecutionContext *execution_context) override {
1144+
m_thread_id = false;
1145+
}
1146+
1147+
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1148+
ExecutionContext *execution_context) override {
1149+
const int short_option = m_getopt_table[option_idx].val;
1150+
switch (short_option) {
1151+
case 't': {
1152+
m_thread_id = true;
1153+
break;
1154+
}
1155+
1156+
default:
1157+
llvm_unreachable("Unimplemented option");
1158+
}
1159+
1160+
return {};
1161+
}
1162+
1163+
llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1164+
return llvm::ArrayRef(g_thread_select_options);
1165+
}
1166+
1167+
bool m_thread_id;
1168+
};
1169+
11341170
CommandObjectThreadSelect(CommandInterpreter &interpreter)
11351171
: CommandObjectParsed(interpreter, "thread select",
11361172
"Change the currently selected thread.", nullptr,
@@ -1165,6 +1201,8 @@ class CommandObjectThreadSelect : public CommandObjectParsed {
11651201
nullptr);
11661202
}
11671203

1204+
Options *GetOptions() override { return &m_options; }
1205+
11681206
protected:
11691207
void DoExecute(Args &command, CommandReturnObject &result) override {
11701208
Process *process = m_exe_ctx.GetProcessPtr();
@@ -1173,29 +1211,38 @@ class CommandObjectThreadSelect : public CommandObjectParsed {
11731211
return;
11741212
} else if (command.GetArgumentCount() != 1) {
11751213
result.AppendErrorWithFormat(
1176-
"'%s' takes exactly one thread index argument:\nUsage: %s\n",
1177-
m_cmd_name.c_str(), m_cmd_syntax.c_str());
1214+
"'%s' takes exactly one thread %s argument:\nUsage: %s\n",
1215+
m_cmd_name.c_str(), m_options.m_thread_id ? "ID" : "index",
1216+
m_cmd_syntax.c_str());
11781217
return;
11791218
}
11801219

11811220
uint32_t index_id;
11821221
if (!llvm::to_integer(command.GetArgumentAtIndex(0), index_id)) {
1183-
result.AppendErrorWithFormat("Invalid thread index '%s'",
1222+
result.AppendErrorWithFormat("Invalid thread %s '%s'",
1223+
m_options.m_thread_id ? "ID" : "index",
11841224
command.GetArgumentAtIndex(0));
11851225
return;
11861226
}
11871227

1188-
Thread *new_thread =
1189-
process->GetThreadList().FindThreadByIndexID(index_id).get();
1228+
Thread *new_thread = nullptr;
1229+
if (m_options.m_thread_id) {
1230+
new_thread = process->GetThreadList().FindThreadByID(index_id).get();
1231+
} else {
1232+
new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get();
1233+
}
11901234
if (new_thread == nullptr) {
1191-
result.AppendErrorWithFormat("invalid thread #%s.\n",
1235+
result.AppendErrorWithFormat("invalid thread %s%s.\n",
1236+
m_options.m_thread_id ? "ID " : "#",
11921237
command.GetArgumentAtIndex(0));
11931238
return;
11941239
}
11951240

11961241
process->GetThreadList().SetSelectedThreadByID(new_thread->GetID(), true);
11971242
result.SetStatus(eReturnStatusSuccessFinishNoResult);
11981243
}
1244+
1245+
CommandOptions m_options;
11991246
};
12001247

12011248
// CommandObjectThreadList

lldb/source/Commands/Options.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,6 +1117,11 @@ let Command = "thread plan list" in {
11171117
Desc<"Display thread plans for unreported threads">;
11181118
}
11191119

1120+
let Command = "thread select" in {
1121+
def thread_thread_id : Option<"thread_id", "t">,
1122+
Desc<"Provide a thread ID instead of a thread index.">;
1123+
}
1124+
11201125
let Command = "thread trace dump function calls" in {
11211126
def thread_trace_dump_function_calls_file : Option<"file", "F">, Group<1>,
11221127
Arg<"Filename">,

lldb/test/API/commands/thread/select/TestThreadSelect.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,34 @@ def test_invalid_arg(self):
1212
self, "// break here", lldb.SBFileSpec("main.cpp")
1313
)
1414

15-
self.expect(
16-
"thread select -1", error=True, startstr="error: Invalid thread index '-1'"
17-
)
1815
self.expect(
1916
"thread select 0x1ffffffff",
2017
error=True,
2118
startstr="error: Invalid thread index '0x1ffffffff'",
2219
)
20+
self.expect(
21+
"thread select -t 0x1ffffffff",
22+
error=True,
23+
startstr="error: Invalid thread ID '0x1ffffffff'",
24+
)
2325
# Parses but not a valid thread id.
2426
self.expect(
2527
"thread select 0xffffffff",
2628
error=True,
2729
startstr="error: invalid thread #0xffffffff.",
2830
)
31+
self.expect(
32+
"thread select -t 0xffffffff",
33+
error=True,
34+
startstr="error: invalid thread ID 0xffffffff.",
35+
)
36+
37+
def test_thread_select_tid(self):
38+
self.build()
39+
40+
lldbutil.run_to_source_breakpoint(
41+
self, "// break here", lldb.SBFileSpec("main.cpp")
42+
)
43+
self.runCmd(
44+
"thread select -t %d" % self.thread().GetThreadID(),
45+
)

0 commit comments

Comments
 (0)