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