xref: /llvm-project/lldb/source/Commands/CommandObjectThread.cpp (revision 58e9cc13e24f668a33abdae201d59a02e10c22c0)
1 //===-- CommandObjectThread.cpp -------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "CommandObjectThread.h"
10 
11 #include <memory>
12 #include <sstream>
13 
14 #include "CommandObjectThreadUtil.h"
15 #include "CommandObjectTrace.h"
16 #include "lldb/Core/PluginManager.h"
17 #include "lldb/Core/ValueObject.h"
18 #include "lldb/Host/OptionParser.h"
19 #include "lldb/Interpreter/CommandInterpreter.h"
20 #include "lldb/Interpreter/CommandOptionArgumentTable.h"
21 #include "lldb/Interpreter/CommandReturnObject.h"
22 #include "lldb/Interpreter/OptionArgParser.h"
23 #include "lldb/Interpreter/OptionGroupPythonClassWithDict.h"
24 #include "lldb/Interpreter/Options.h"
25 #include "lldb/Symbol/CompileUnit.h"
26 #include "lldb/Symbol/Function.h"
27 #include "lldb/Symbol/LineEntry.h"
28 #include "lldb/Symbol/LineTable.h"
29 #include "lldb/Target/Process.h"
30 #include "lldb/Target/RegisterContext.h"
31 #include "lldb/Target/SystemRuntime.h"
32 #include "lldb/Target/Target.h"
33 #include "lldb/Target/Thread.h"
34 #include "lldb/Target/ThreadPlan.h"
35 #include "lldb/Target/ThreadPlanStepInRange.h"
36 #include "lldb/Target/Trace.h"
37 #include "lldb/Target/TraceDumper.h"
38 #include "lldb/Utility/State.h"
39 
40 using namespace lldb;
41 using namespace lldb_private;
42 
43 // CommandObjectThreadBacktrace
44 #define LLDB_OPTIONS_thread_backtrace
45 #include "CommandOptions.inc"
46 
47 class CommandObjectThreadBacktrace : public CommandObjectIterateOverThreads {
48 public:
49   class CommandOptions : public Options {
50   public:
51     CommandOptions() {
52       // Keep default values of all options in one place: OptionParsingStarting
53       // ()
54       OptionParsingStarting(nullptr);
55     }
56 
57     ~CommandOptions() override = default;
58 
59     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
60                           ExecutionContext *execution_context) override {
61       Status error;
62       const int short_option = m_getopt_table[option_idx].val;
63 
64       switch (short_option) {
65       case 'c':
66         if (option_arg.getAsInteger(0, m_count)) {
67           m_count = UINT32_MAX;
68           error.SetErrorStringWithFormat(
69               "invalid integer value for option '%c'", short_option);
70         }
71         break;
72       case 's':
73         if (option_arg.getAsInteger(0, m_start))
74           error.SetErrorStringWithFormat(
75               "invalid integer value for option '%c'", short_option);
76         break;
77       case 'e': {
78         bool success;
79         m_extended_backtrace =
80             OptionArgParser::ToBoolean(option_arg, false, &success);
81         if (!success)
82           error.SetErrorStringWithFormat(
83               "invalid boolean value for option '%c'", short_option);
84       } break;
85       default:
86         llvm_unreachable("Unimplemented option");
87       }
88       return error;
89     }
90 
91     void OptionParsingStarting(ExecutionContext *execution_context) override {
92       m_count = UINT32_MAX;
93       m_start = 0;
94       m_extended_backtrace = false;
95     }
96 
97     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
98       return llvm::makeArrayRef(g_thread_backtrace_options);
99     }
100 
101     // Instance variables to hold the values for command options.
102     uint32_t m_count;
103     uint32_t m_start;
104     bool m_extended_backtrace;
105   };
106 
107   CommandObjectThreadBacktrace(CommandInterpreter &interpreter)
108       : CommandObjectIterateOverThreads(
109             interpreter, "thread backtrace",
110             "Show thread call stacks.  Defaults to the current thread, thread "
111             "indexes can be specified as arguments.\n"
112             "Use the thread-index \"all\" to see all threads.\n"
113             "Use the thread-index \"unique\" to see threads grouped by unique "
114             "call stacks.\n"
115             "Use 'settings set frame-format' to customize the printing of "
116             "frames in the backtrace and 'settings set thread-format' to "
117             "customize the thread header.",
118             nullptr,
119             eCommandRequiresProcess | eCommandRequiresThread |
120                 eCommandTryTargetAPILock | eCommandProcessMustBeLaunched |
121                 eCommandProcessMustBePaused) {}
122 
123   ~CommandObjectThreadBacktrace() override = default;
124 
125   Options *GetOptions() override { return &m_options; }
126 
127   llvm::Optional<std::string> GetRepeatCommand(Args &current_args,
128                                                uint32_t idx) override {
129     llvm::StringRef count_opt("--count");
130     llvm::StringRef start_opt("--start");
131 
132     // If no "count" was provided, we are dumping the entire backtrace, so
133     // there isn't a repeat command.  So we search for the count option in
134     // the args, and if we find it, we make a copy and insert or modify the
135     // start option's value to start count indices greater.
136 
137     Args copy_args(current_args);
138     size_t num_entries = copy_args.GetArgumentCount();
139     // These two point at the index of the option value if found.
140     size_t count_idx = 0;
141     size_t start_idx = 0;
142     size_t count_val = 0;
143     size_t start_val = 0;
144 
145     for (size_t idx = 0; idx < num_entries; idx++) {
146       llvm::StringRef arg_string = copy_args[idx].ref();
147       if (arg_string.equals("-c") || count_opt.startswith(arg_string)) {
148         idx++;
149         if (idx == num_entries)
150           return std::nullopt;
151         count_idx = idx;
152         if (copy_args[idx].ref().getAsInteger(0, count_val))
153           return std::nullopt;
154       } else if (arg_string.equals("-s") || start_opt.startswith(arg_string)) {
155         idx++;
156         if (idx == num_entries)
157           return std::nullopt;
158         start_idx = idx;
159         if (copy_args[idx].ref().getAsInteger(0, start_val))
160           return std::nullopt;
161       }
162     }
163     if (count_idx == 0)
164       return std::nullopt;
165 
166     std::string new_start_val = llvm::formatv("{0}", start_val + count_val);
167     if (start_idx == 0) {
168       copy_args.AppendArgument(start_opt);
169       copy_args.AppendArgument(new_start_val);
170     } else {
171       copy_args.ReplaceArgumentAtIndex(start_idx, new_start_val);
172     }
173     std::string repeat_command;
174     if (!copy_args.GetQuotedCommandString(repeat_command))
175       return std::nullopt;
176     return repeat_command;
177   }
178 
179 protected:
180   void DoExtendedBacktrace(Thread *thread, CommandReturnObject &result) {
181     SystemRuntime *runtime = thread->GetProcess()->GetSystemRuntime();
182     if (runtime) {
183       Stream &strm = result.GetOutputStream();
184       const std::vector<ConstString> &types =
185           runtime->GetExtendedBacktraceTypes();
186       for (auto type : types) {
187         ThreadSP ext_thread_sp = runtime->GetExtendedBacktraceThread(
188             thread->shared_from_this(), type);
189         if (ext_thread_sp && ext_thread_sp->IsValid()) {
190           const uint32_t num_frames_with_source = 0;
191           const bool stop_format = false;
192           strm.PutChar('\n');
193           if (ext_thread_sp->GetStatus(strm, m_options.m_start,
194                                        m_options.m_count,
195                                        num_frames_with_source, stop_format)) {
196             DoExtendedBacktrace(ext_thread_sp.get(), result);
197           }
198         }
199       }
200     }
201   }
202 
203   bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override {
204     ThreadSP thread_sp =
205         m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid);
206     if (!thread_sp) {
207       result.AppendErrorWithFormat(
208           "thread disappeared while computing backtraces: 0x%" PRIx64 "\n",
209           tid);
210       return false;
211     }
212 
213     Thread *thread = thread_sp.get();
214 
215     Stream &strm = result.GetOutputStream();
216 
217     // Only dump stack info if we processing unique stacks.
218     const bool only_stacks = m_unique_stacks;
219 
220     // Don't show source context when doing backtraces.
221     const uint32_t num_frames_with_source = 0;
222     const bool stop_format = true;
223     if (!thread->GetStatus(strm, m_options.m_start, m_options.m_count,
224                            num_frames_with_source, stop_format, only_stacks)) {
225       result.AppendErrorWithFormat(
226           "error displaying backtrace for thread: \"0x%4.4x\"\n",
227           thread->GetIndexID());
228       return false;
229     }
230     if (m_options.m_extended_backtrace) {
231       DoExtendedBacktrace(thread, result);
232     }
233 
234     return true;
235   }
236 
237   CommandOptions m_options;
238 };
239 
240 enum StepScope { eStepScopeSource, eStepScopeInstruction };
241 
242 #define LLDB_OPTIONS_thread_step_scope
243 #include "CommandOptions.inc"
244 
245 class ThreadStepScopeOptionGroup : public OptionGroup {
246 public:
247   ThreadStepScopeOptionGroup() {
248     // Keep default values of all options in one place: OptionParsingStarting
249     // ()
250     OptionParsingStarting(nullptr);
251   }
252 
253   ~ThreadStepScopeOptionGroup() override = default;
254 
255   llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
256     return llvm::makeArrayRef(g_thread_step_scope_options);
257   }
258 
259   Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
260                         ExecutionContext *execution_context) override {
261     Status error;
262     const int short_option =
263         g_thread_step_scope_options[option_idx].short_option;
264 
265     switch (short_option) {
266     case 'a': {
267       bool success;
268       bool avoid_no_debug =
269           OptionArgParser::ToBoolean(option_arg, true, &success);
270       if (!success)
271         error.SetErrorStringWithFormat("invalid boolean value for option '%c'",
272                                        short_option);
273       else {
274         m_step_in_avoid_no_debug = avoid_no_debug ? eLazyBoolYes : eLazyBoolNo;
275       }
276     } break;
277 
278     case 'A': {
279       bool success;
280       bool avoid_no_debug =
281           OptionArgParser::ToBoolean(option_arg, true, &success);
282       if (!success)
283         error.SetErrorStringWithFormat("invalid boolean value for option '%c'",
284                                        short_option);
285       else {
286         m_step_out_avoid_no_debug = avoid_no_debug ? eLazyBoolYes : eLazyBoolNo;
287       }
288     } break;
289 
290     case 'c':
291       if (option_arg.getAsInteger(0, m_step_count))
292         error.SetErrorStringWithFormat("invalid step count '%s'",
293                                        option_arg.str().c_str());
294       break;
295 
296     case 'm': {
297       auto enum_values = GetDefinitions()[option_idx].enum_values;
298       m_run_mode = (lldb::RunMode)OptionArgParser::ToOptionEnum(
299           option_arg, enum_values, eOnlyDuringStepping, error);
300     } break;
301 
302     case 'e':
303       if (option_arg == "block") {
304         m_end_line_is_block_end = true;
305         break;
306       }
307       if (option_arg.getAsInteger(0, m_end_line))
308         error.SetErrorStringWithFormat("invalid end line number '%s'",
309                                        option_arg.str().c_str());
310       break;
311 
312     case 'r':
313       m_avoid_regexp.clear();
314       m_avoid_regexp.assign(std::string(option_arg));
315       break;
316 
317     case 't':
318       m_step_in_target.clear();
319       m_step_in_target.assign(std::string(option_arg));
320       break;
321 
322     default:
323       llvm_unreachable("Unimplemented option");
324     }
325     return error;
326   }
327 
328   void OptionParsingStarting(ExecutionContext *execution_context) override {
329     m_step_in_avoid_no_debug = eLazyBoolCalculate;
330     m_step_out_avoid_no_debug = eLazyBoolCalculate;
331     m_run_mode = eOnlyDuringStepping;
332 
333     // Check if we are in Non-Stop mode
334     TargetSP target_sp =
335         execution_context ? execution_context->GetTargetSP() : TargetSP();
336     ProcessSP process_sp =
337         execution_context ? execution_context->GetProcessSP() : ProcessSP();
338     if (process_sp && process_sp->GetSteppingRunsAllThreads())
339       m_run_mode = eAllThreads;
340 
341     m_avoid_regexp.clear();
342     m_step_in_target.clear();
343     m_step_count = 1;
344     m_end_line = LLDB_INVALID_LINE_NUMBER;
345     m_end_line_is_block_end = false;
346   }
347 
348   // Instance variables to hold the values for command options.
349   LazyBool m_step_in_avoid_no_debug;
350   LazyBool m_step_out_avoid_no_debug;
351   RunMode m_run_mode;
352   std::string m_avoid_regexp;
353   std::string m_step_in_target;
354   uint32_t m_step_count;
355   uint32_t m_end_line;
356   bool m_end_line_is_block_end;
357 };
358 
359 class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed {
360 public:
361   CommandObjectThreadStepWithTypeAndScope(CommandInterpreter &interpreter,
362                                           const char *name, const char *help,
363                                           const char *syntax,
364                                           StepType step_type,
365                                           StepScope step_scope)
366       : CommandObjectParsed(interpreter, name, help, syntax,
367                             eCommandRequiresProcess | eCommandRequiresThread |
368                                 eCommandTryTargetAPILock |
369                                 eCommandProcessMustBeLaunched |
370                                 eCommandProcessMustBePaused),
371         m_step_type(step_type), m_step_scope(step_scope),
372         m_class_options("scripted step") {
373     CommandArgumentEntry arg;
374     CommandArgumentData thread_id_arg;
375 
376     // Define the first (and only) variant of this arg.
377     thread_id_arg.arg_type = eArgTypeThreadID;
378     thread_id_arg.arg_repetition = eArgRepeatOptional;
379 
380     // There is only one variant this argument could be; put it into the
381     // argument entry.
382     arg.push_back(thread_id_arg);
383 
384     // Push the data for the first argument into the m_arguments vector.
385     m_arguments.push_back(arg);
386 
387     if (step_type == eStepTypeScripted) {
388       m_all_options.Append(&m_class_options, LLDB_OPT_SET_1 | LLDB_OPT_SET_2,
389                            LLDB_OPT_SET_1);
390     }
391     m_all_options.Append(&m_options);
392     m_all_options.Finalize();
393   }
394 
395   ~CommandObjectThreadStepWithTypeAndScope() override = default;
396 
397   void
398   HandleArgumentCompletion(CompletionRequest &request,
399                            OptionElementVector &opt_element_vector) override {
400     if (request.GetCursorIndex())
401       return;
402 
403     CommandCompletions::InvokeCommonCompletionCallbacks(
404         GetCommandInterpreter(), CommandCompletions::eThreadIndexCompletion,
405         request, nullptr);
406   }
407 
408   Options *GetOptions() override { return &m_all_options; }
409 
410 protected:
411   bool DoExecute(Args &command, CommandReturnObject &result) override {
412     Process *process = m_exe_ctx.GetProcessPtr();
413     bool synchronous_execution = m_interpreter.GetSynchronous();
414 
415     const uint32_t num_threads = process->GetThreadList().GetSize();
416     Thread *thread = nullptr;
417 
418     if (command.GetArgumentCount() == 0) {
419       thread = GetDefaultThread();
420 
421       if (thread == nullptr) {
422         result.AppendError("no selected thread in process");
423         return false;
424       }
425     } else {
426       const char *thread_idx_cstr = command.GetArgumentAtIndex(0);
427       uint32_t step_thread_idx;
428 
429       if (!llvm::to_integer(thread_idx_cstr, step_thread_idx)) {
430         result.AppendErrorWithFormat("invalid thread index '%s'.\n",
431                                      thread_idx_cstr);
432         return false;
433       }
434       thread =
435           process->GetThreadList().FindThreadByIndexID(step_thread_idx).get();
436       if (thread == nullptr) {
437         result.AppendErrorWithFormat(
438             "Thread index %u is out of range (valid values are 0 - %u).\n",
439             step_thread_idx, num_threads);
440         return false;
441       }
442     }
443 
444     if (m_step_type == eStepTypeScripted) {
445       if (m_class_options.GetName().empty()) {
446         result.AppendErrorWithFormat("empty class name for scripted step.");
447         return false;
448       } else if (!GetDebugger().GetScriptInterpreter()->CheckObjectExists(
449                      m_class_options.GetName().c_str())) {
450         result.AppendErrorWithFormat(
451             "class for scripted step: \"%s\" does not exist.",
452             m_class_options.GetName().c_str());
453         return false;
454       }
455     }
456 
457     if (m_options.m_end_line != LLDB_INVALID_LINE_NUMBER &&
458         m_step_type != eStepTypeInto) {
459       result.AppendErrorWithFormat(
460           "end line option is only valid for step into");
461       return false;
462     }
463 
464     const bool abort_other_plans = false;
465     const lldb::RunMode stop_other_threads = m_options.m_run_mode;
466 
467     // This is a bit unfortunate, but not all the commands in this command
468     // object support only while stepping, so I use the bool for them.
469     bool bool_stop_other_threads;
470     if (m_options.m_run_mode == eAllThreads)
471       bool_stop_other_threads = false;
472     else if (m_options.m_run_mode == eOnlyDuringStepping)
473       bool_stop_other_threads = (m_step_type != eStepTypeOut);
474     else
475       bool_stop_other_threads = true;
476 
477     ThreadPlanSP new_plan_sp;
478     Status new_plan_status;
479 
480     if (m_step_type == eStepTypeInto) {
481       StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
482       assert(frame != nullptr);
483 
484       if (frame->HasDebugInformation()) {
485         AddressRange range;
486         SymbolContext sc = frame->GetSymbolContext(eSymbolContextEverything);
487         if (m_options.m_end_line != LLDB_INVALID_LINE_NUMBER) {
488           Status error;
489           if (!sc.GetAddressRangeFromHereToEndLine(m_options.m_end_line, range,
490                                                    error)) {
491             result.AppendErrorWithFormat("invalid end-line option: %s.",
492                                          error.AsCString());
493             return false;
494           }
495         } else if (m_options.m_end_line_is_block_end) {
496           Status error;
497           Block *block = frame->GetSymbolContext(eSymbolContextBlock).block;
498           if (!block) {
499             result.AppendErrorWithFormat("Could not find the current block.");
500             return false;
501           }
502 
503           AddressRange block_range;
504           Address pc_address = frame->GetFrameCodeAddress();
505           block->GetRangeContainingAddress(pc_address, block_range);
506           if (!block_range.GetBaseAddress().IsValid()) {
507             result.AppendErrorWithFormat(
508                 "Could not find the current block address.");
509             return false;
510           }
511           lldb::addr_t pc_offset_in_block =
512               pc_address.GetFileAddress() -
513               block_range.GetBaseAddress().GetFileAddress();
514           lldb::addr_t range_length =
515               block_range.GetByteSize() - pc_offset_in_block;
516           range = AddressRange(pc_address, range_length);
517         } else {
518           range = sc.line_entry.range;
519         }
520 
521         new_plan_sp = thread->QueueThreadPlanForStepInRange(
522             abort_other_plans, range,
523             frame->GetSymbolContext(eSymbolContextEverything),
524             m_options.m_step_in_target.c_str(), stop_other_threads,
525             new_plan_status, m_options.m_step_in_avoid_no_debug,
526             m_options.m_step_out_avoid_no_debug);
527 
528         if (new_plan_sp && !m_options.m_avoid_regexp.empty()) {
529           ThreadPlanStepInRange *step_in_range_plan =
530               static_cast<ThreadPlanStepInRange *>(new_plan_sp.get());
531           step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str());
532         }
533       } else
534         new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
535             false, abort_other_plans, bool_stop_other_threads, new_plan_status);
536     } else if (m_step_type == eStepTypeOver) {
537       StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
538 
539       if (frame->HasDebugInformation())
540         new_plan_sp = thread->QueueThreadPlanForStepOverRange(
541             abort_other_plans,
542             frame->GetSymbolContext(eSymbolContextEverything).line_entry,
543             frame->GetSymbolContext(eSymbolContextEverything),
544             stop_other_threads, new_plan_status,
545             m_options.m_step_out_avoid_no_debug);
546       else
547         new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
548             true, abort_other_plans, bool_stop_other_threads, new_plan_status);
549     } else if (m_step_type == eStepTypeTrace) {
550       new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
551           false, abort_other_plans, bool_stop_other_threads, new_plan_status);
552     } else if (m_step_type == eStepTypeTraceOver) {
553       new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
554           true, abort_other_plans, bool_stop_other_threads, new_plan_status);
555     } else if (m_step_type == eStepTypeOut) {
556       new_plan_sp = thread->QueueThreadPlanForStepOut(
557           abort_other_plans, nullptr, false, bool_stop_other_threads, eVoteYes,
558           eVoteNoOpinion, thread->GetSelectedFrameIndex(), new_plan_status,
559           m_options.m_step_out_avoid_no_debug);
560     } else if (m_step_type == eStepTypeScripted) {
561       new_plan_sp = thread->QueueThreadPlanForStepScripted(
562           abort_other_plans, m_class_options.GetName().c_str(),
563           m_class_options.GetStructuredData(), bool_stop_other_threads,
564           new_plan_status);
565     } else {
566       result.AppendError("step type is not supported");
567       return false;
568     }
569 
570     // If we got a new plan, then set it to be a controlling plan (User level
571     // Plans should be controlling plans so that they can be interruptible).
572     // Then resume the process.
573 
574     if (new_plan_sp) {
575       new_plan_sp->SetIsControllingPlan(true);
576       new_plan_sp->SetOkayToDiscard(false);
577 
578       if (m_options.m_step_count > 1) {
579         if (!new_plan_sp->SetIterationCount(m_options.m_step_count)) {
580           result.AppendWarning(
581               "step operation does not support iteration count.");
582         }
583       }
584 
585       process->GetThreadList().SetSelectedThreadByID(thread->GetID());
586 
587       const uint32_t iohandler_id = process->GetIOHandlerID();
588 
589       StreamString stream;
590       Status error;
591       if (synchronous_execution)
592         error = process->ResumeSynchronous(&stream);
593       else
594         error = process->Resume();
595 
596       if (!error.Success()) {
597         result.AppendMessage(error.AsCString());
598         return false;
599       }
600 
601       // There is a race condition where this thread will return up the call
602       // stack to the main command handler and show an (lldb) prompt before
603       // HandlePrivateEvent (from PrivateStateThread) has a chance to call
604       // PushProcessIOHandler().
605       process->SyncIOHandler(iohandler_id, std::chrono::seconds(2));
606 
607       if (synchronous_execution) {
608         // If any state changed events had anything to say, add that to the
609         // result
610         if (stream.GetSize() > 0)
611           result.AppendMessage(stream.GetString());
612 
613         process->GetThreadList().SetSelectedThreadByID(thread->GetID());
614         result.SetDidChangeProcessState(true);
615         result.SetStatus(eReturnStatusSuccessFinishNoResult);
616       } else {
617         result.SetStatus(eReturnStatusSuccessContinuingNoResult);
618       }
619     } else {
620       result.SetError(new_plan_status);
621     }
622     return result.Succeeded();
623   }
624 
625   StepType m_step_type;
626   StepScope m_step_scope;
627   ThreadStepScopeOptionGroup m_options;
628   OptionGroupPythonClassWithDict m_class_options;
629   OptionGroupOptions m_all_options;
630 };
631 
632 // CommandObjectThreadContinue
633 
634 class CommandObjectThreadContinue : public CommandObjectParsed {
635 public:
636   CommandObjectThreadContinue(CommandInterpreter &interpreter)
637       : CommandObjectParsed(
638             interpreter, "thread continue",
639             "Continue execution of the current target process.  One "
640             "or more threads may be specified, by default all "
641             "threads continue.",
642             nullptr,
643             eCommandRequiresThread | eCommandTryTargetAPILock |
644                 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {
645     CommandArgumentEntry arg;
646     CommandArgumentData thread_idx_arg;
647 
648     // Define the first (and only) variant of this arg.
649     thread_idx_arg.arg_type = eArgTypeThreadIndex;
650     thread_idx_arg.arg_repetition = eArgRepeatPlus;
651 
652     // There is only one variant this argument could be; put it into the
653     // argument entry.
654     arg.push_back(thread_idx_arg);
655 
656     // Push the data for the first argument into the m_arguments vector.
657     m_arguments.push_back(arg);
658   }
659 
660   ~CommandObjectThreadContinue() override = default;
661 
662   void
663   HandleArgumentCompletion(CompletionRequest &request,
664                            OptionElementVector &opt_element_vector) override {
665     CommandCompletions::InvokeCommonCompletionCallbacks(
666         GetCommandInterpreter(), CommandCompletions::eThreadIndexCompletion,
667         request, nullptr);
668   }
669 
670   bool DoExecute(Args &command, CommandReturnObject &result) override {
671     bool synchronous_execution = m_interpreter.GetSynchronous();
672 
673     Process *process = m_exe_ctx.GetProcessPtr();
674     if (process == nullptr) {
675       result.AppendError("no process exists. Cannot continue");
676       return false;
677     }
678 
679     StateType state = process->GetState();
680     if ((state == eStateCrashed) || (state == eStateStopped) ||
681         (state == eStateSuspended)) {
682       const size_t argc = command.GetArgumentCount();
683       if (argc > 0) {
684         // These two lines appear at the beginning of both blocks in this
685         // if..else, but that is because we need to release the lock before
686         // calling process->Resume below.
687         std::lock_guard<std::recursive_mutex> guard(
688             process->GetThreadList().GetMutex());
689         const uint32_t num_threads = process->GetThreadList().GetSize();
690         std::vector<Thread *> resume_threads;
691         for (auto &entry : command.entries()) {
692           uint32_t thread_idx;
693           if (entry.ref().getAsInteger(0, thread_idx)) {
694             result.AppendErrorWithFormat(
695                 "invalid thread index argument: \"%s\".\n", entry.c_str());
696             return false;
697           }
698           Thread *thread =
699               process->GetThreadList().FindThreadByIndexID(thread_idx).get();
700 
701           if (thread) {
702             resume_threads.push_back(thread);
703           } else {
704             result.AppendErrorWithFormat("invalid thread index %u.\n",
705                                          thread_idx);
706             return false;
707           }
708         }
709 
710         if (resume_threads.empty()) {
711           result.AppendError("no valid thread indexes were specified");
712           return false;
713         } else {
714           if (resume_threads.size() == 1)
715             result.AppendMessageWithFormat("Resuming thread: ");
716           else
717             result.AppendMessageWithFormat("Resuming threads: ");
718 
719           for (uint32_t idx = 0; idx < num_threads; ++idx) {
720             Thread *thread =
721                 process->GetThreadList().GetThreadAtIndex(idx).get();
722             std::vector<Thread *>::iterator this_thread_pos =
723                 find(resume_threads.begin(), resume_threads.end(), thread);
724 
725             if (this_thread_pos != resume_threads.end()) {
726               resume_threads.erase(this_thread_pos);
727               if (!resume_threads.empty())
728                 result.AppendMessageWithFormat("%u, ", thread->GetIndexID());
729               else
730                 result.AppendMessageWithFormat("%u ", thread->GetIndexID());
731 
732               const bool override_suspend = true;
733               thread->SetResumeState(eStateRunning, override_suspend);
734             } else {
735               thread->SetResumeState(eStateSuspended);
736             }
737           }
738           result.AppendMessageWithFormat("in process %" PRIu64 "\n",
739                                          process->GetID());
740         }
741       } else {
742         // These two lines appear at the beginning of both blocks in this
743         // if..else, but that is because we need to release the lock before
744         // calling process->Resume below.
745         std::lock_guard<std::recursive_mutex> guard(
746             process->GetThreadList().GetMutex());
747         const uint32_t num_threads = process->GetThreadList().GetSize();
748         Thread *current_thread = GetDefaultThread();
749         if (current_thread == nullptr) {
750           result.AppendError("the process doesn't have a current thread");
751           return false;
752         }
753         // Set the actions that the threads should each take when resuming
754         for (uint32_t idx = 0; idx < num_threads; ++idx) {
755           Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
756           if (thread == current_thread) {
757             result.AppendMessageWithFormat("Resuming thread 0x%4.4" PRIx64
758                                            " in process %" PRIu64 "\n",
759                                            thread->GetID(), process->GetID());
760             const bool override_suspend = true;
761             thread->SetResumeState(eStateRunning, override_suspend);
762           } else {
763             thread->SetResumeState(eStateSuspended);
764           }
765         }
766       }
767 
768       StreamString stream;
769       Status error;
770       if (synchronous_execution)
771         error = process->ResumeSynchronous(&stream);
772       else
773         error = process->Resume();
774 
775       // We should not be holding the thread list lock when we do this.
776       if (error.Success()) {
777         result.AppendMessageWithFormat("Process %" PRIu64 " resuming\n",
778                                        process->GetID());
779         if (synchronous_execution) {
780           // If any state changed events had anything to say, add that to the
781           // result
782           if (stream.GetSize() > 0)
783             result.AppendMessage(stream.GetString());
784 
785           result.SetDidChangeProcessState(true);
786           result.SetStatus(eReturnStatusSuccessFinishNoResult);
787         } else {
788           result.SetStatus(eReturnStatusSuccessContinuingNoResult);
789         }
790       } else {
791         result.AppendErrorWithFormat("Failed to resume process: %s\n",
792                                      error.AsCString());
793       }
794     } else {
795       result.AppendErrorWithFormat(
796           "Process cannot be continued from its current state (%s).\n",
797           StateAsCString(state));
798     }
799 
800     return result.Succeeded();
801   }
802 };
803 
804 // CommandObjectThreadUntil
805 
806 #define LLDB_OPTIONS_thread_until
807 #include "CommandOptions.inc"
808 
809 class CommandObjectThreadUntil : public CommandObjectParsed {
810 public:
811   class CommandOptions : public Options {
812   public:
813     uint32_t m_thread_idx = LLDB_INVALID_THREAD_ID;
814     uint32_t m_frame_idx = LLDB_INVALID_FRAME_ID;
815 
816     CommandOptions() {
817       // Keep default values of all options in one place: OptionParsingStarting
818       // ()
819       OptionParsingStarting(nullptr);
820     }
821 
822     ~CommandOptions() override = default;
823 
824     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
825                           ExecutionContext *execution_context) override {
826       Status error;
827       const int short_option = m_getopt_table[option_idx].val;
828 
829       switch (short_option) {
830       case 'a': {
831         lldb::addr_t tmp_addr = OptionArgParser::ToAddress(
832             execution_context, option_arg, LLDB_INVALID_ADDRESS, &error);
833         if (error.Success())
834           m_until_addrs.push_back(tmp_addr);
835       } break;
836       case 't':
837         if (option_arg.getAsInteger(0, m_thread_idx)) {
838           m_thread_idx = LLDB_INVALID_INDEX32;
839           error.SetErrorStringWithFormat("invalid thread index '%s'",
840                                          option_arg.str().c_str());
841         }
842         break;
843       case 'f':
844         if (option_arg.getAsInteger(0, m_frame_idx)) {
845           m_frame_idx = LLDB_INVALID_FRAME_ID;
846           error.SetErrorStringWithFormat("invalid frame index '%s'",
847                                          option_arg.str().c_str());
848         }
849         break;
850       case 'm': {
851         auto enum_values = GetDefinitions()[option_idx].enum_values;
852         lldb::RunMode run_mode = (lldb::RunMode)OptionArgParser::ToOptionEnum(
853             option_arg, enum_values, eOnlyDuringStepping, error);
854 
855         if (error.Success()) {
856           if (run_mode == eAllThreads)
857             m_stop_others = false;
858           else
859             m_stop_others = true;
860         }
861       } break;
862       default:
863         llvm_unreachable("Unimplemented option");
864       }
865       return error;
866     }
867 
868     void OptionParsingStarting(ExecutionContext *execution_context) override {
869       m_thread_idx = LLDB_INVALID_THREAD_ID;
870       m_frame_idx = 0;
871       m_stop_others = false;
872       m_until_addrs.clear();
873     }
874 
875     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
876       return llvm::makeArrayRef(g_thread_until_options);
877     }
878 
879     uint32_t m_step_thread_idx = LLDB_INVALID_THREAD_ID;
880     bool m_stop_others = false;
881     std::vector<lldb::addr_t> m_until_addrs;
882 
883     // Instance variables to hold the values for command options.
884   };
885 
886   CommandObjectThreadUntil(CommandInterpreter &interpreter)
887       : CommandObjectParsed(
888             interpreter, "thread until",
889             "Continue until a line number or address is reached by the "
890             "current or specified thread.  Stops when returning from "
891             "the current function as a safety measure.  "
892             "The target line number(s) are given as arguments, and if more "
893             "than one"
894             " is provided, stepping will stop when the first one is hit.",
895             nullptr,
896             eCommandRequiresThread | eCommandTryTargetAPILock |
897                 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {
898     CommandArgumentEntry arg;
899     CommandArgumentData line_num_arg;
900 
901     // Define the first (and only) variant of this arg.
902     line_num_arg.arg_type = eArgTypeLineNum;
903     line_num_arg.arg_repetition = eArgRepeatPlain;
904 
905     // There is only one variant this argument could be; put it into the
906     // argument entry.
907     arg.push_back(line_num_arg);
908 
909     // Push the data for the first argument into the m_arguments vector.
910     m_arguments.push_back(arg);
911   }
912 
913   ~CommandObjectThreadUntil() override = default;
914 
915   Options *GetOptions() override { return &m_options; }
916 
917 protected:
918   bool DoExecute(Args &command, CommandReturnObject &result) override {
919     bool synchronous_execution = m_interpreter.GetSynchronous();
920 
921     Target *target = &GetSelectedTarget();
922 
923     Process *process = m_exe_ctx.GetProcessPtr();
924     if (process == nullptr) {
925       result.AppendError("need a valid process to step");
926     } else {
927       Thread *thread = nullptr;
928       std::vector<uint32_t> line_numbers;
929 
930       if (command.GetArgumentCount() >= 1) {
931         size_t num_args = command.GetArgumentCount();
932         for (size_t i = 0; i < num_args; i++) {
933           uint32_t line_number;
934           if (!llvm::to_integer(command.GetArgumentAtIndex(i), line_number)) {
935             result.AppendErrorWithFormat("invalid line number: '%s'.\n",
936                                          command.GetArgumentAtIndex(i));
937             return false;
938           } else
939             line_numbers.push_back(line_number);
940         }
941       } else if (m_options.m_until_addrs.empty()) {
942         result.AppendErrorWithFormat("No line number or address provided:\n%s",
943                                      GetSyntax().str().c_str());
944         return false;
945       }
946 
947       if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID) {
948         thread = GetDefaultThread();
949       } else {
950         thread = process->GetThreadList()
951                      .FindThreadByIndexID(m_options.m_thread_idx)
952                      .get();
953       }
954 
955       if (thread == nullptr) {
956         const uint32_t num_threads = process->GetThreadList().GetSize();
957         result.AppendErrorWithFormat(
958             "Thread index %u is out of range (valid values are 0 - %u).\n",
959             m_options.m_thread_idx, num_threads);
960         return false;
961       }
962 
963       const bool abort_other_plans = false;
964 
965       StackFrame *frame =
966           thread->GetStackFrameAtIndex(m_options.m_frame_idx).get();
967       if (frame == nullptr) {
968         result.AppendErrorWithFormat(
969             "Frame index %u is out of range for thread id %" PRIu64 ".\n",
970             m_options.m_frame_idx, thread->GetID());
971         return false;
972       }
973 
974       ThreadPlanSP new_plan_sp;
975       Status new_plan_status;
976 
977       if (frame->HasDebugInformation()) {
978         // Finally we got here...  Translate the given line number to a bunch
979         // of addresses:
980         SymbolContext sc(frame->GetSymbolContext(eSymbolContextCompUnit));
981         LineTable *line_table = nullptr;
982         if (sc.comp_unit)
983           line_table = sc.comp_unit->GetLineTable();
984 
985         if (line_table == nullptr) {
986           result.AppendErrorWithFormat("Failed to resolve the line table for "
987                                        "frame %u of thread id %" PRIu64 ".\n",
988                                        m_options.m_frame_idx, thread->GetID());
989           return false;
990         }
991 
992         LineEntry function_start;
993         uint32_t index_ptr = 0, end_ptr = UINT32_MAX;
994         std::vector<addr_t> address_list;
995 
996         // Find the beginning & end index of the function, but first make
997         // sure it is valid:
998         if (!sc.function) {
999           result.AppendErrorWithFormat("Have debug information but no "
1000                                        "function info - can't get until range.");
1001           return false;
1002         }
1003 
1004         AddressRange fun_addr_range = sc.function->GetAddressRange();
1005         Address fun_start_addr = fun_addr_range.GetBaseAddress();
1006         line_table->FindLineEntryByAddress(fun_start_addr, function_start,
1007                                            &index_ptr);
1008 
1009         Address fun_end_addr(fun_start_addr.GetSection(),
1010                              fun_start_addr.GetOffset() +
1011                                  fun_addr_range.GetByteSize());
1012 
1013         bool all_in_function = true;
1014 
1015         line_table->FindLineEntryByAddress(fun_end_addr, function_start,
1016                                            &end_ptr);
1017 
1018         // Since not all source lines will contribute code, check if we are
1019         // setting the breakpoint on the exact line number or the nearest
1020         // subsequent line number and set breakpoints at all the line table
1021         // entries of the chosen line number (exact or nearest subsequent).
1022         for (uint32_t line_number : line_numbers) {
1023           LineEntry line_entry;
1024           bool exact = false;
1025           uint32_t start_idx_ptr = index_ptr;
1026           start_idx_ptr = sc.comp_unit->FindLineEntry(
1027               index_ptr, line_number, nullptr, exact, &line_entry);
1028           if (start_idx_ptr != UINT32_MAX)
1029             line_number = line_entry.line;
1030           exact = true;
1031           start_idx_ptr = index_ptr;
1032           while (start_idx_ptr <= end_ptr) {
1033             start_idx_ptr = sc.comp_unit->FindLineEntry(
1034                 start_idx_ptr, line_number, nullptr, exact, &line_entry);
1035             if (start_idx_ptr == UINT32_MAX)
1036               break;
1037 
1038             addr_t address =
1039                 line_entry.range.GetBaseAddress().GetLoadAddress(target);
1040             if (address != LLDB_INVALID_ADDRESS) {
1041               if (fun_addr_range.ContainsLoadAddress(address, target))
1042                 address_list.push_back(address);
1043               else
1044                 all_in_function = false;
1045             }
1046             start_idx_ptr++;
1047           }
1048         }
1049 
1050         for (lldb::addr_t address : m_options.m_until_addrs) {
1051           if (fun_addr_range.ContainsLoadAddress(address, target))
1052             address_list.push_back(address);
1053           else
1054             all_in_function = false;
1055         }
1056 
1057         if (address_list.empty()) {
1058           if (all_in_function)
1059             result.AppendErrorWithFormat(
1060                 "No line entries matching until target.\n");
1061           else
1062             result.AppendErrorWithFormat(
1063                 "Until target outside of the current function.\n");
1064 
1065           return false;
1066         }
1067 
1068         new_plan_sp = thread->QueueThreadPlanForStepUntil(
1069             abort_other_plans, &address_list.front(), address_list.size(),
1070             m_options.m_stop_others, m_options.m_frame_idx, new_plan_status);
1071         if (new_plan_sp) {
1072           // User level plans should be controlling plans so they can be
1073           // interrupted
1074           // (e.g. by hitting a breakpoint) and other plans executed by the
1075           // user (stepping around the breakpoint) and then a "continue" will
1076           // resume the original plan.
1077           new_plan_sp->SetIsControllingPlan(true);
1078           new_plan_sp->SetOkayToDiscard(false);
1079         } else {
1080           result.SetError(new_plan_status);
1081           return false;
1082         }
1083       } else {
1084         result.AppendErrorWithFormat("Frame index %u of thread id %" PRIu64
1085                                      " has no debug information.\n",
1086                                      m_options.m_frame_idx, thread->GetID());
1087         return false;
1088       }
1089 
1090       if (!process->GetThreadList().SetSelectedThreadByID(thread->GetID())) {
1091         result.AppendErrorWithFormat(
1092             "Failed to set the selected thread to thread id %" PRIu64 ".\n",
1093             thread->GetID());
1094         return false;
1095       }
1096 
1097       StreamString stream;
1098       Status error;
1099       if (synchronous_execution)
1100         error = process->ResumeSynchronous(&stream);
1101       else
1102         error = process->Resume();
1103 
1104       if (error.Success()) {
1105         result.AppendMessageWithFormat("Process %" PRIu64 " resuming\n",
1106                                        process->GetID());
1107         if (synchronous_execution) {
1108           // If any state changed events had anything to say, add that to the
1109           // result
1110           if (stream.GetSize() > 0)
1111             result.AppendMessage(stream.GetString());
1112 
1113           result.SetDidChangeProcessState(true);
1114           result.SetStatus(eReturnStatusSuccessFinishNoResult);
1115         } else {
1116           result.SetStatus(eReturnStatusSuccessContinuingNoResult);
1117         }
1118       } else {
1119         result.AppendErrorWithFormat("Failed to resume process: %s.\n",
1120                                      error.AsCString());
1121       }
1122     }
1123     return result.Succeeded();
1124   }
1125 
1126   CommandOptions m_options;
1127 };
1128 
1129 // CommandObjectThreadSelect
1130 
1131 class CommandObjectThreadSelect : public CommandObjectParsed {
1132 public:
1133   CommandObjectThreadSelect(CommandInterpreter &interpreter)
1134       : CommandObjectParsed(interpreter, "thread select",
1135                             "Change the currently selected thread.", nullptr,
1136                             eCommandRequiresProcess | eCommandTryTargetAPILock |
1137                                 eCommandProcessMustBeLaunched |
1138                                 eCommandProcessMustBePaused) {
1139     CommandArgumentEntry arg;
1140     CommandArgumentData thread_idx_arg;
1141 
1142     // Define the first (and only) variant of this arg.
1143     thread_idx_arg.arg_type = eArgTypeThreadIndex;
1144     thread_idx_arg.arg_repetition = eArgRepeatPlain;
1145 
1146     // There is only one variant this argument could be; put it into the
1147     // argument entry.
1148     arg.push_back(thread_idx_arg);
1149 
1150     // Push the data for the first argument into the m_arguments vector.
1151     m_arguments.push_back(arg);
1152   }
1153 
1154   ~CommandObjectThreadSelect() override = default;
1155 
1156   void
1157   HandleArgumentCompletion(CompletionRequest &request,
1158                            OptionElementVector &opt_element_vector) override {
1159     if (request.GetCursorIndex())
1160       return;
1161 
1162     CommandCompletions::InvokeCommonCompletionCallbacks(
1163         GetCommandInterpreter(), CommandCompletions::eThreadIndexCompletion,
1164         request, nullptr);
1165   }
1166 
1167 protected:
1168   bool DoExecute(Args &command, CommandReturnObject &result) override {
1169     Process *process = m_exe_ctx.GetProcessPtr();
1170     if (process == nullptr) {
1171       result.AppendError("no process");
1172       return false;
1173     } else if (command.GetArgumentCount() != 1) {
1174       result.AppendErrorWithFormat(
1175           "'%s' takes exactly one thread index argument:\nUsage: %s\n",
1176           m_cmd_name.c_str(), m_cmd_syntax.c_str());
1177       return false;
1178     }
1179 
1180     uint32_t index_id;
1181     if (!llvm::to_integer(command.GetArgumentAtIndex(0), index_id)) {
1182       result.AppendErrorWithFormat("Invalid thread index '%s'",
1183                                    command.GetArgumentAtIndex(0));
1184       return false;
1185     }
1186 
1187     Thread *new_thread =
1188         process->GetThreadList().FindThreadByIndexID(index_id).get();
1189     if (new_thread == nullptr) {
1190       result.AppendErrorWithFormat("invalid thread #%s.\n",
1191                                    command.GetArgumentAtIndex(0));
1192       return false;
1193     }
1194 
1195     process->GetThreadList().SetSelectedThreadByID(new_thread->GetID(), true);
1196     result.SetStatus(eReturnStatusSuccessFinishNoResult);
1197 
1198     return result.Succeeded();
1199   }
1200 };
1201 
1202 // CommandObjectThreadList
1203 
1204 class CommandObjectThreadList : public CommandObjectParsed {
1205 public:
1206   CommandObjectThreadList(CommandInterpreter &interpreter)
1207       : CommandObjectParsed(
1208             interpreter, "thread list",
1209             "Show a summary of each thread in the current target process.  "
1210             "Use 'settings set thread-format' to customize the individual "
1211             "thread listings.",
1212             "thread list",
1213             eCommandRequiresProcess | eCommandTryTargetAPILock |
1214                 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {}
1215 
1216   ~CommandObjectThreadList() override = default;
1217 
1218 protected:
1219   bool DoExecute(Args &command, CommandReturnObject &result) override {
1220     Stream &strm = result.GetOutputStream();
1221     result.SetStatus(eReturnStatusSuccessFinishNoResult);
1222     Process *process = m_exe_ctx.GetProcessPtr();
1223     const bool only_threads_with_stop_reason = false;
1224     const uint32_t start_frame = 0;
1225     const uint32_t num_frames = 0;
1226     const uint32_t num_frames_with_source = 0;
1227     process->GetStatus(strm);
1228     process->GetThreadStatus(strm, only_threads_with_stop_reason, start_frame,
1229                              num_frames, num_frames_with_source, false);
1230     return result.Succeeded();
1231   }
1232 };
1233 
1234 // CommandObjectThreadInfo
1235 #define LLDB_OPTIONS_thread_info
1236 #include "CommandOptions.inc"
1237 
1238 class CommandObjectThreadInfo : public CommandObjectIterateOverThreads {
1239 public:
1240   class CommandOptions : public Options {
1241   public:
1242     CommandOptions() { OptionParsingStarting(nullptr); }
1243 
1244     ~CommandOptions() override = default;
1245 
1246     void OptionParsingStarting(ExecutionContext *execution_context) override {
1247       m_json_thread = false;
1248       m_json_stopinfo = false;
1249     }
1250 
1251     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1252                           ExecutionContext *execution_context) override {
1253       const int short_option = m_getopt_table[option_idx].val;
1254       Status error;
1255 
1256       switch (short_option) {
1257       case 'j':
1258         m_json_thread = true;
1259         break;
1260 
1261       case 's':
1262         m_json_stopinfo = true;
1263         break;
1264 
1265       default:
1266         llvm_unreachable("Unimplemented option");
1267       }
1268       return error;
1269     }
1270 
1271     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1272       return llvm::makeArrayRef(g_thread_info_options);
1273     }
1274 
1275     bool m_json_thread;
1276     bool m_json_stopinfo;
1277   };
1278 
1279   CommandObjectThreadInfo(CommandInterpreter &interpreter)
1280       : CommandObjectIterateOverThreads(
1281             interpreter, "thread info",
1282             "Show an extended summary of one or "
1283             "more threads.  Defaults to the "
1284             "current thread.",
1285             "thread info",
1286             eCommandRequiresProcess | eCommandTryTargetAPILock |
1287                 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {
1288     m_add_return = false;
1289   }
1290 
1291   ~CommandObjectThreadInfo() override = default;
1292 
1293   void
1294   HandleArgumentCompletion(CompletionRequest &request,
1295                            OptionElementVector &opt_element_vector) override {
1296     CommandCompletions::InvokeCommonCompletionCallbacks(
1297         GetCommandInterpreter(), CommandCompletions::eThreadIndexCompletion,
1298         request, nullptr);
1299   }
1300 
1301   Options *GetOptions() override { return &m_options; }
1302 
1303   bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override {
1304     ThreadSP thread_sp =
1305         m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid);
1306     if (!thread_sp) {
1307       result.AppendErrorWithFormat("thread no longer exists: 0x%" PRIx64 "\n",
1308                                    tid);
1309       return false;
1310     }
1311 
1312     Thread *thread = thread_sp.get();
1313 
1314     Stream &strm = result.GetOutputStream();
1315     if (!thread->GetDescription(strm, eDescriptionLevelFull,
1316                                 m_options.m_json_thread,
1317                                 m_options.m_json_stopinfo)) {
1318       result.AppendErrorWithFormat("error displaying info for thread: \"%d\"\n",
1319                                    thread->GetIndexID());
1320       return false;
1321     }
1322     return true;
1323   }
1324 
1325   CommandOptions m_options;
1326 };
1327 
1328 // CommandObjectThreadException
1329 
1330 class CommandObjectThreadException : public CommandObjectIterateOverThreads {
1331 public:
1332   CommandObjectThreadException(CommandInterpreter &interpreter)
1333       : CommandObjectIterateOverThreads(
1334             interpreter, "thread exception",
1335             "Display the current exception object for a thread. Defaults to "
1336             "the current thread.",
1337             "thread exception",
1338             eCommandRequiresProcess | eCommandTryTargetAPILock |
1339                 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {}
1340 
1341   ~CommandObjectThreadException() override = default;
1342 
1343   void
1344   HandleArgumentCompletion(CompletionRequest &request,
1345                            OptionElementVector &opt_element_vector) override {
1346     CommandCompletions::InvokeCommonCompletionCallbacks(
1347         GetCommandInterpreter(), CommandCompletions::eThreadIndexCompletion,
1348         request, nullptr);
1349   }
1350 
1351   bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override {
1352     ThreadSP thread_sp =
1353         m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid);
1354     if (!thread_sp) {
1355       result.AppendErrorWithFormat("thread no longer exists: 0x%" PRIx64 "\n",
1356                                    tid);
1357       return false;
1358     }
1359 
1360     Stream &strm = result.GetOutputStream();
1361     ValueObjectSP exception_object_sp = thread_sp->GetCurrentException();
1362     if (exception_object_sp) {
1363       exception_object_sp->Dump(strm);
1364     }
1365 
1366     ThreadSP exception_thread_sp = thread_sp->GetCurrentExceptionBacktrace();
1367     if (exception_thread_sp && exception_thread_sp->IsValid()) {
1368       const uint32_t num_frames_with_source = 0;
1369       const bool stop_format = false;
1370       exception_thread_sp->GetStatus(strm, 0, UINT32_MAX,
1371                                      num_frames_with_source, stop_format);
1372     }
1373 
1374     return true;
1375   }
1376 };
1377 
1378 class CommandObjectThreadSiginfo : public CommandObjectIterateOverThreads {
1379 public:
1380   CommandObjectThreadSiginfo(CommandInterpreter &interpreter)
1381       : CommandObjectIterateOverThreads(
1382             interpreter, "thread siginfo",
1383             "Display the current siginfo object for a thread. Defaults to "
1384             "the current thread.",
1385             "thread siginfo",
1386             eCommandRequiresProcess | eCommandTryTargetAPILock |
1387                 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {}
1388 
1389   ~CommandObjectThreadSiginfo() override = default;
1390 
1391   void
1392   HandleArgumentCompletion(CompletionRequest &request,
1393                            OptionElementVector &opt_element_vector) override {
1394     CommandCompletions::InvokeCommonCompletionCallbacks(
1395         GetCommandInterpreter(), CommandCompletions::eThreadIndexCompletion,
1396         request, nullptr);
1397   }
1398 
1399   bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override {
1400     ThreadSP thread_sp =
1401         m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid);
1402     if (!thread_sp) {
1403       result.AppendErrorWithFormat("thread no longer exists: 0x%" PRIx64 "\n",
1404                                    tid);
1405       return false;
1406     }
1407 
1408     Stream &strm = result.GetOutputStream();
1409     if (!thread_sp->GetDescription(strm, eDescriptionLevelFull, false, false)) {
1410       result.AppendErrorWithFormat("error displaying info for thread: \"%d\"\n",
1411                                    thread_sp->GetIndexID());
1412       return false;
1413     }
1414     ValueObjectSP exception_object_sp = thread_sp->GetSiginfoValue();
1415     if (exception_object_sp)
1416       exception_object_sp->Dump(strm);
1417     else
1418       strm.Printf("(no siginfo)\n");
1419     strm.PutChar('\n');
1420 
1421     return true;
1422   }
1423 };
1424 
1425 // CommandObjectThreadReturn
1426 #define LLDB_OPTIONS_thread_return
1427 #include "CommandOptions.inc"
1428 
1429 class CommandObjectThreadReturn : public CommandObjectRaw {
1430 public:
1431   class CommandOptions : public Options {
1432   public:
1433     CommandOptions() {
1434       // Keep default values of all options in one place: OptionParsingStarting
1435       // ()
1436       OptionParsingStarting(nullptr);
1437     }
1438 
1439     ~CommandOptions() override = default;
1440 
1441     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1442                           ExecutionContext *execution_context) override {
1443       Status error;
1444       const int short_option = m_getopt_table[option_idx].val;
1445 
1446       switch (short_option) {
1447       case 'x': {
1448         bool success;
1449         bool tmp_value =
1450             OptionArgParser::ToBoolean(option_arg, false, &success);
1451         if (success)
1452           m_from_expression = tmp_value;
1453         else {
1454           error.SetErrorStringWithFormat(
1455               "invalid boolean value '%s' for 'x' option",
1456               option_arg.str().c_str());
1457         }
1458       } break;
1459       default:
1460         llvm_unreachable("Unimplemented option");
1461       }
1462       return error;
1463     }
1464 
1465     void OptionParsingStarting(ExecutionContext *execution_context) override {
1466       m_from_expression = false;
1467     }
1468 
1469     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1470       return llvm::makeArrayRef(g_thread_return_options);
1471     }
1472 
1473     bool m_from_expression = false;
1474 
1475     // Instance variables to hold the values for command options.
1476   };
1477 
1478   CommandObjectThreadReturn(CommandInterpreter &interpreter)
1479       : CommandObjectRaw(interpreter, "thread return",
1480                          "Prematurely return from a stack frame, "
1481                          "short-circuiting execution of newer frames "
1482                          "and optionally yielding a specified value.  Defaults "
1483                          "to the exiting the current stack "
1484                          "frame.",
1485                          "thread return",
1486                          eCommandRequiresFrame | eCommandTryTargetAPILock |
1487                              eCommandProcessMustBeLaunched |
1488                              eCommandProcessMustBePaused) {
1489     CommandArgumentEntry arg;
1490     CommandArgumentData expression_arg;
1491 
1492     // Define the first (and only) variant of this arg.
1493     expression_arg.arg_type = eArgTypeExpression;
1494     expression_arg.arg_repetition = eArgRepeatOptional;
1495 
1496     // There is only one variant this argument could be; put it into the
1497     // argument entry.
1498     arg.push_back(expression_arg);
1499 
1500     // Push the data for the first argument into the m_arguments vector.
1501     m_arguments.push_back(arg);
1502   }
1503 
1504   ~CommandObjectThreadReturn() override = default;
1505 
1506   Options *GetOptions() override { return &m_options; }
1507 
1508 protected:
1509   bool DoExecute(llvm::StringRef command,
1510                  CommandReturnObject &result) override {
1511     // I am going to handle this by hand, because I don't want you to have to
1512     // say:
1513     // "thread return -- -5".
1514     if (command.startswith("-x")) {
1515       if (command.size() != 2U)
1516         result.AppendWarning("Return values ignored when returning from user "
1517                              "called expressions");
1518 
1519       Thread *thread = m_exe_ctx.GetThreadPtr();
1520       Status error;
1521       error = thread->UnwindInnermostExpression();
1522       if (!error.Success()) {
1523         result.AppendErrorWithFormat("Unwinding expression failed - %s.",
1524                                      error.AsCString());
1525       } else {
1526         bool success =
1527             thread->SetSelectedFrameByIndexNoisily(0, result.GetOutputStream());
1528         if (success) {
1529           m_exe_ctx.SetFrameSP(thread->GetSelectedFrame());
1530           result.SetStatus(eReturnStatusSuccessFinishResult);
1531         } else {
1532           result.AppendErrorWithFormat(
1533               "Could not select 0th frame after unwinding expression.");
1534         }
1535       }
1536       return result.Succeeded();
1537     }
1538 
1539     ValueObjectSP return_valobj_sp;
1540 
1541     StackFrameSP frame_sp = m_exe_ctx.GetFrameSP();
1542     uint32_t frame_idx = frame_sp->GetFrameIndex();
1543 
1544     if (frame_sp->IsInlined()) {
1545       result.AppendError("Don't know how to return from inlined frames.");
1546       return false;
1547     }
1548 
1549     if (!command.empty()) {
1550       Target *target = m_exe_ctx.GetTargetPtr();
1551       EvaluateExpressionOptions options;
1552 
1553       options.SetUnwindOnError(true);
1554       options.SetUseDynamic(eNoDynamicValues);
1555 
1556       ExpressionResults exe_results = eExpressionSetupError;
1557       exe_results = target->EvaluateExpression(command, frame_sp.get(),
1558                                                return_valobj_sp, options);
1559       if (exe_results != eExpressionCompleted) {
1560         if (return_valobj_sp)
1561           result.AppendErrorWithFormat(
1562               "Error evaluating result expression: %s",
1563               return_valobj_sp->GetError().AsCString());
1564         else
1565           result.AppendErrorWithFormat(
1566               "Unknown error evaluating result expression.");
1567         return false;
1568       }
1569     }
1570 
1571     Status error;
1572     ThreadSP thread_sp = m_exe_ctx.GetThreadSP();
1573     const bool broadcast = true;
1574     error = thread_sp->ReturnFromFrame(frame_sp, return_valobj_sp, broadcast);
1575     if (!error.Success()) {
1576       result.AppendErrorWithFormat(
1577           "Error returning from frame %d of thread %d: %s.", frame_idx,
1578           thread_sp->GetIndexID(), error.AsCString());
1579       return false;
1580     }
1581 
1582     result.SetStatus(eReturnStatusSuccessFinishResult);
1583     return true;
1584   }
1585 
1586   CommandOptions m_options;
1587 };
1588 
1589 // CommandObjectThreadJump
1590 #define LLDB_OPTIONS_thread_jump
1591 #include "CommandOptions.inc"
1592 
1593 class CommandObjectThreadJump : public CommandObjectParsed {
1594 public:
1595   class CommandOptions : public Options {
1596   public:
1597     CommandOptions() { OptionParsingStarting(nullptr); }
1598 
1599     ~CommandOptions() override = default;
1600 
1601     void OptionParsingStarting(ExecutionContext *execution_context) override {
1602       m_filenames.Clear();
1603       m_line_num = 0;
1604       m_line_offset = 0;
1605       m_load_addr = LLDB_INVALID_ADDRESS;
1606       m_force = false;
1607     }
1608 
1609     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1610                           ExecutionContext *execution_context) override {
1611       const int short_option = m_getopt_table[option_idx].val;
1612       Status error;
1613 
1614       switch (short_option) {
1615       case 'f':
1616         m_filenames.AppendIfUnique(FileSpec(option_arg));
1617         if (m_filenames.GetSize() > 1)
1618           return Status("only one source file expected.");
1619         break;
1620       case 'l':
1621         if (option_arg.getAsInteger(0, m_line_num))
1622           return Status("invalid line number: '%s'.", option_arg.str().c_str());
1623         break;
1624       case 'b':
1625         if (option_arg.getAsInteger(0, m_line_offset))
1626           return Status("invalid line offset: '%s'.", option_arg.str().c_str());
1627         break;
1628       case 'a':
1629         m_load_addr = OptionArgParser::ToAddress(execution_context, option_arg,
1630                                                  LLDB_INVALID_ADDRESS, &error);
1631         break;
1632       case 'r':
1633         m_force = true;
1634         break;
1635       default:
1636         llvm_unreachable("Unimplemented option");
1637       }
1638       return error;
1639     }
1640 
1641     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1642       return llvm::makeArrayRef(g_thread_jump_options);
1643     }
1644 
1645     FileSpecList m_filenames;
1646     uint32_t m_line_num;
1647     int32_t m_line_offset;
1648     lldb::addr_t m_load_addr;
1649     bool m_force;
1650   };
1651 
1652   CommandObjectThreadJump(CommandInterpreter &interpreter)
1653       : CommandObjectParsed(
1654             interpreter, "thread jump",
1655             "Sets the program counter to a new address.", "thread jump",
1656             eCommandRequiresFrame | eCommandTryTargetAPILock |
1657                 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {}
1658 
1659   ~CommandObjectThreadJump() override = default;
1660 
1661   Options *GetOptions() override { return &m_options; }
1662 
1663 protected:
1664   bool DoExecute(Args &args, CommandReturnObject &result) override {
1665     RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext();
1666     StackFrame *frame = m_exe_ctx.GetFramePtr();
1667     Thread *thread = m_exe_ctx.GetThreadPtr();
1668     Target *target = m_exe_ctx.GetTargetPtr();
1669     const SymbolContext &sym_ctx =
1670         frame->GetSymbolContext(eSymbolContextLineEntry);
1671 
1672     if (m_options.m_load_addr != LLDB_INVALID_ADDRESS) {
1673       // Use this address directly.
1674       Address dest = Address(m_options.m_load_addr);
1675 
1676       lldb::addr_t callAddr = dest.GetCallableLoadAddress(target);
1677       if (callAddr == LLDB_INVALID_ADDRESS) {
1678         result.AppendErrorWithFormat("Invalid destination address.");
1679         return false;
1680       }
1681 
1682       if (!reg_ctx->SetPC(callAddr)) {
1683         result.AppendErrorWithFormat("Error changing PC value for thread %d.",
1684                                      thread->GetIndexID());
1685         return false;
1686       }
1687     } else {
1688       // Pick either the absolute line, or work out a relative one.
1689       int32_t line = (int32_t)m_options.m_line_num;
1690       if (line == 0)
1691         line = sym_ctx.line_entry.line + m_options.m_line_offset;
1692 
1693       // Try the current file, but override if asked.
1694       FileSpec file = sym_ctx.line_entry.file;
1695       if (m_options.m_filenames.GetSize() == 1)
1696         file = m_options.m_filenames.GetFileSpecAtIndex(0);
1697 
1698       if (!file) {
1699         result.AppendErrorWithFormat(
1700             "No source file available for the current location.");
1701         return false;
1702       }
1703 
1704       std::string warnings;
1705       Status err = thread->JumpToLine(file, line, m_options.m_force, &warnings);
1706 
1707       if (err.Fail()) {
1708         result.SetError(err);
1709         return false;
1710       }
1711 
1712       if (!warnings.empty())
1713         result.AppendWarning(warnings.c_str());
1714     }
1715 
1716     result.SetStatus(eReturnStatusSuccessFinishResult);
1717     return true;
1718   }
1719 
1720   CommandOptions m_options;
1721 };
1722 
1723 // Next are the subcommands of CommandObjectMultiwordThreadPlan
1724 
1725 // CommandObjectThreadPlanList
1726 #define LLDB_OPTIONS_thread_plan_list
1727 #include "CommandOptions.inc"
1728 
1729 class CommandObjectThreadPlanList : public CommandObjectIterateOverThreads {
1730 public:
1731   class CommandOptions : public Options {
1732   public:
1733     CommandOptions() {
1734       // Keep default values of all options in one place: OptionParsingStarting
1735       // ()
1736       OptionParsingStarting(nullptr);
1737     }
1738 
1739     ~CommandOptions() override = default;
1740 
1741     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1742                           ExecutionContext *execution_context) override {
1743       const int short_option = m_getopt_table[option_idx].val;
1744 
1745       switch (short_option) {
1746       case 'i':
1747         m_internal = true;
1748         break;
1749       case 't':
1750         lldb::tid_t tid;
1751         if (option_arg.getAsInteger(0, tid))
1752           return Status("invalid tid: '%s'.", option_arg.str().c_str());
1753         m_tids.push_back(tid);
1754         break;
1755       case 'u':
1756         m_unreported = false;
1757         break;
1758       case 'v':
1759         m_verbose = true;
1760         break;
1761       default:
1762         llvm_unreachable("Unimplemented option");
1763       }
1764       return {};
1765     }
1766 
1767     void OptionParsingStarting(ExecutionContext *execution_context) override {
1768       m_verbose = false;
1769       m_internal = false;
1770       m_unreported = true; // The variable is "skip unreported" and we want to
1771                            // skip unreported by default.
1772       m_tids.clear();
1773     }
1774 
1775     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1776       return llvm::makeArrayRef(g_thread_plan_list_options);
1777     }
1778 
1779     // Instance variables to hold the values for command options.
1780     bool m_verbose;
1781     bool m_internal;
1782     bool m_unreported;
1783     std::vector<lldb::tid_t> m_tids;
1784   };
1785 
1786   CommandObjectThreadPlanList(CommandInterpreter &interpreter)
1787       : CommandObjectIterateOverThreads(
1788             interpreter, "thread plan list",
1789             "Show thread plans for one or more threads.  If no threads are "
1790             "specified, show the "
1791             "current thread.  Use the thread-index \"all\" to see all threads.",
1792             nullptr,
1793             eCommandRequiresProcess | eCommandRequiresThread |
1794                 eCommandTryTargetAPILock | eCommandProcessMustBeLaunched |
1795                 eCommandProcessMustBePaused) {}
1796 
1797   ~CommandObjectThreadPlanList() override = default;
1798 
1799   Options *GetOptions() override { return &m_options; }
1800 
1801   bool DoExecute(Args &command, CommandReturnObject &result) override {
1802     // If we are reporting all threads, dispatch to the Process to do that:
1803     if (command.GetArgumentCount() == 0 && m_options.m_tids.empty()) {
1804       Stream &strm = result.GetOutputStream();
1805       DescriptionLevel desc_level = m_options.m_verbose
1806                                         ? eDescriptionLevelVerbose
1807                                         : eDescriptionLevelFull;
1808       m_exe_ctx.GetProcessPtr()->DumpThreadPlans(
1809           strm, desc_level, m_options.m_internal, true, m_options.m_unreported);
1810       result.SetStatus(eReturnStatusSuccessFinishResult);
1811       return true;
1812     } else {
1813       // Do any TID's that the user may have specified as TID, then do any
1814       // Thread Indexes...
1815       if (!m_options.m_tids.empty()) {
1816         Process *process = m_exe_ctx.GetProcessPtr();
1817         StreamString tmp_strm;
1818         for (lldb::tid_t tid : m_options.m_tids) {
1819           bool success = process->DumpThreadPlansForTID(
1820               tmp_strm, tid, eDescriptionLevelFull, m_options.m_internal,
1821               true /* condense_trivial */, m_options.m_unreported);
1822           // If we didn't find a TID, stop here and return an error.
1823           if (!success) {
1824             result.AppendError("Error dumping plans:");
1825             result.AppendError(tmp_strm.GetString());
1826             return false;
1827           }
1828           // Otherwise, add our data to the output:
1829           result.GetOutputStream() << tmp_strm.GetString();
1830         }
1831       }
1832       return CommandObjectIterateOverThreads::DoExecute(command, result);
1833     }
1834   }
1835 
1836 protected:
1837   bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override {
1838     // If we have already handled this from a -t option, skip it here.
1839     if (llvm::is_contained(m_options.m_tids, tid))
1840       return true;
1841 
1842     Process *process = m_exe_ctx.GetProcessPtr();
1843 
1844     Stream &strm = result.GetOutputStream();
1845     DescriptionLevel desc_level = eDescriptionLevelFull;
1846     if (m_options.m_verbose)
1847       desc_level = eDescriptionLevelVerbose;
1848 
1849     process->DumpThreadPlansForTID(strm, tid, desc_level, m_options.m_internal,
1850                                    true /* condense_trivial */,
1851                                    m_options.m_unreported);
1852     return true;
1853   }
1854 
1855   CommandOptions m_options;
1856 };
1857 
1858 class CommandObjectThreadPlanDiscard : public CommandObjectParsed {
1859 public:
1860   CommandObjectThreadPlanDiscard(CommandInterpreter &interpreter)
1861       : CommandObjectParsed(interpreter, "thread plan discard",
1862                             "Discards thread plans up to and including the "
1863                             "specified index (see 'thread plan list'.)  "
1864                             "Only user visible plans can be discarded.",
1865                             nullptr,
1866                             eCommandRequiresProcess | eCommandRequiresThread |
1867                                 eCommandTryTargetAPILock |
1868                                 eCommandProcessMustBeLaunched |
1869                                 eCommandProcessMustBePaused) {
1870     CommandArgumentEntry arg;
1871     CommandArgumentData plan_index_arg;
1872 
1873     // Define the first (and only) variant of this arg.
1874     plan_index_arg.arg_type = eArgTypeUnsignedInteger;
1875     plan_index_arg.arg_repetition = eArgRepeatPlain;
1876 
1877     // There is only one variant this argument could be; put it into the
1878     // argument entry.
1879     arg.push_back(plan_index_arg);
1880 
1881     // Push the data for the first argument into the m_arguments vector.
1882     m_arguments.push_back(arg);
1883   }
1884 
1885   ~CommandObjectThreadPlanDiscard() override = default;
1886 
1887   void
1888   HandleArgumentCompletion(CompletionRequest &request,
1889                            OptionElementVector &opt_element_vector) override {
1890     if (!m_exe_ctx.HasThreadScope() || request.GetCursorIndex())
1891       return;
1892 
1893     m_exe_ctx.GetThreadPtr()->AutoCompleteThreadPlans(request);
1894   }
1895 
1896   bool DoExecute(Args &args, CommandReturnObject &result) override {
1897     Thread *thread = m_exe_ctx.GetThreadPtr();
1898     if (args.GetArgumentCount() != 1) {
1899       result.AppendErrorWithFormat("Too many arguments, expected one - the "
1900                                    "thread plan index - but got %zu.",
1901                                    args.GetArgumentCount());
1902       return false;
1903     }
1904 
1905     uint32_t thread_plan_idx;
1906     if (!llvm::to_integer(args.GetArgumentAtIndex(0), thread_plan_idx)) {
1907       result.AppendErrorWithFormat(
1908           "Invalid thread index: \"%s\" - should be unsigned int.",
1909           args.GetArgumentAtIndex(0));
1910       return false;
1911     }
1912 
1913     if (thread_plan_idx == 0) {
1914       result.AppendErrorWithFormat(
1915           "You wouldn't really want me to discard the base thread plan.");
1916       return false;
1917     }
1918 
1919     if (thread->DiscardUserThreadPlansUpToIndex(thread_plan_idx)) {
1920       result.SetStatus(eReturnStatusSuccessFinishNoResult);
1921       return true;
1922     } else {
1923       result.AppendErrorWithFormat(
1924           "Could not find User thread plan with index %s.",
1925           args.GetArgumentAtIndex(0));
1926       return false;
1927     }
1928   }
1929 };
1930 
1931 class CommandObjectThreadPlanPrune : public CommandObjectParsed {
1932 public:
1933   CommandObjectThreadPlanPrune(CommandInterpreter &interpreter)
1934       : CommandObjectParsed(interpreter, "thread plan prune",
1935                             "Removes any thread plans associated with "
1936                             "currently unreported threads.  "
1937                             "Specify one or more TID's to remove, or if no "
1938                             "TID's are provides, remove threads for all "
1939                             "unreported threads",
1940                             nullptr,
1941                             eCommandRequiresProcess |
1942                                 eCommandTryTargetAPILock |
1943                                 eCommandProcessMustBeLaunched |
1944                                 eCommandProcessMustBePaused) {
1945     CommandArgumentEntry arg;
1946     CommandArgumentData tid_arg;
1947 
1948     // Define the first (and only) variant of this arg.
1949     tid_arg.arg_type = eArgTypeThreadID;
1950     tid_arg.arg_repetition = eArgRepeatStar;
1951 
1952     // There is only one variant this argument could be; put it into the
1953     // argument entry.
1954     arg.push_back(tid_arg);
1955 
1956     // Push the data for the first argument into the m_arguments vector.
1957     m_arguments.push_back(arg);
1958   }
1959 
1960   ~CommandObjectThreadPlanPrune() override = default;
1961 
1962   bool DoExecute(Args &args, CommandReturnObject &result) override {
1963     Process *process = m_exe_ctx.GetProcessPtr();
1964 
1965     if (args.GetArgumentCount() == 0) {
1966       process->PruneThreadPlans();
1967       result.SetStatus(eReturnStatusSuccessFinishNoResult);
1968       return true;
1969     }
1970 
1971     const size_t num_args = args.GetArgumentCount();
1972 
1973     std::lock_guard<std::recursive_mutex> guard(
1974         process->GetThreadList().GetMutex());
1975 
1976     for (size_t i = 0; i < num_args; i++) {
1977       lldb::tid_t tid;
1978       if (!llvm::to_integer(args.GetArgumentAtIndex(i), tid)) {
1979         result.AppendErrorWithFormat("invalid thread specification: \"%s\"\n",
1980                                      args.GetArgumentAtIndex(i));
1981         return false;
1982       }
1983       if (!process->PruneThreadPlansForTID(tid)) {
1984         result.AppendErrorWithFormat("Could not find unreported tid: \"%s\"\n",
1985                                      args.GetArgumentAtIndex(i));
1986         return false;
1987       }
1988     }
1989     result.SetStatus(eReturnStatusSuccessFinishNoResult);
1990     return true;
1991   }
1992 };
1993 
1994 // CommandObjectMultiwordThreadPlan
1995 
1996 class CommandObjectMultiwordThreadPlan : public CommandObjectMultiword {
1997 public:
1998   CommandObjectMultiwordThreadPlan(CommandInterpreter &interpreter)
1999       : CommandObjectMultiword(
2000             interpreter, "plan",
2001             "Commands for managing thread plans that control execution.",
2002             "thread plan <subcommand> [<subcommand objects]") {
2003     LoadSubCommand(
2004         "list", CommandObjectSP(new CommandObjectThreadPlanList(interpreter)));
2005     LoadSubCommand(
2006         "discard",
2007         CommandObjectSP(new CommandObjectThreadPlanDiscard(interpreter)));
2008     LoadSubCommand(
2009         "prune",
2010         CommandObjectSP(new CommandObjectThreadPlanPrune(interpreter)));
2011   }
2012 
2013   ~CommandObjectMultiwordThreadPlan() override = default;
2014 };
2015 
2016 // Next are the subcommands of CommandObjectMultiwordTrace
2017 
2018 // CommandObjectTraceExport
2019 
2020 class CommandObjectTraceExport : public CommandObjectMultiword {
2021 public:
2022   CommandObjectTraceExport(CommandInterpreter &interpreter)
2023       : CommandObjectMultiword(
2024             interpreter, "trace thread export",
2025             "Commands for exporting traces of the threads in the current "
2026             "process to different formats.",
2027             "thread trace export <export-plugin> [<subcommand objects>]") {
2028 
2029     unsigned i = 0;
2030     for (llvm::StringRef plugin_name =
2031              PluginManager::GetTraceExporterPluginNameAtIndex(i);
2032          !plugin_name.empty();
2033          plugin_name = PluginManager::GetTraceExporterPluginNameAtIndex(i++)) {
2034       if (ThreadTraceExportCommandCreator command_creator =
2035               PluginManager::GetThreadTraceExportCommandCreatorAtIndex(i)) {
2036         LoadSubCommand(plugin_name, command_creator(interpreter));
2037       }
2038     }
2039   }
2040 };
2041 
2042 // CommandObjectTraceStart
2043 
2044 class CommandObjectTraceStart : public CommandObjectTraceProxy {
2045 public:
2046   CommandObjectTraceStart(CommandInterpreter &interpreter)
2047       : CommandObjectTraceProxy(
2048             /*live_debug_session_only=*/true, interpreter, "thread trace start",
2049             "Start tracing threads with the corresponding trace "
2050             "plug-in for the current process.",
2051             "thread trace start [<trace-options>]") {}
2052 
2053 protected:
2054   lldb::CommandObjectSP GetDelegateCommand(Trace &trace) override {
2055     return trace.GetThreadTraceStartCommand(m_interpreter);
2056   }
2057 };
2058 
2059 // CommandObjectTraceStop
2060 
2061 class CommandObjectTraceStop : public CommandObjectMultipleThreads {
2062 public:
2063   CommandObjectTraceStop(CommandInterpreter &interpreter)
2064       : CommandObjectMultipleThreads(
2065             interpreter, "thread trace stop",
2066             "Stop tracing threads, including the ones traced with the "
2067             "\"process trace start\" command."
2068             "Defaults to the current thread. Thread indices can be "
2069             "specified as arguments.\n Use the thread-index \"all\" to stop "
2070             "tracing "
2071             "for all existing threads.",
2072             "thread trace stop [<thread-index> <thread-index> ...]",
2073             eCommandRequiresProcess | eCommandTryTargetAPILock |
2074                 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused |
2075                 eCommandProcessMustBeTraced) {}
2076 
2077   ~CommandObjectTraceStop() override = default;
2078 
2079   bool DoExecuteOnThreads(Args &command, CommandReturnObject &result,
2080                           llvm::ArrayRef<lldb::tid_t> tids) override {
2081     ProcessSP process_sp = m_exe_ctx.GetProcessSP();
2082 
2083     TraceSP trace_sp = process_sp->GetTarget().GetTrace();
2084 
2085     if (llvm::Error err = trace_sp->Stop(tids))
2086       result.AppendError(toString(std::move(err)));
2087     else
2088       result.SetStatus(eReturnStatusSuccessFinishResult);
2089 
2090     return result.Succeeded();
2091   }
2092 };
2093 
2094 static ThreadSP GetSingleThreadFromArgs(ExecutionContext &exe_ctx, Args &args,
2095                                         CommandReturnObject &result) {
2096   if (args.GetArgumentCount() == 0)
2097     return exe_ctx.GetThreadSP();
2098 
2099   const char *arg = args.GetArgumentAtIndex(0);
2100   uint32_t thread_idx;
2101 
2102   if (!llvm::to_integer(arg, thread_idx)) {
2103     result.AppendErrorWithFormat("invalid thread specification: \"%s\"\n", arg);
2104     return nullptr;
2105   }
2106   ThreadSP thread_sp =
2107       exe_ctx.GetProcessRef().GetThreadList().FindThreadByIndexID(thread_idx);
2108   if (!thread_sp)
2109     result.AppendErrorWithFormat("no thread with index: \"%s\"\n", arg);
2110   return thread_sp;
2111 }
2112 
2113 // CommandObjectTraceDumpFunctionCalls
2114 #define LLDB_OPTIONS_thread_trace_dump_function_calls
2115 #include "CommandOptions.inc"
2116 
2117 class CommandObjectTraceDumpFunctionCalls : public CommandObjectParsed {
2118 public:
2119   class CommandOptions : public Options {
2120   public:
2121     CommandOptions() { OptionParsingStarting(nullptr); }
2122 
2123     ~CommandOptions() override = default;
2124 
2125     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2126                           ExecutionContext *execution_context) override {
2127       Status error;
2128       const int short_option = m_getopt_table[option_idx].val;
2129 
2130       switch (short_option) {
2131       case 'j': {
2132         m_dumper_options.json = true;
2133         break;
2134       }
2135       case 'J': {
2136         m_dumper_options.json = true;
2137         m_dumper_options.pretty_print_json = true;
2138         break;
2139       }
2140       case 'F': {
2141         m_output_file.emplace(option_arg);
2142         break;
2143       }
2144       default:
2145         llvm_unreachable("Unimplemented option");
2146       }
2147       return error;
2148     }
2149 
2150     void OptionParsingStarting(ExecutionContext *execution_context) override {
2151       m_dumper_options = {};
2152       m_output_file = std::nullopt;
2153     }
2154 
2155     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2156       return llvm::makeArrayRef(g_thread_trace_dump_function_calls_options);
2157     }
2158 
2159     static const size_t kDefaultCount = 20;
2160 
2161     // Instance variables to hold the values for command options.
2162     TraceDumperOptions m_dumper_options;
2163     llvm::Optional<FileSpec> m_output_file;
2164   };
2165 
2166   CommandObjectTraceDumpFunctionCalls(CommandInterpreter &interpreter)
2167       : CommandObjectParsed(
2168             interpreter, "thread trace dump function-calls",
2169             "Dump the traced function-calls for one thread. If no "
2170             "thread is specified, the current thread is used.",
2171             nullptr,
2172             eCommandRequiresProcess | eCommandRequiresThread |
2173                 eCommandTryTargetAPILock | eCommandProcessMustBeLaunched |
2174                 eCommandProcessMustBePaused | eCommandProcessMustBeTraced) {
2175     CommandArgumentData thread_arg{eArgTypeThreadIndex, eArgRepeatOptional};
2176     m_arguments.push_back({thread_arg});
2177   }
2178 
2179   ~CommandObjectTraceDumpFunctionCalls() override = default;
2180 
2181   Options *GetOptions() override { return &m_options; }
2182 
2183 protected:
2184   bool DoExecute(Args &args, CommandReturnObject &result) override {
2185     ThreadSP thread_sp = GetSingleThreadFromArgs(m_exe_ctx, args, result);
2186     if (!thread_sp) {
2187       result.AppendError("invalid thread\n");
2188       return false;
2189     }
2190 
2191     llvm::Expected<TraceCursorSP> cursor_or_error =
2192         m_exe_ctx.GetTargetSP()->GetTrace()->CreateNewCursor(*thread_sp);
2193 
2194     if (!cursor_or_error) {
2195       result.AppendError(llvm::toString(cursor_or_error.takeError()));
2196       return false;
2197     }
2198     TraceCursorSP &cursor_sp = *cursor_or_error;
2199 
2200     llvm::Optional<StreamFile> out_file;
2201     if (m_options.m_output_file) {
2202       out_file.emplace(m_options.m_output_file->GetPath().c_str(),
2203                        File::eOpenOptionWriteOnly | File::eOpenOptionCanCreate |
2204                            File::eOpenOptionTruncate);
2205     }
2206 
2207     m_options.m_dumper_options.forwards = true;
2208 
2209     TraceDumper dumper(std::move(cursor_sp),
2210                        out_file ? *out_file : result.GetOutputStream(),
2211                        m_options.m_dumper_options);
2212 
2213     dumper.DumpFunctionCalls();
2214     return true;
2215   }
2216 
2217   CommandOptions m_options;
2218 };
2219 
2220 // CommandObjectTraceDumpInstructions
2221 #define LLDB_OPTIONS_thread_trace_dump_instructions
2222 #include "CommandOptions.inc"
2223 
2224 class CommandObjectTraceDumpInstructions : public CommandObjectParsed {
2225 public:
2226   class CommandOptions : public Options {
2227   public:
2228     CommandOptions() { OptionParsingStarting(nullptr); }
2229 
2230     ~CommandOptions() override = default;
2231 
2232     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2233                           ExecutionContext *execution_context) override {
2234       Status error;
2235       const int short_option = m_getopt_table[option_idx].val;
2236 
2237       switch (short_option) {
2238       case 'c': {
2239         int32_t count;
2240         if (option_arg.empty() || option_arg.getAsInteger(0, count) ||
2241             count < 0)
2242           error.SetErrorStringWithFormat(
2243               "invalid integer value for option '%s'",
2244               option_arg.str().c_str());
2245         else
2246           m_count = count;
2247         break;
2248       }
2249       case 'a': {
2250         m_count = std::numeric_limits<decltype(m_count)>::max();
2251         break;
2252       }
2253       case 's': {
2254         int32_t skip;
2255         if (option_arg.empty() || option_arg.getAsInteger(0, skip) || skip < 0)
2256           error.SetErrorStringWithFormat(
2257               "invalid integer value for option '%s'",
2258               option_arg.str().c_str());
2259         else
2260           m_dumper_options.skip = skip;
2261         break;
2262       }
2263       case 'i': {
2264         uint64_t id;
2265         if (option_arg.empty() || option_arg.getAsInteger(0, id))
2266           error.SetErrorStringWithFormat(
2267               "invalid integer value for option '%s'",
2268               option_arg.str().c_str());
2269         else
2270           m_dumper_options.id = id;
2271         break;
2272       }
2273       case 'F': {
2274         m_output_file.emplace(option_arg);
2275         break;
2276       }
2277       case 'r': {
2278         m_dumper_options.raw = true;
2279         break;
2280       }
2281       case 'f': {
2282         m_dumper_options.forwards = true;
2283         break;
2284       }
2285       case 'k': {
2286         m_dumper_options.show_control_flow_kind = true;
2287         break;
2288       }
2289       case 't': {
2290         m_dumper_options.show_timestamps = true;
2291         break;
2292       }
2293       case 'e': {
2294         m_dumper_options.show_events = true;
2295         break;
2296       }
2297       case 'j': {
2298         m_dumper_options.json = true;
2299         break;
2300       }
2301       case 'J': {
2302         m_dumper_options.pretty_print_json = true;
2303         m_dumper_options.json = true;
2304         break;
2305       }
2306       case 'E': {
2307         m_dumper_options.only_events = true;
2308         m_dumper_options.show_events = true;
2309         break;
2310       }
2311       case 'C': {
2312         m_continue = true;
2313         break;
2314       }
2315       default:
2316         llvm_unreachable("Unimplemented option");
2317       }
2318       return error;
2319     }
2320 
2321     void OptionParsingStarting(ExecutionContext *execution_context) override {
2322       m_count = kDefaultCount;
2323       m_continue = false;
2324       m_output_file = std::nullopt;
2325       m_dumper_options = {};
2326     }
2327 
2328     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2329       return llvm::makeArrayRef(g_thread_trace_dump_instructions_options);
2330     }
2331 
2332     static const size_t kDefaultCount = 20;
2333 
2334     // Instance variables to hold the values for command options.
2335     size_t m_count;
2336     size_t m_continue;
2337     llvm::Optional<FileSpec> m_output_file;
2338     TraceDumperOptions m_dumper_options;
2339   };
2340 
2341   CommandObjectTraceDumpInstructions(CommandInterpreter &interpreter)
2342       : CommandObjectParsed(
2343             interpreter, "thread trace dump instructions",
2344             "Dump the traced instructions for one thread. If no "
2345             "thread is specified, show the current thread.",
2346             nullptr,
2347             eCommandRequiresProcess | eCommandRequiresThread |
2348                 eCommandTryTargetAPILock | eCommandProcessMustBeLaunched |
2349                 eCommandProcessMustBePaused | eCommandProcessMustBeTraced) {
2350     CommandArgumentData thread_arg{eArgTypeThreadIndex, eArgRepeatOptional};
2351     m_arguments.push_back({thread_arg});
2352   }
2353 
2354   ~CommandObjectTraceDumpInstructions() override = default;
2355 
2356   Options *GetOptions() override { return &m_options; }
2357 
2358   llvm::Optional<std::string> GetRepeatCommand(Args &current_command_args,
2359                                                uint32_t index) override {
2360     std::string cmd;
2361     current_command_args.GetCommandString(cmd);
2362     if (cmd.find(" --continue") == std::string::npos)
2363       cmd += " --continue";
2364     return cmd;
2365   }
2366 
2367 protected:
2368   bool DoExecute(Args &args, CommandReturnObject &result) override {
2369     ThreadSP thread_sp = GetSingleThreadFromArgs(m_exe_ctx, args, result);
2370     if (!thread_sp) {
2371       result.AppendError("invalid thread\n");
2372       return false;
2373     }
2374 
2375     if (m_options.m_continue && m_last_id) {
2376       // We set up the options to continue one instruction past where
2377       // the previous iteration stopped.
2378       m_options.m_dumper_options.skip = 1;
2379       m_options.m_dumper_options.id = m_last_id;
2380     }
2381 
2382     llvm::Expected<TraceCursorSP> cursor_or_error =
2383         m_exe_ctx.GetTargetSP()->GetTrace()->CreateNewCursor(*thread_sp);
2384 
2385     if (!cursor_or_error) {
2386       result.AppendError(llvm::toString(cursor_or_error.takeError()));
2387       return false;
2388     }
2389     TraceCursorSP &cursor_sp = *cursor_or_error;
2390 
2391     if (m_options.m_dumper_options.id &&
2392         !cursor_sp->HasId(*m_options.m_dumper_options.id)) {
2393       result.AppendError("invalid instruction id\n");
2394       return false;
2395     }
2396 
2397     llvm::Optional<StreamFile> out_file;
2398     if (m_options.m_output_file) {
2399       out_file.emplace(m_options.m_output_file->GetPath().c_str(),
2400                        File::eOpenOptionWriteOnly | File::eOpenOptionCanCreate |
2401                            File::eOpenOptionTruncate);
2402     }
2403 
2404     if (m_options.m_continue && !m_last_id) {
2405       // We need to stop processing data when we already ran out of instructions
2406       // in a previous command. We can fake this by setting the cursor past the
2407       // end of the trace.
2408       cursor_sp->Seek(1, lldb::eTraceCursorSeekTypeEnd);
2409     }
2410 
2411     TraceDumper dumper(std::move(cursor_sp),
2412                        out_file ? *out_file : result.GetOutputStream(),
2413                        m_options.m_dumper_options);
2414 
2415     m_last_id = dumper.DumpInstructions(m_options.m_count);
2416     return true;
2417   }
2418 
2419   CommandOptions m_options;
2420   // Last traversed id used to continue a repeat command. None means
2421   // that all the trace has been consumed.
2422   llvm::Optional<lldb::user_id_t> m_last_id;
2423 };
2424 
2425 // CommandObjectTraceDumpInfo
2426 #define LLDB_OPTIONS_thread_trace_dump_info
2427 #include "CommandOptions.inc"
2428 
2429 class CommandObjectTraceDumpInfo : public CommandObjectIterateOverThreads {
2430 public:
2431   class CommandOptions : public Options {
2432   public:
2433     CommandOptions() { OptionParsingStarting(nullptr); }
2434 
2435     ~CommandOptions() override = default;
2436 
2437     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2438                           ExecutionContext *execution_context) override {
2439       Status error;
2440       const int short_option = m_getopt_table[option_idx].val;
2441 
2442       switch (short_option) {
2443       case 'v': {
2444         m_verbose = true;
2445         break;
2446       }
2447       case 'j': {
2448         m_json = true;
2449         break;
2450       }
2451       default:
2452         llvm_unreachable("Unimplemented option");
2453       }
2454       return error;
2455     }
2456 
2457     void OptionParsingStarting(ExecutionContext *execution_context) override {
2458       m_verbose = false;
2459       m_json = false;
2460     }
2461 
2462     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2463       return llvm::makeArrayRef(g_thread_trace_dump_info_options);
2464     }
2465 
2466     // Instance variables to hold the values for command options.
2467     bool m_verbose;
2468     bool m_json;
2469   };
2470 
2471   CommandObjectTraceDumpInfo(CommandInterpreter &interpreter)
2472       : CommandObjectIterateOverThreads(
2473             interpreter, "thread trace dump info",
2474             "Dump the traced information for one or more threads.  If no "
2475             "threads are specified, show the current thread. Use the "
2476             "thread-index \"all\" to see all threads.",
2477             nullptr,
2478             eCommandRequiresProcess | eCommandTryTargetAPILock |
2479                 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused |
2480                 eCommandProcessMustBeTraced) {}
2481 
2482   ~CommandObjectTraceDumpInfo() override = default;
2483 
2484   Options *GetOptions() override { return &m_options; }
2485 
2486 protected:
2487   bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override {
2488     const TraceSP &trace_sp = m_exe_ctx.GetTargetSP()->GetTrace();
2489     ThreadSP thread_sp =
2490         m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid);
2491     trace_sp->DumpTraceInfo(*thread_sp, result.GetOutputStream(),
2492                             m_options.m_verbose, m_options.m_json);
2493     return true;
2494   }
2495 
2496   CommandOptions m_options;
2497 };
2498 
2499 // CommandObjectMultiwordTraceDump
2500 class CommandObjectMultiwordTraceDump : public CommandObjectMultiword {
2501 public:
2502   CommandObjectMultiwordTraceDump(CommandInterpreter &interpreter)
2503       : CommandObjectMultiword(
2504             interpreter, "dump",
2505             "Commands for displaying trace information of the threads "
2506             "in the current process.",
2507             "thread trace dump <subcommand> [<subcommand objects>]") {
2508     LoadSubCommand(
2509         "instructions",
2510         CommandObjectSP(new CommandObjectTraceDumpInstructions(interpreter)));
2511     LoadSubCommand(
2512         "function-calls",
2513         CommandObjectSP(new CommandObjectTraceDumpFunctionCalls(interpreter)));
2514     LoadSubCommand(
2515         "info", CommandObjectSP(new CommandObjectTraceDumpInfo(interpreter)));
2516   }
2517   ~CommandObjectMultiwordTraceDump() override = default;
2518 };
2519 
2520 // CommandObjectMultiwordTrace
2521 class CommandObjectMultiwordTrace : public CommandObjectMultiword {
2522 public:
2523   CommandObjectMultiwordTrace(CommandInterpreter &interpreter)
2524       : CommandObjectMultiword(
2525             interpreter, "trace",
2526             "Commands for operating on traces of the threads in the current "
2527             "process.",
2528             "thread trace <subcommand> [<subcommand objects>]") {
2529     LoadSubCommand("dump", CommandObjectSP(new CommandObjectMultiwordTraceDump(
2530                                interpreter)));
2531     LoadSubCommand("start",
2532                    CommandObjectSP(new CommandObjectTraceStart(interpreter)));
2533     LoadSubCommand("stop",
2534                    CommandObjectSP(new CommandObjectTraceStop(interpreter)));
2535     LoadSubCommand("export",
2536                    CommandObjectSP(new CommandObjectTraceExport(interpreter)));
2537   }
2538 
2539   ~CommandObjectMultiwordTrace() override = default;
2540 };
2541 
2542 // CommandObjectMultiwordThread
2543 
2544 CommandObjectMultiwordThread::CommandObjectMultiwordThread(
2545     CommandInterpreter &interpreter)
2546     : CommandObjectMultiword(interpreter, "thread",
2547                              "Commands for operating on "
2548                              "one or more threads in "
2549                              "the current process.",
2550                              "thread <subcommand> [<subcommand-options>]") {
2551   LoadSubCommand("backtrace", CommandObjectSP(new CommandObjectThreadBacktrace(
2552                                   interpreter)));
2553   LoadSubCommand("continue",
2554                  CommandObjectSP(new CommandObjectThreadContinue(interpreter)));
2555   LoadSubCommand("list",
2556                  CommandObjectSP(new CommandObjectThreadList(interpreter)));
2557   LoadSubCommand("return",
2558                  CommandObjectSP(new CommandObjectThreadReturn(interpreter)));
2559   LoadSubCommand("jump",
2560                  CommandObjectSP(new CommandObjectThreadJump(interpreter)));
2561   LoadSubCommand("select",
2562                  CommandObjectSP(new CommandObjectThreadSelect(interpreter)));
2563   LoadSubCommand("until",
2564                  CommandObjectSP(new CommandObjectThreadUntil(interpreter)));
2565   LoadSubCommand("info",
2566                  CommandObjectSP(new CommandObjectThreadInfo(interpreter)));
2567   LoadSubCommand("exception", CommandObjectSP(new CommandObjectThreadException(
2568                                   interpreter)));
2569   LoadSubCommand("siginfo",
2570                  CommandObjectSP(new CommandObjectThreadSiginfo(interpreter)));
2571   LoadSubCommand("step-in",
2572                  CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
2573                      interpreter, "thread step-in",
2574                      "Source level single step, stepping into calls.  Defaults "
2575                      "to current thread unless specified.",
2576                      nullptr, eStepTypeInto, eStepScopeSource)));
2577 
2578   LoadSubCommand("step-out",
2579                  CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
2580                      interpreter, "thread step-out",
2581                      "Finish executing the current stack frame and stop after "
2582                      "returning.  Defaults to current thread unless specified.",
2583                      nullptr, eStepTypeOut, eStepScopeSource)));
2584 
2585   LoadSubCommand("step-over",
2586                  CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
2587                      interpreter, "thread step-over",
2588                      "Source level single step, stepping over calls.  Defaults "
2589                      "to current thread unless specified.",
2590                      nullptr, eStepTypeOver, eStepScopeSource)));
2591 
2592   LoadSubCommand("step-inst",
2593                  CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
2594                      interpreter, "thread step-inst",
2595                      "Instruction level single step, stepping into calls.  "
2596                      "Defaults to current thread unless specified.",
2597                      nullptr, eStepTypeTrace, eStepScopeInstruction)));
2598 
2599   LoadSubCommand("step-inst-over",
2600                  CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
2601                      interpreter, "thread step-inst-over",
2602                      "Instruction level single step, stepping over calls.  "
2603                      "Defaults to current thread unless specified.",
2604                      nullptr, eStepTypeTraceOver, eStepScopeInstruction)));
2605 
2606   LoadSubCommand(
2607       "step-scripted",
2608       CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
2609           interpreter, "thread step-scripted",
2610           "Step as instructed by the script class passed in the -C option.  "
2611           "You can also specify a dictionary of key (-k) and value (-v) pairs "
2612           "that will be used to populate an SBStructuredData Dictionary, which "
2613           "will be passed to the constructor of the class implementing the "
2614           "scripted step.  See the Python Reference for more details.",
2615           nullptr, eStepTypeScripted, eStepScopeSource)));
2616 
2617   LoadSubCommand("plan", CommandObjectSP(new CommandObjectMultiwordThreadPlan(
2618                              interpreter)));
2619   LoadSubCommand("trace",
2620                  CommandObjectSP(new CommandObjectMultiwordTrace(interpreter)));
2621 }
2622 
2623 CommandObjectMultiwordThread::~CommandObjectMultiwordThread() = default;
2624