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