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