@@ -1129,11 +1129,51 @@ class CommandObjectThreadUntil : public CommandObjectParsed {
1129
1129
1130
1130
// CommandObjectThreadSelect
1131
1131
1132
+ #define LLDB_OPTIONS_thread_select
1133
+ #include " CommandOptions.inc"
1134
+
1132
1135
class CommandObjectThreadSelect : public CommandObjectParsed {
1133
1136
public:
1137
+ class OptionGroupThreadSelect : public OptionGroup {
1138
+ public:
1139
+ OptionGroupThreadSelect () { OptionParsingStarting (nullptr ); }
1140
+
1141
+ ~OptionGroupThreadSelect () override = default ;
1142
+
1143
+ void OptionParsingStarting (ExecutionContext *execution_context) override {
1144
+ m_thread_id = LLDB_INVALID_THREAD_ID;
1145
+ }
1146
+
1147
+ Status SetOptionValue (uint32_t option_idx, llvm::StringRef option_arg,
1148
+ ExecutionContext *execution_context) override {
1149
+ const int short_option = g_thread_select_options[option_idx].short_option ;
1150
+ switch (short_option) {
1151
+ case ' t' : {
1152
+ if (option_arg.getAsInteger (0 , m_thread_id)) {
1153
+ m_thread_id = LLDB_INVALID_THREAD_ID;
1154
+ return Status (" Invalid thread ID: '%s'." , option_arg.str ().c_str ());
1155
+ }
1156
+ break ;
1157
+ }
1158
+
1159
+ default :
1160
+ llvm_unreachable (" Unimplemented option" );
1161
+ }
1162
+
1163
+ return {};
1164
+ }
1165
+
1166
+ llvm::ArrayRef<OptionDefinition> GetDefinitions () override {
1167
+ return llvm::ArrayRef (g_thread_select_options);
1168
+ }
1169
+
1170
+ lldb::tid_t m_thread_id;
1171
+ };
1172
+
1134
1173
CommandObjectThreadSelect (CommandInterpreter &interpreter)
1135
1174
: CommandObjectParsed(interpreter, " thread select" ,
1136
- " Change the currently selected thread." , nullptr ,
1175
+ " Change the currently selected thread." ,
1176
+ " thread select <thread-index> (or -t <thread-id>)" ,
1137
1177
eCommandRequiresProcess | eCommandTryTargetAPILock |
1138
1178
eCommandProcessMustBeLaunched |
1139
1179
eCommandProcessMustBePaused) {
@@ -1143,13 +1183,17 @@ class CommandObjectThreadSelect : public CommandObjectParsed {
1143
1183
// Define the first (and only) variant of this arg.
1144
1184
thread_idx_arg.arg_type = eArgTypeThreadIndex;
1145
1185
thread_idx_arg.arg_repetition = eArgRepeatPlain;
1186
+ thread_idx_arg.arg_opt_set_association = LLDB_OPT_SET_1;
1146
1187
1147
1188
// There is only one variant this argument could be; put it into the
1148
1189
// argument entry.
1149
1190
arg.push_back (thread_idx_arg);
1150
1191
1151
1192
// Push the data for the first argument into the m_arguments vector.
1152
1193
m_arguments.push_back (arg);
1194
+
1195
+ m_option_group.Append (&m_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_2);
1196
+ m_option_group.Finalize ();
1153
1197
}
1154
1198
1155
1199
~CommandObjectThreadSelect () override = default ;
@@ -1165,37 +1209,59 @@ class CommandObjectThreadSelect : public CommandObjectParsed {
1165
1209
nullptr );
1166
1210
}
1167
1211
1212
+ Options *GetOptions () override { return &m_option_group; }
1213
+
1168
1214
protected:
1169
1215
void DoExecute (Args &command, CommandReturnObject &result) override {
1170
1216
Process *process = m_exe_ctx.GetProcessPtr ();
1171
1217
if (process == nullptr ) {
1172
1218
result.AppendError (" no process" );
1173
1219
return ;
1174
- } else if (command.GetArgumentCount () != 1 ) {
1220
+ } else if (m_options.m_thread_id == LLDB_INVALID_THREAD_ID &&
1221
+ command.GetArgumentCount () != 1 ) {
1175
1222
result.AppendErrorWithFormat (
1176
- " '%s' takes exactly one thread index argument:\n Usage: %s\n " ,
1223
+ " '%s' takes exactly one thread index argument, or a thread ID "
1224
+ " option:\n Usage: %s\n " ,
1177
1225
m_cmd_name.c_str (), m_cmd_syntax.c_str ());
1178
1226
return ;
1179
- }
1180
-
1181
- uint32_t index_id;
1182
- if (!llvm::to_integer (command.GetArgumentAtIndex (0 ), index_id)) {
1183
- result.AppendErrorWithFormat (" Invalid thread index '%s'" ,
1184
- command.GetArgumentAtIndex (0 ));
1227
+ } else if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID &&
1228
+ command.GetArgumentCount () != 0 ) {
1229
+ result.AppendErrorWithFormat (" '%s' cannot take both a thread ID option "
1230
+ " and a thread index argument:\n Usage: %s\n " ,
1231
+ m_cmd_name.c_str (), m_cmd_syntax.c_str ());
1185
1232
return ;
1186
1233
}
1187
1234
1188
- Thread *new_thread =
1189
- process->GetThreadList ().FindThreadByIndexID (index_id).get ();
1190
- if (new_thread == nullptr ) {
1191
- result.AppendErrorWithFormat (" invalid thread #%s.\n " ,
1192
- command.GetArgumentAtIndex (0 ));
1193
- return ;
1235
+ Thread *new_thread = nullptr ;
1236
+ if (command.GetArgumentCount () == 1 ) {
1237
+ uint32_t index_id;
1238
+ if (!llvm::to_integer (command.GetArgumentAtIndex (0 ), index_id)) {
1239
+ result.AppendErrorWithFormat (" Invalid thread index '%s'" ,
1240
+ command.GetArgumentAtIndex (0 ));
1241
+ return ;
1242
+ }
1243
+ new_thread = process->GetThreadList ().FindThreadByIndexID (index_id).get ();
1244
+ if (new_thread == nullptr ) {
1245
+ result.AppendErrorWithFormat (" Invalid thread index #%s.\n " ,
1246
+ command.GetArgumentAtIndex (0 ));
1247
+ return ;
1248
+ }
1249
+ } else {
1250
+ new_thread =
1251
+ process->GetThreadList ().FindThreadByID (m_options.m_thread_id ).get ();
1252
+ if (new_thread == nullptr ) {
1253
+ result.AppendErrorWithFormat (" Invalid thread ID %" PRIu64 " .\n " ,
1254
+ m_options.m_thread_id );
1255
+ return ;
1256
+ }
1194
1257
}
1195
1258
1196
1259
process->GetThreadList ().SetSelectedThreadByID (new_thread->GetID (), true );
1197
1260
result.SetStatus (eReturnStatusSuccessFinishNoResult);
1198
1261
}
1262
+
1263
+ OptionGroupThreadSelect m_options;
1264
+ OptionGroupOptions m_option_group;
1199
1265
};
1200
1266
1201
1267
// CommandObjectThreadList
0 commit comments