xref: /llvm-project/lldb/source/Commands/CommandObjectThread.cpp (revision 0b69756110db444282c40ea16929186b2910c3b1)
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;
806     uint32_t m_frame_idx;
807 
808     CommandOptions()
809         : Options(), m_thread_idx(LLDB_INVALID_THREAD_ID),
810           m_frame_idx(LLDB_INVALID_FRAME_ID) {
811       // Keep default values of all options in one place: OptionParsingStarting
812       // ()
813       OptionParsingStarting(nullptr);
814     }
815 
816     ~CommandOptions() override = default;
817 
818     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
819                           ExecutionContext *execution_context) override {
820       Status error;
821       const int short_option = m_getopt_table[option_idx].val;
822 
823       switch (short_option) {
824       case 'a': {
825         lldb::addr_t tmp_addr = OptionArgParser::ToAddress(
826             execution_context, option_arg, LLDB_INVALID_ADDRESS, &error);
827         if (error.Success())
828           m_until_addrs.push_back(tmp_addr);
829       } break;
830       case 't':
831         if (option_arg.getAsInteger(0, m_thread_idx)) {
832           m_thread_idx = LLDB_INVALID_INDEX32;
833           error.SetErrorStringWithFormat("invalid thread index '%s'",
834                                          option_arg.str().c_str());
835         }
836         break;
837       case 'f':
838         if (option_arg.getAsInteger(0, m_frame_idx)) {
839           m_frame_idx = LLDB_INVALID_FRAME_ID;
840           error.SetErrorStringWithFormat("invalid frame index '%s'",
841                                          option_arg.str().c_str());
842         }
843         break;
844       case 'm': {
845         auto enum_values = GetDefinitions()[option_idx].enum_values;
846         lldb::RunMode run_mode = (lldb::RunMode)OptionArgParser::ToOptionEnum(
847             option_arg, enum_values, eOnlyDuringStepping, error);
848 
849         if (error.Success()) {
850           if (run_mode == eAllThreads)
851             m_stop_others = false;
852           else
853             m_stop_others = true;
854         }
855       } break;
856       default:
857         llvm_unreachable("Unimplemented option");
858       }
859       return error;
860     }
861 
862     void OptionParsingStarting(ExecutionContext *execution_context) override {
863       m_thread_idx = LLDB_INVALID_THREAD_ID;
864       m_frame_idx = 0;
865       m_stop_others = false;
866       m_until_addrs.clear();
867     }
868 
869     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
870       return llvm::makeArrayRef(g_thread_until_options);
871     }
872 
873     uint32_t m_step_thread_idx;
874     bool m_stop_others;
875     std::vector<lldb::addr_t> m_until_addrs;
876 
877     // Instance variables to hold the values for command options.
878   };
879 
880   CommandObjectThreadUntil(CommandInterpreter &interpreter)
881       : CommandObjectParsed(
882             interpreter, "thread until",
883             "Continue until a line number or address is reached by the "
884             "current or specified thread.  Stops when returning from "
885             "the current function as a safety measure.  "
886             "The target line number(s) are given as arguments, and if more "
887             "than one"
888             " is provided, stepping will stop when the first one is hit.",
889             nullptr,
890             eCommandRequiresThread | eCommandTryTargetAPILock |
891                 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
892         m_options() {
893     CommandArgumentEntry arg;
894     CommandArgumentData line_num_arg;
895 
896     // Define the first (and only) variant of this arg.
897     line_num_arg.arg_type = eArgTypeLineNum;
898     line_num_arg.arg_repetition = eArgRepeatPlain;
899 
900     // There is only one variant this argument could be; put it into the
901     // argument entry.
902     arg.push_back(line_num_arg);
903 
904     // Push the data for the first argument into the m_arguments vector.
905     m_arguments.push_back(arg);
906   }
907 
908   ~CommandObjectThreadUntil() override = default;
909 
910   Options *GetOptions() override { return &m_options; }
911 
912 protected:
913   bool DoExecute(Args &command, CommandReturnObject &result) override {
914     bool synchronous_execution = m_interpreter.GetSynchronous();
915 
916     Target *target = &GetSelectedTarget();
917 
918     Process *process = m_exe_ctx.GetProcessPtr();
919     if (process == nullptr) {
920       result.AppendError("need a valid process to step");
921       result.SetStatus(eReturnStatusFailed);
922     } else {
923       Thread *thread = nullptr;
924       std::vector<uint32_t> line_numbers;
925 
926       if (command.GetArgumentCount() >= 1) {
927         size_t num_args = command.GetArgumentCount();
928         for (size_t i = 0; i < num_args; i++) {
929           uint32_t line_number;
930           if (!llvm::to_integer(command.GetArgumentAtIndex(i), line_number)) {
931             result.AppendErrorWithFormat("invalid line number: '%s'.\n",
932                                          command.GetArgumentAtIndex(i));
933             result.SetStatus(eReturnStatusFailed);
934             return false;
935           } else
936             line_numbers.push_back(line_number);
937         }
938       } else if (m_options.m_until_addrs.empty()) {
939         result.AppendErrorWithFormat("No line number or address provided:\n%s",
940                                      GetSyntax().str().c_str());
941         result.SetStatus(eReturnStatusFailed);
942         return false;
943       }
944 
945       if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID) {
946         thread = GetDefaultThread();
947       } else {
948         thread = process->GetThreadList()
949                      .FindThreadByIndexID(m_options.m_thread_idx)
950                      .get();
951       }
952 
953       if (thread == nullptr) {
954         const uint32_t num_threads = process->GetThreadList().GetSize();
955         result.AppendErrorWithFormat(
956             "Thread index %u is out of range (valid values are 0 - %u).\n",
957             m_options.m_thread_idx, num_threads);
958         result.SetStatus(eReturnStatusFailed);
959         return false;
960       }
961 
962       const bool abort_other_plans = false;
963 
964       StackFrame *frame =
965           thread->GetStackFrameAtIndex(m_options.m_frame_idx).get();
966       if (frame == nullptr) {
967         result.AppendErrorWithFormat(
968             "Frame index %u is out of range for thread %u.\n",
969             m_options.m_frame_idx, m_options.m_thread_idx);
970         result.SetStatus(eReturnStatusFailed);
971         return false;
972       }
973 
974       ThreadPlanSP new_plan_sp;
975       Status new_plan_status;
976 
977       if (frame->HasDebugInformation()) {
978         // Finally we got here...  Translate the given line number to a bunch
979         // of addresses:
980         SymbolContext sc(frame->GetSymbolContext(eSymbolContextCompUnit));
981         LineTable *line_table = nullptr;
982         if (sc.comp_unit)
983           line_table = sc.comp_unit->GetLineTable();
984 
985         if (line_table == nullptr) {
986           result.AppendErrorWithFormat("Failed to resolve the line table for "
987                                        "frame %u of thread index %u.\n",
988                                        m_options.m_frame_idx,
989                                        m_options.m_thread_idx);
990           result.SetStatus(eReturnStatusFailed);
991           return false;
992         }
993 
994         LineEntry function_start;
995         uint32_t index_ptr = 0, end_ptr;
996         std::vector<addr_t> address_list;
997 
998         // Find the beginning & end index of the
999         AddressRange fun_addr_range = sc.function->GetAddressRange();
1000         Address fun_start_addr = fun_addr_range.GetBaseAddress();
1001         line_table->FindLineEntryByAddress(fun_start_addr, function_start,
1002                                            &index_ptr);
1003 
1004         Address fun_end_addr(fun_start_addr.GetSection(),
1005                              fun_start_addr.GetOffset() +
1006                                  fun_addr_range.GetByteSize());
1007 
1008         bool all_in_function = true;
1009 
1010         line_table->FindLineEntryByAddress(fun_end_addr, function_start,
1011                                            &end_ptr);
1012 
1013         for (uint32_t line_number : line_numbers) {
1014           uint32_t start_idx_ptr = index_ptr;
1015           while (start_idx_ptr <= end_ptr) {
1016             LineEntry line_entry;
1017             const bool exact = false;
1018             start_idx_ptr = sc.comp_unit->FindLineEntry(
1019                 start_idx_ptr, line_number, nullptr, exact, &line_entry);
1020             if (start_idx_ptr == UINT32_MAX)
1021               break;
1022 
1023             addr_t address =
1024                 line_entry.range.GetBaseAddress().GetLoadAddress(target);
1025             if (address != LLDB_INVALID_ADDRESS) {
1026               if (fun_addr_range.ContainsLoadAddress(address, target))
1027                 address_list.push_back(address);
1028               else
1029                 all_in_function = false;
1030             }
1031             start_idx_ptr++;
1032           }
1033         }
1034 
1035         for (lldb::addr_t address : m_options.m_until_addrs) {
1036           if (fun_addr_range.ContainsLoadAddress(address, target))
1037             address_list.push_back(address);
1038           else
1039             all_in_function = false;
1040         }
1041 
1042         if (address_list.empty()) {
1043           if (all_in_function)
1044             result.AppendErrorWithFormat(
1045                 "No line entries matching until target.\n");
1046           else
1047             result.AppendErrorWithFormat(
1048                 "Until target outside of the current function.\n");
1049 
1050           result.SetStatus(eReturnStatusFailed);
1051           return false;
1052         }
1053 
1054         new_plan_sp = thread->QueueThreadPlanForStepUntil(
1055             abort_other_plans, &address_list.front(), address_list.size(),
1056             m_options.m_stop_others, m_options.m_frame_idx, new_plan_status);
1057         if (new_plan_sp) {
1058           // User level plans should be master plans so they can be interrupted
1059           // (e.g. by hitting a breakpoint) and other plans executed by the
1060           // user (stepping around the breakpoint) and then a "continue" will
1061           // resume the original plan.
1062           new_plan_sp->SetIsMasterPlan(true);
1063           new_plan_sp->SetOkayToDiscard(false);
1064         } else {
1065           result.SetError(new_plan_status);
1066           result.SetStatus(eReturnStatusFailed);
1067           return false;
1068         }
1069       } else {
1070         result.AppendErrorWithFormat(
1071             "Frame index %u of thread %u has no debug information.\n",
1072             m_options.m_frame_idx, m_options.m_thread_idx);
1073         result.SetStatus(eReturnStatusFailed);
1074         return false;
1075       }
1076 
1077       process->GetThreadList().SetSelectedThreadByID(m_options.m_thread_idx);
1078 
1079       StreamString stream;
1080       Status error;
1081       if (synchronous_execution)
1082         error = process->ResumeSynchronous(&stream);
1083       else
1084         error = process->Resume();
1085 
1086       if (error.Success()) {
1087         result.AppendMessageWithFormat("Process %" PRIu64 " resuming\n",
1088                                        process->GetID());
1089         if (synchronous_execution) {
1090           // If any state changed events had anything to say, add that to the
1091           // result
1092           if (stream.GetSize() > 0)
1093             result.AppendMessage(stream.GetString());
1094 
1095           result.SetDidChangeProcessState(true);
1096           result.SetStatus(eReturnStatusSuccessFinishNoResult);
1097         } else {
1098           result.SetStatus(eReturnStatusSuccessContinuingNoResult);
1099         }
1100       } else {
1101         result.AppendErrorWithFormat("Failed to resume process: %s.\n",
1102                                      error.AsCString());
1103         result.SetStatus(eReturnStatusFailed);
1104       }
1105     }
1106     return result.Succeeded();
1107   }
1108 
1109   CommandOptions m_options;
1110 };
1111 
1112 // CommandObjectThreadSelect
1113 
1114 class CommandObjectThreadSelect : public CommandObjectParsed {
1115 public:
1116   CommandObjectThreadSelect(CommandInterpreter &interpreter)
1117       : CommandObjectParsed(interpreter, "thread select",
1118                             "Change the currently selected thread.", nullptr,
1119                             eCommandRequiresProcess | eCommandTryTargetAPILock |
1120                                 eCommandProcessMustBeLaunched |
1121                                 eCommandProcessMustBePaused) {
1122     CommandArgumentEntry arg;
1123     CommandArgumentData thread_idx_arg;
1124 
1125     // Define the first (and only) variant of this arg.
1126     thread_idx_arg.arg_type = eArgTypeThreadIndex;
1127     thread_idx_arg.arg_repetition = eArgRepeatPlain;
1128 
1129     // There is only one variant this argument could be; put it into the
1130     // argument entry.
1131     arg.push_back(thread_idx_arg);
1132 
1133     // Push the data for the first argument into the m_arguments vector.
1134     m_arguments.push_back(arg);
1135   }
1136 
1137   ~CommandObjectThreadSelect() override = default;
1138 
1139   void
1140   HandleArgumentCompletion(CompletionRequest &request,
1141                            OptionElementVector &opt_element_vector) override {
1142     if (request.GetCursorIndex())
1143       return;
1144 
1145     CommandCompletions::InvokeCommonCompletionCallbacks(
1146         GetCommandInterpreter(), CommandCompletions::eThreadIndexCompletion,
1147         request, nullptr);
1148   }
1149 
1150 protected:
1151   bool DoExecute(Args &command, CommandReturnObject &result) override {
1152     Process *process = m_exe_ctx.GetProcessPtr();
1153     if (process == nullptr) {
1154       result.AppendError("no process");
1155       result.SetStatus(eReturnStatusFailed);
1156       return false;
1157     } else if (command.GetArgumentCount() != 1) {
1158       result.AppendErrorWithFormat(
1159           "'%s' takes exactly one thread index argument:\nUsage: %s\n",
1160           m_cmd_name.c_str(), m_cmd_syntax.c_str());
1161       result.SetStatus(eReturnStatusFailed);
1162       return false;
1163     }
1164 
1165     uint32_t index_id;
1166     if (!llvm::to_integer(command.GetArgumentAtIndex(0), index_id)) {
1167       result.AppendErrorWithFormat("Invalid thread index '%s'",
1168                                    command.GetArgumentAtIndex(0));
1169       result.SetStatus(eReturnStatusFailed);
1170       return false;
1171     }
1172 
1173     Thread *new_thread =
1174         process->GetThreadList().FindThreadByIndexID(index_id).get();
1175     if (new_thread == nullptr) {
1176       result.AppendErrorWithFormat("invalid thread #%s.\n",
1177                                    command.GetArgumentAtIndex(0));
1178       result.SetStatus(eReturnStatusFailed);
1179       return false;
1180     }
1181 
1182     process->GetThreadList().SetSelectedThreadByID(new_thread->GetID(), true);
1183     result.SetStatus(eReturnStatusSuccessFinishNoResult);
1184 
1185     return result.Succeeded();
1186   }
1187 };
1188 
1189 // CommandObjectThreadList
1190 
1191 class CommandObjectThreadList : public CommandObjectParsed {
1192 public:
1193   CommandObjectThreadList(CommandInterpreter &interpreter)
1194       : CommandObjectParsed(
1195             interpreter, "thread list",
1196             "Show a summary of each thread in the current target process.  "
1197             "Use 'settings set thread-format' to customize the individual "
1198             "thread listings.",
1199             "thread list",
1200             eCommandRequiresProcess | eCommandTryTargetAPILock |
1201                 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {}
1202 
1203   ~CommandObjectThreadList() override = default;
1204 
1205 protected:
1206   bool DoExecute(Args &command, CommandReturnObject &result) override {
1207     Stream &strm = result.GetOutputStream();
1208     result.SetStatus(eReturnStatusSuccessFinishNoResult);
1209     Process *process = m_exe_ctx.GetProcessPtr();
1210     const bool only_threads_with_stop_reason = false;
1211     const uint32_t start_frame = 0;
1212     const uint32_t num_frames = 0;
1213     const uint32_t num_frames_with_source = 0;
1214     process->GetStatus(strm);
1215     process->GetThreadStatus(strm, only_threads_with_stop_reason, start_frame,
1216                              num_frames, num_frames_with_source, false);
1217     return result.Succeeded();
1218   }
1219 };
1220 
1221 // CommandObjectThreadInfo
1222 #define LLDB_OPTIONS_thread_info
1223 #include "CommandOptions.inc"
1224 
1225 class CommandObjectThreadInfo : public CommandObjectIterateOverThreads {
1226 public:
1227   class CommandOptions : public Options {
1228   public:
1229     CommandOptions() : Options() { OptionParsingStarting(nullptr); }
1230 
1231     ~CommandOptions() override = default;
1232 
1233     void OptionParsingStarting(ExecutionContext *execution_context) override {
1234       m_json_thread = false;
1235       m_json_stopinfo = false;
1236     }
1237 
1238     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1239                           ExecutionContext *execution_context) override {
1240       const int short_option = m_getopt_table[option_idx].val;
1241       Status error;
1242 
1243       switch (short_option) {
1244       case 'j':
1245         m_json_thread = true;
1246         break;
1247 
1248       case 's':
1249         m_json_stopinfo = true;
1250         break;
1251 
1252       default:
1253         llvm_unreachable("Unimplemented option");
1254       }
1255       return error;
1256     }
1257 
1258     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1259       return llvm::makeArrayRef(g_thread_info_options);
1260     }
1261 
1262     bool m_json_thread;
1263     bool m_json_stopinfo;
1264   };
1265 
1266   CommandObjectThreadInfo(CommandInterpreter &interpreter)
1267       : CommandObjectIterateOverThreads(
1268             interpreter, "thread info",
1269             "Show an extended summary of one or "
1270             "more threads.  Defaults to the "
1271             "current thread.",
1272             "thread info",
1273             eCommandRequiresProcess | eCommandTryTargetAPILock |
1274                 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
1275         m_options() {
1276     m_add_return = false;
1277   }
1278 
1279   ~CommandObjectThreadInfo() override = default;
1280 
1281   void
1282   HandleArgumentCompletion(CompletionRequest &request,
1283                            OptionElementVector &opt_element_vector) override {
1284     CommandCompletions::InvokeCommonCompletionCallbacks(
1285         GetCommandInterpreter(), CommandCompletions::eThreadIndexCompletion,
1286         request, nullptr);
1287   }
1288 
1289   Options *GetOptions() override { return &m_options; }
1290 
1291   bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override {
1292     ThreadSP thread_sp =
1293         m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid);
1294     if (!thread_sp) {
1295       result.AppendErrorWithFormat("thread no longer exists: 0x%" PRIx64 "\n",
1296                                    tid);
1297       result.SetStatus(eReturnStatusFailed);
1298       return false;
1299     }
1300 
1301     Thread *thread = thread_sp.get();
1302 
1303     Stream &strm = result.GetOutputStream();
1304     if (!thread->GetDescription(strm, eDescriptionLevelFull,
1305                                 m_options.m_json_thread,
1306                                 m_options.m_json_stopinfo)) {
1307       result.AppendErrorWithFormat("error displaying info for thread: \"%d\"\n",
1308                                    thread->GetIndexID());
1309       result.SetStatus(eReturnStatusFailed);
1310       return false;
1311     }
1312     return true;
1313   }
1314 
1315   CommandOptions m_options;
1316 };
1317 
1318 // CommandObjectThreadException
1319 
1320 class CommandObjectThreadException : public CommandObjectIterateOverThreads {
1321 public:
1322   CommandObjectThreadException(CommandInterpreter &interpreter)
1323       : CommandObjectIterateOverThreads(
1324             interpreter, "thread exception",
1325             "Display the current exception object for a thread. Defaults to "
1326             "the current thread.",
1327             "thread exception",
1328             eCommandRequiresProcess | eCommandTryTargetAPILock |
1329                 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {}
1330 
1331   ~CommandObjectThreadException() override = default;
1332 
1333   void
1334   HandleArgumentCompletion(CompletionRequest &request,
1335                            OptionElementVector &opt_element_vector) override {
1336     CommandCompletions::InvokeCommonCompletionCallbacks(
1337         GetCommandInterpreter(), CommandCompletions::eThreadIndexCompletion,
1338         request, nullptr);
1339   }
1340 
1341   bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override {
1342     ThreadSP thread_sp =
1343         m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid);
1344     if (!thread_sp) {
1345       result.AppendErrorWithFormat("thread no longer exists: 0x%" PRIx64 "\n",
1346                                    tid);
1347       result.SetStatus(eReturnStatusFailed);
1348       return false;
1349     }
1350 
1351     Stream &strm = result.GetOutputStream();
1352     ValueObjectSP exception_object_sp = thread_sp->GetCurrentException();
1353     if (exception_object_sp) {
1354       exception_object_sp->Dump(strm);
1355     }
1356 
1357     ThreadSP exception_thread_sp = thread_sp->GetCurrentExceptionBacktrace();
1358     if (exception_thread_sp && exception_thread_sp->IsValid()) {
1359       const uint32_t num_frames_with_source = 0;
1360       const bool stop_format = false;
1361       exception_thread_sp->GetStatus(strm, 0, UINT32_MAX,
1362                                      num_frames_with_source, stop_format);
1363     }
1364 
1365     return true;
1366   }
1367 };
1368 
1369 // CommandObjectThreadReturn
1370 #define LLDB_OPTIONS_thread_return
1371 #include "CommandOptions.inc"
1372 
1373 class CommandObjectThreadReturn : public CommandObjectRaw {
1374 public:
1375   class CommandOptions : public Options {
1376   public:
1377     CommandOptions() : Options(), m_from_expression(false) {
1378       // Keep default values of all options in one place: OptionParsingStarting
1379       // ()
1380       OptionParsingStarting(nullptr);
1381     }
1382 
1383     ~CommandOptions() override = default;
1384 
1385     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1386                           ExecutionContext *execution_context) override {
1387       Status error;
1388       const int short_option = m_getopt_table[option_idx].val;
1389 
1390       switch (short_option) {
1391       case 'x': {
1392         bool success;
1393         bool tmp_value =
1394             OptionArgParser::ToBoolean(option_arg, false, &success);
1395         if (success)
1396           m_from_expression = tmp_value;
1397         else {
1398           error.SetErrorStringWithFormat(
1399               "invalid boolean value '%s' for 'x' option",
1400               option_arg.str().c_str());
1401         }
1402       } break;
1403       default:
1404         llvm_unreachable("Unimplemented option");
1405       }
1406       return error;
1407     }
1408 
1409     void OptionParsingStarting(ExecutionContext *execution_context) override {
1410       m_from_expression = false;
1411     }
1412 
1413     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1414       return llvm::makeArrayRef(g_thread_return_options);
1415     }
1416 
1417     bool m_from_expression;
1418 
1419     // Instance variables to hold the values for command options.
1420   };
1421 
1422   CommandObjectThreadReturn(CommandInterpreter &interpreter)
1423       : CommandObjectRaw(interpreter, "thread return",
1424                          "Prematurely return from a stack frame, "
1425                          "short-circuiting execution of newer frames "
1426                          "and optionally yielding a specified value.  Defaults "
1427                          "to the exiting the current stack "
1428                          "frame.",
1429                          "thread return",
1430                          eCommandRequiresFrame | eCommandTryTargetAPILock |
1431                              eCommandProcessMustBeLaunched |
1432                              eCommandProcessMustBePaused),
1433         m_options() {
1434     CommandArgumentEntry arg;
1435     CommandArgumentData expression_arg;
1436 
1437     // Define the first (and only) variant of this arg.
1438     expression_arg.arg_type = eArgTypeExpression;
1439     expression_arg.arg_repetition = eArgRepeatOptional;
1440 
1441     // There is only one variant this argument could be; put it into the
1442     // argument entry.
1443     arg.push_back(expression_arg);
1444 
1445     // Push the data for the first argument into the m_arguments vector.
1446     m_arguments.push_back(arg);
1447   }
1448 
1449   ~CommandObjectThreadReturn() override = default;
1450 
1451   Options *GetOptions() override { return &m_options; }
1452 
1453 protected:
1454   bool DoExecute(llvm::StringRef command,
1455                  CommandReturnObject &result) override {
1456     // I am going to handle this by hand, because I don't want you to have to
1457     // say:
1458     // "thread return -- -5".
1459     if (command.startswith("-x")) {
1460       if (command.size() != 2U)
1461         result.AppendWarning("Return values ignored when returning from user "
1462                              "called expressions");
1463 
1464       Thread *thread = m_exe_ctx.GetThreadPtr();
1465       Status error;
1466       error = thread->UnwindInnermostExpression();
1467       if (!error.Success()) {
1468         result.AppendErrorWithFormat("Unwinding expression failed - %s.",
1469                                      error.AsCString());
1470         result.SetStatus(eReturnStatusFailed);
1471       } else {
1472         bool success =
1473             thread->SetSelectedFrameByIndexNoisily(0, result.GetOutputStream());
1474         if (success) {
1475           m_exe_ctx.SetFrameSP(thread->GetSelectedFrame());
1476           result.SetStatus(eReturnStatusSuccessFinishResult);
1477         } else {
1478           result.AppendErrorWithFormat(
1479               "Could not select 0th frame after unwinding expression.");
1480           result.SetStatus(eReturnStatusFailed);
1481         }
1482       }
1483       return result.Succeeded();
1484     }
1485 
1486     ValueObjectSP return_valobj_sp;
1487 
1488     StackFrameSP frame_sp = m_exe_ctx.GetFrameSP();
1489     uint32_t frame_idx = frame_sp->GetFrameIndex();
1490 
1491     if (frame_sp->IsInlined()) {
1492       result.AppendError("Don't know how to return from inlined frames.");
1493       result.SetStatus(eReturnStatusFailed);
1494       return false;
1495     }
1496 
1497     if (!command.empty()) {
1498       Target *target = m_exe_ctx.GetTargetPtr();
1499       EvaluateExpressionOptions options;
1500 
1501       options.SetUnwindOnError(true);
1502       options.SetUseDynamic(eNoDynamicValues);
1503 
1504       ExpressionResults exe_results = eExpressionSetupError;
1505       exe_results = target->EvaluateExpression(command, frame_sp.get(),
1506                                                return_valobj_sp, options);
1507       if (exe_results != eExpressionCompleted) {
1508         if (return_valobj_sp)
1509           result.AppendErrorWithFormat(
1510               "Error evaluating result expression: %s",
1511               return_valobj_sp->GetError().AsCString());
1512         else
1513           result.AppendErrorWithFormat(
1514               "Unknown error evaluating result expression.");
1515         result.SetStatus(eReturnStatusFailed);
1516         return false;
1517       }
1518     }
1519 
1520     Status error;
1521     ThreadSP thread_sp = m_exe_ctx.GetThreadSP();
1522     const bool broadcast = true;
1523     error = thread_sp->ReturnFromFrame(frame_sp, return_valobj_sp, broadcast);
1524     if (!error.Success()) {
1525       result.AppendErrorWithFormat(
1526           "Error returning from frame %d of thread %d: %s.", frame_idx,
1527           thread_sp->GetIndexID(), error.AsCString());
1528       result.SetStatus(eReturnStatusFailed);
1529       return false;
1530     }
1531 
1532     result.SetStatus(eReturnStatusSuccessFinishResult);
1533     return true;
1534   }
1535 
1536   CommandOptions m_options;
1537 };
1538 
1539 // CommandObjectThreadJump
1540 #define LLDB_OPTIONS_thread_jump
1541 #include "CommandOptions.inc"
1542 
1543 class CommandObjectThreadJump : public CommandObjectParsed {
1544 public:
1545   class CommandOptions : public Options {
1546   public:
1547     CommandOptions() : Options() { OptionParsingStarting(nullptr); }
1548 
1549     ~CommandOptions() override = default;
1550 
1551     void OptionParsingStarting(ExecutionContext *execution_context) override {
1552       m_filenames.Clear();
1553       m_line_num = 0;
1554       m_line_offset = 0;
1555       m_load_addr = LLDB_INVALID_ADDRESS;
1556       m_force = false;
1557     }
1558 
1559     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1560                           ExecutionContext *execution_context) override {
1561       const int short_option = m_getopt_table[option_idx].val;
1562       Status error;
1563 
1564       switch (short_option) {
1565       case 'f':
1566         m_filenames.AppendIfUnique(FileSpec(option_arg));
1567         if (m_filenames.GetSize() > 1)
1568           return Status("only one source file expected.");
1569         break;
1570       case 'l':
1571         if (option_arg.getAsInteger(0, m_line_num))
1572           return Status("invalid line number: '%s'.", option_arg.str().c_str());
1573         break;
1574       case 'b':
1575         if (option_arg.getAsInteger(0, m_line_offset))
1576           return Status("invalid line offset: '%s'.", option_arg.str().c_str());
1577         break;
1578       case 'a':
1579         m_load_addr = OptionArgParser::ToAddress(execution_context, option_arg,
1580                                                  LLDB_INVALID_ADDRESS, &error);
1581         break;
1582       case 'r':
1583         m_force = true;
1584         break;
1585       default:
1586         llvm_unreachable("Unimplemented option");
1587       }
1588       return error;
1589     }
1590 
1591     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1592       return llvm::makeArrayRef(g_thread_jump_options);
1593     }
1594 
1595     FileSpecList m_filenames;
1596     uint32_t m_line_num;
1597     int32_t m_line_offset;
1598     lldb::addr_t m_load_addr;
1599     bool m_force;
1600   };
1601 
1602   CommandObjectThreadJump(CommandInterpreter &interpreter)
1603       : CommandObjectParsed(
1604             interpreter, "thread jump",
1605             "Sets the program counter to a new address.", "thread jump",
1606             eCommandRequiresFrame | eCommandTryTargetAPILock |
1607                 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
1608         m_options() {}
1609 
1610   ~CommandObjectThreadJump() override = default;
1611 
1612   Options *GetOptions() override { return &m_options; }
1613 
1614 protected:
1615   bool DoExecute(Args &args, CommandReturnObject &result) override {
1616     RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext();
1617     StackFrame *frame = m_exe_ctx.GetFramePtr();
1618     Thread *thread = m_exe_ctx.GetThreadPtr();
1619     Target *target = m_exe_ctx.GetTargetPtr();
1620     const SymbolContext &sym_ctx =
1621         frame->GetSymbolContext(eSymbolContextLineEntry);
1622 
1623     if (m_options.m_load_addr != LLDB_INVALID_ADDRESS) {
1624       // Use this address directly.
1625       Address dest = Address(m_options.m_load_addr);
1626 
1627       lldb::addr_t callAddr = dest.GetCallableLoadAddress(target);
1628       if (callAddr == LLDB_INVALID_ADDRESS) {
1629         result.AppendErrorWithFormat("Invalid destination address.");
1630         result.SetStatus(eReturnStatusFailed);
1631         return false;
1632       }
1633 
1634       if (!reg_ctx->SetPC(callAddr)) {
1635         result.AppendErrorWithFormat("Error changing PC value for thread %d.",
1636                                      thread->GetIndexID());
1637         result.SetStatus(eReturnStatusFailed);
1638         return false;
1639       }
1640     } else {
1641       // Pick either the absolute line, or work out a relative one.
1642       int32_t line = (int32_t)m_options.m_line_num;
1643       if (line == 0)
1644         line = sym_ctx.line_entry.line + m_options.m_line_offset;
1645 
1646       // Try the current file, but override if asked.
1647       FileSpec file = sym_ctx.line_entry.file;
1648       if (m_options.m_filenames.GetSize() == 1)
1649         file = m_options.m_filenames.GetFileSpecAtIndex(0);
1650 
1651       if (!file) {
1652         result.AppendErrorWithFormat(
1653             "No source file available for the current location.");
1654         result.SetStatus(eReturnStatusFailed);
1655         return false;
1656       }
1657 
1658       std::string warnings;
1659       Status err = thread->JumpToLine(file, line, m_options.m_force, &warnings);
1660 
1661       if (err.Fail()) {
1662         result.SetError(err);
1663         return false;
1664       }
1665 
1666       if (!warnings.empty())
1667         result.AppendWarning(warnings.c_str());
1668     }
1669 
1670     result.SetStatus(eReturnStatusSuccessFinishResult);
1671     return true;
1672   }
1673 
1674   CommandOptions m_options;
1675 };
1676 
1677 // Next are the subcommands of CommandObjectMultiwordThreadPlan
1678 
1679 // CommandObjectThreadPlanList
1680 #define LLDB_OPTIONS_thread_plan_list
1681 #include "CommandOptions.inc"
1682 
1683 class CommandObjectThreadPlanList : public CommandObjectIterateOverThreads {
1684 public:
1685   class CommandOptions : public Options {
1686   public:
1687     CommandOptions() : Options() {
1688       // Keep default values of all options in one place: OptionParsingStarting
1689       // ()
1690       OptionParsingStarting(nullptr);
1691     }
1692 
1693     ~CommandOptions() override = default;
1694 
1695     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1696                           ExecutionContext *execution_context) override {
1697       const int short_option = m_getopt_table[option_idx].val;
1698 
1699       switch (short_option) {
1700       case 'i':
1701         m_internal = true;
1702         break;
1703       case 't':
1704         lldb::tid_t tid;
1705         if (option_arg.getAsInteger(0, tid))
1706           return Status("invalid tid: '%s'.", option_arg.str().c_str());
1707         m_tids.push_back(tid);
1708         break;
1709       case 'u':
1710         m_unreported = false;
1711         break;
1712       case 'v':
1713         m_verbose = true;
1714         break;
1715       default:
1716         llvm_unreachable("Unimplemented option");
1717       }
1718       return {};
1719     }
1720 
1721     void OptionParsingStarting(ExecutionContext *execution_context) override {
1722       m_verbose = false;
1723       m_internal = false;
1724       m_unreported = true; // The variable is "skip unreported" and we want to
1725                            // skip unreported by default.
1726       m_tids.clear();
1727     }
1728 
1729     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1730       return llvm::makeArrayRef(g_thread_plan_list_options);
1731     }
1732 
1733     // Instance variables to hold the values for command options.
1734     bool m_verbose;
1735     bool m_internal;
1736     bool m_unreported;
1737     std::vector<lldb::tid_t> m_tids;
1738   };
1739 
1740   CommandObjectThreadPlanList(CommandInterpreter &interpreter)
1741       : CommandObjectIterateOverThreads(
1742             interpreter, "thread plan list",
1743             "Show thread plans for one or more threads.  If no threads are "
1744             "specified, show the "
1745             "current thread.  Use the thread-index \"all\" to see all threads.",
1746             nullptr,
1747             eCommandRequiresProcess | eCommandRequiresThread |
1748                 eCommandTryTargetAPILock | eCommandProcessMustBeLaunched |
1749                 eCommandProcessMustBePaused),
1750         m_options() {}
1751 
1752   ~CommandObjectThreadPlanList() override = default;
1753 
1754   Options *GetOptions() override { return &m_options; }
1755 
1756   bool DoExecute(Args &command, CommandReturnObject &result) override {
1757     // If we are reporting all threads, dispatch to the Process to do that:
1758     if (command.GetArgumentCount() == 0 && m_options.m_tids.empty()) {
1759       Stream &strm = result.GetOutputStream();
1760       DescriptionLevel desc_level = m_options.m_verbose
1761                                         ? eDescriptionLevelVerbose
1762                                         : eDescriptionLevelFull;
1763       m_exe_ctx.GetProcessPtr()->DumpThreadPlans(
1764           strm, desc_level, m_options.m_internal, true, m_options.m_unreported);
1765       result.SetStatus(eReturnStatusSuccessFinishResult);
1766       return true;
1767     } else {
1768       // Do any TID's that the user may have specified as TID, then do any
1769       // Thread Indexes...
1770       if (!m_options.m_tids.empty()) {
1771         Process *process = m_exe_ctx.GetProcessPtr();
1772         StreamString tmp_strm;
1773         for (lldb::tid_t tid : m_options.m_tids) {
1774           bool success = process->DumpThreadPlansForTID(
1775               tmp_strm, tid, eDescriptionLevelFull, m_options.m_internal,
1776               true /* condense_trivial */, m_options.m_unreported);
1777           // If we didn't find a TID, stop here and return an error.
1778           if (!success) {
1779             result.SetError("Error dumping plans:");
1780             result.AppendError(tmp_strm.GetString());
1781             result.SetStatus(eReturnStatusFailed);
1782             return false;
1783           }
1784           // Otherwise, add our data to the output:
1785           result.GetOutputStream() << tmp_strm.GetString();
1786         }
1787       }
1788       return CommandObjectIterateOverThreads::DoExecute(command, result);
1789     }
1790   }
1791 
1792 protected:
1793   bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override {
1794     // If we have already handled this from a -t option, skip it here.
1795     if (llvm::is_contained(m_options.m_tids, tid))
1796       return true;
1797 
1798     Process *process = m_exe_ctx.GetProcessPtr();
1799 
1800     Stream &strm = result.GetOutputStream();
1801     DescriptionLevel desc_level = eDescriptionLevelFull;
1802     if (m_options.m_verbose)
1803       desc_level = eDescriptionLevelVerbose;
1804 
1805     process->DumpThreadPlansForTID(strm, tid, desc_level, m_options.m_internal,
1806                                    true /* condense_trivial */,
1807                                    m_options.m_unreported);
1808     return true;
1809   }
1810 
1811   CommandOptions m_options;
1812 };
1813 
1814 class CommandObjectThreadPlanDiscard : public CommandObjectParsed {
1815 public:
1816   CommandObjectThreadPlanDiscard(CommandInterpreter &interpreter)
1817       : CommandObjectParsed(interpreter, "thread plan discard",
1818                             "Discards thread plans up to and including the "
1819                             "specified index (see 'thread plan list'.)  "
1820                             "Only user visible plans can be discarded.",
1821                             nullptr,
1822                             eCommandRequiresProcess | eCommandRequiresThread |
1823                                 eCommandTryTargetAPILock |
1824                                 eCommandProcessMustBeLaunched |
1825                                 eCommandProcessMustBePaused) {
1826     CommandArgumentEntry arg;
1827     CommandArgumentData plan_index_arg;
1828 
1829     // Define the first (and only) variant of this arg.
1830     plan_index_arg.arg_type = eArgTypeUnsignedInteger;
1831     plan_index_arg.arg_repetition = eArgRepeatPlain;
1832 
1833     // There is only one variant this argument could be; put it into the
1834     // argument entry.
1835     arg.push_back(plan_index_arg);
1836 
1837     // Push the data for the first argument into the m_arguments vector.
1838     m_arguments.push_back(arg);
1839   }
1840 
1841   ~CommandObjectThreadPlanDiscard() override = default;
1842 
1843   void
1844   HandleArgumentCompletion(CompletionRequest &request,
1845                            OptionElementVector &opt_element_vector) override {
1846     if (!m_exe_ctx.HasThreadScope() || request.GetCursorIndex())
1847       return;
1848 
1849     m_exe_ctx.GetThreadPtr()->AutoCompleteThreadPlans(request);
1850   }
1851 
1852   bool DoExecute(Args &args, CommandReturnObject &result) override {
1853     Thread *thread = m_exe_ctx.GetThreadPtr();
1854     if (args.GetArgumentCount() != 1) {
1855       result.AppendErrorWithFormat("Too many arguments, expected one - the "
1856                                    "thread plan index - but got %zu.",
1857                                    args.GetArgumentCount());
1858       result.SetStatus(eReturnStatusFailed);
1859       return false;
1860     }
1861 
1862     uint32_t thread_plan_idx;
1863     if (!llvm::to_integer(args.GetArgumentAtIndex(0), thread_plan_idx)) {
1864       result.AppendErrorWithFormat(
1865           "Invalid thread index: \"%s\" - should be unsigned int.",
1866           args.GetArgumentAtIndex(0));
1867       result.SetStatus(eReturnStatusFailed);
1868       return false;
1869     }
1870 
1871     if (thread_plan_idx == 0) {
1872       result.AppendErrorWithFormat(
1873           "You wouldn't really want me to discard the base thread plan.");
1874       result.SetStatus(eReturnStatusFailed);
1875       return false;
1876     }
1877 
1878     if (thread->DiscardUserThreadPlansUpToIndex(thread_plan_idx)) {
1879       result.SetStatus(eReturnStatusSuccessFinishNoResult);
1880       return true;
1881     } else {
1882       result.AppendErrorWithFormat(
1883           "Could not find User thread plan with index %s.",
1884           args.GetArgumentAtIndex(0));
1885       result.SetStatus(eReturnStatusFailed);
1886       return false;
1887     }
1888   }
1889 };
1890 
1891 class CommandObjectThreadPlanPrune : public CommandObjectParsed {
1892 public:
1893   CommandObjectThreadPlanPrune(CommandInterpreter &interpreter)
1894       : CommandObjectParsed(interpreter, "thread plan prune",
1895                             "Removes any thread plans associated with "
1896                             "currently unreported threads.  "
1897                             "Specify one or more TID's to remove, or if no "
1898                             "TID's are provides, remove threads for all "
1899                             "unreported threads",
1900                             nullptr,
1901                             eCommandRequiresProcess |
1902                                 eCommandTryTargetAPILock |
1903                                 eCommandProcessMustBeLaunched |
1904                                 eCommandProcessMustBePaused) {
1905     CommandArgumentEntry arg;
1906     CommandArgumentData tid_arg;
1907 
1908     // Define the first (and only) variant of this arg.
1909     tid_arg.arg_type = eArgTypeThreadID;
1910     tid_arg.arg_repetition = eArgRepeatStar;
1911 
1912     // There is only one variant this argument could be; put it into the
1913     // argument entry.
1914     arg.push_back(tid_arg);
1915 
1916     // Push the data for the first argument into the m_arguments vector.
1917     m_arguments.push_back(arg);
1918   }
1919 
1920   ~CommandObjectThreadPlanPrune() override = default;
1921 
1922   bool DoExecute(Args &args, CommandReturnObject &result) override {
1923     Process *process = m_exe_ctx.GetProcessPtr();
1924 
1925     if (args.GetArgumentCount() == 0) {
1926       process->PruneThreadPlans();
1927       result.SetStatus(eReturnStatusSuccessFinishNoResult);
1928       return true;
1929     }
1930 
1931     const size_t num_args = args.GetArgumentCount();
1932 
1933     std::lock_guard<std::recursive_mutex> guard(
1934         process->GetThreadList().GetMutex());
1935 
1936     for (size_t i = 0; i < num_args; i++) {
1937       lldb::tid_t tid;
1938       if (!llvm::to_integer(args.GetArgumentAtIndex(i), tid)) {
1939         result.AppendErrorWithFormat("invalid thread specification: \"%s\"\n",
1940                                      args.GetArgumentAtIndex(i));
1941         result.SetStatus(eReturnStatusFailed);
1942         return false;
1943       }
1944       if (!process->PruneThreadPlansForTID(tid)) {
1945         result.AppendErrorWithFormat("Could not find unreported tid: \"%s\"\n",
1946                                      args.GetArgumentAtIndex(i));
1947         result.SetStatus(eReturnStatusFailed);
1948         return false;
1949       }
1950     }
1951     result.SetStatus(eReturnStatusSuccessFinishNoResult);
1952     return true;
1953   }
1954 };
1955 
1956 // CommandObjectMultiwordThreadPlan
1957 
1958 class CommandObjectMultiwordThreadPlan : public CommandObjectMultiword {
1959 public:
1960   CommandObjectMultiwordThreadPlan(CommandInterpreter &interpreter)
1961       : CommandObjectMultiword(
1962             interpreter, "plan",
1963             "Commands for managing thread plans that control execution.",
1964             "thread plan <subcommand> [<subcommand objects]") {
1965     LoadSubCommand(
1966         "list", CommandObjectSP(new CommandObjectThreadPlanList(interpreter)));
1967     LoadSubCommand(
1968         "discard",
1969         CommandObjectSP(new CommandObjectThreadPlanDiscard(interpreter)));
1970     LoadSubCommand(
1971         "prune",
1972         CommandObjectSP(new CommandObjectThreadPlanPrune(interpreter)));
1973   }
1974 
1975   ~CommandObjectMultiwordThreadPlan() override = default;
1976 };
1977 
1978 // Next are the subcommands of CommandObjectMultiwordTrace
1979 
1980 // CommandObjectTraceStart
1981 
1982 class CommandObjectTraceStart : public CommandObjectTraceProxy {
1983 public:
1984   CommandObjectTraceStart(CommandInterpreter &interpreter)
1985       : CommandObjectTraceProxy(
1986             /*live_debug_session_only*/ true, interpreter, "thread trace start",
1987             "Start tracing threads with the corresponding trace "
1988             "plug-in for the current process.",
1989             "thread trace start [<trace-options>]") {}
1990 
1991 protected:
1992   lldb::CommandObjectSP GetDelegateCommand(Trace &trace) override {
1993     return trace.GetThreadTraceStartCommand(m_interpreter);
1994   }
1995 };
1996 
1997 // CommandObjectTraceStop
1998 
1999 class CommandObjectTraceStop : public CommandObjectMultipleThreads {
2000 public:
2001   CommandObjectTraceStop(CommandInterpreter &interpreter)
2002       : CommandObjectMultipleThreads(
2003             interpreter, "thread trace stop",
2004             "Stop tracing threads, including the ones traced with the "
2005             "\"process trace start\" command."
2006             "Defaults to the current thread. Thread indices can be "
2007             "specified as arguments.\n Use the thread-index \"all\" to stop "
2008             "tracing "
2009             "for all existing threads.",
2010             "thread trace stop [<thread-index> <thread-index> ...]",
2011             eCommandRequiresProcess | eCommandTryTargetAPILock |
2012                 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused |
2013                 eCommandProcessMustBeTraced) {}
2014 
2015   ~CommandObjectTraceStop() override = default;
2016 
2017   bool DoExecuteOnThreads(Args &command, CommandReturnObject &result,
2018                           const std::vector<lldb::tid_t> &tids) override {
2019     ProcessSP process_sp = m_exe_ctx.GetProcessSP();
2020 
2021     TraceSP trace_sp = process_sp->GetTarget().GetTrace();
2022 
2023     if (llvm::Error err = trace_sp->StopThreads(tids))
2024       result.SetError(toString(std::move(err)));
2025     else
2026       result.SetStatus(eReturnStatusSuccessFinishResult);
2027 
2028     return result.Succeeded();
2029   }
2030 };
2031 
2032 // CommandObjectTraceDumpInstructions
2033 #define LLDB_OPTIONS_thread_trace_dump_instructions
2034 #include "CommandOptions.inc"
2035 
2036 class CommandObjectTraceDumpInstructions
2037     : public CommandObjectIterateOverThreads {
2038 public:
2039   class CommandOptions : public Options {
2040   public:
2041     CommandOptions() : Options() { OptionParsingStarting(nullptr); }
2042 
2043     ~CommandOptions() override = default;
2044 
2045     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2046                           ExecutionContext *execution_context) override {
2047       Status error;
2048       const int short_option = m_getopt_table[option_idx].val;
2049 
2050       switch (short_option) {
2051       case 'c': {
2052         int32_t count;
2053         if (option_arg.empty() || option_arg.getAsInteger(0, count) ||
2054             count < 0)
2055           error.SetErrorStringWithFormat(
2056               "invalid integer value for option '%s'",
2057               option_arg.str().c_str());
2058         else
2059           m_count = count;
2060         break;
2061       }
2062       case 'p': {
2063         int32_t position;
2064         if (option_arg.empty() || option_arg.getAsInteger(0, position) ||
2065             position < 0)
2066           error.SetErrorStringWithFormat(
2067               "invalid integer value for option '%s'",
2068               option_arg.str().c_str());
2069         else
2070           m_position = position;
2071         break;
2072       }
2073       case 'r': {
2074         m_raw = true;
2075         break;
2076       }
2077       default:
2078         llvm_unreachable("Unimplemented option");
2079       }
2080       return error;
2081     }
2082 
2083     void OptionParsingStarting(ExecutionContext *execution_context) override {
2084       m_count = kDefaultCount;
2085       m_position = llvm::None;
2086       m_raw = false;
2087     }
2088 
2089     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2090       return llvm::makeArrayRef(g_thread_trace_dump_instructions_options);
2091     }
2092 
2093     static const size_t kDefaultCount = 20;
2094 
2095     // Instance variables to hold the values for command options.
2096     size_t m_count;
2097     llvm::Optional<ssize_t> m_position;
2098     bool m_raw;
2099   };
2100 
2101   CommandObjectTraceDumpInstructions(CommandInterpreter &interpreter)
2102       : CommandObjectIterateOverThreads(
2103             interpreter, "thread trace dump instructions",
2104             "Dump the traced instructions for one or more threads.  If no "
2105             "threads are specified, show the current thread.  Use the "
2106             "thread-index \"all\" to see all threads.",
2107             nullptr,
2108             eCommandRequiresProcess | eCommandTryTargetAPILock |
2109                 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused |
2110                 eCommandProcessMustBeTraced),
2111         m_options(), m_create_repeat_command_just_invoked(false) {}
2112 
2113   ~CommandObjectTraceDumpInstructions() override = default;
2114 
2115   Options *GetOptions() override { return &m_options; }
2116 
2117   const char *GetRepeatCommand(Args &current_command_args,
2118                                uint32_t index) override {
2119     current_command_args.GetCommandString(m_repeat_command);
2120     m_create_repeat_command_just_invoked = true;
2121     m_consecutive_repetitions = 0;
2122     return m_repeat_command.c_str();
2123   }
2124 
2125 protected:
2126   bool DoExecute(Args &args, CommandReturnObject &result) override {
2127     if (IsRepeatCommand())
2128       m_consecutive_repetitions++;
2129     bool status = CommandObjectIterateOverThreads::DoExecute(args, result);
2130 
2131     m_create_repeat_command_just_invoked = false;
2132     return status;
2133   }
2134 
2135   bool IsRepeatCommand() {
2136     return !m_repeat_command.empty() && !m_create_repeat_command_just_invoked;
2137   }
2138 
2139   bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override {
2140     const TraceSP &trace_sp = m_exe_ctx.GetTargetSP()->GetTrace();
2141     ThreadSP thread_sp =
2142         m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid);
2143 
2144     size_t count = m_options.m_count;
2145     ssize_t position = m_options.m_position.getValueOr(
2146                            trace_sp->GetCursorPosition(*thread_sp)) -
2147                        m_consecutive_repetitions * count;
2148     if (position < 0)
2149       result.SetError("error: no more data");
2150     else
2151       trace_sp->DumpTraceInstructions(*thread_sp, result.GetOutputStream(),
2152                                       count, position, m_options.m_raw);
2153     return true;
2154   }
2155 
2156   CommandOptions m_options;
2157 
2158   // Repeat command helpers
2159   std::string m_repeat_command;
2160   bool m_create_repeat_command_just_invoked;
2161   size_t m_consecutive_repetitions = 0;
2162 };
2163 
2164 // CommandObjectMultiwordTraceDump
2165 class CommandObjectMultiwordTraceDump : public CommandObjectMultiword {
2166 public:
2167   CommandObjectMultiwordTraceDump(CommandInterpreter &interpreter)
2168       : CommandObjectMultiword(
2169             interpreter, "dump",
2170             "Commands for displaying trace information of the threads "
2171             "in the current process.",
2172             "thread trace dump <subcommand> [<subcommand objects>]") {
2173     LoadSubCommand(
2174         "instructions",
2175         CommandObjectSP(new CommandObjectTraceDumpInstructions(interpreter)));
2176   }
2177   ~CommandObjectMultiwordTraceDump() override = default;
2178 };
2179 
2180 // CommandObjectMultiwordTrace
2181 class CommandObjectMultiwordTrace : public CommandObjectMultiword {
2182 public:
2183   CommandObjectMultiwordTrace(CommandInterpreter &interpreter)
2184       : CommandObjectMultiword(
2185             interpreter, "trace",
2186             "Commands for operating on traces of the threads in the current "
2187             "process.",
2188             "thread trace <subcommand> [<subcommand objects>]") {
2189     LoadSubCommand("dump", CommandObjectSP(new CommandObjectMultiwordTraceDump(
2190                                interpreter)));
2191     LoadSubCommand("start",
2192                    CommandObjectSP(new CommandObjectTraceStart(interpreter)));
2193     LoadSubCommand("stop",
2194                    CommandObjectSP(new CommandObjectTraceStop(interpreter)));
2195   }
2196 
2197   ~CommandObjectMultiwordTrace() override = default;
2198 };
2199 
2200 // CommandObjectMultiwordThread
2201 
2202 CommandObjectMultiwordThread::CommandObjectMultiwordThread(
2203     CommandInterpreter &interpreter)
2204     : CommandObjectMultiword(interpreter, "thread",
2205                              "Commands for operating on "
2206                              "one or more threads in "
2207                              "the current process.",
2208                              "thread <subcommand> [<subcommand-options>]") {
2209   LoadSubCommand("backtrace", CommandObjectSP(new CommandObjectThreadBacktrace(
2210                                   interpreter)));
2211   LoadSubCommand("continue",
2212                  CommandObjectSP(new CommandObjectThreadContinue(interpreter)));
2213   LoadSubCommand("list",
2214                  CommandObjectSP(new CommandObjectThreadList(interpreter)));
2215   LoadSubCommand("return",
2216                  CommandObjectSP(new CommandObjectThreadReturn(interpreter)));
2217   LoadSubCommand("jump",
2218                  CommandObjectSP(new CommandObjectThreadJump(interpreter)));
2219   LoadSubCommand("select",
2220                  CommandObjectSP(new CommandObjectThreadSelect(interpreter)));
2221   LoadSubCommand("until",
2222                  CommandObjectSP(new CommandObjectThreadUntil(interpreter)));
2223   LoadSubCommand("info",
2224                  CommandObjectSP(new CommandObjectThreadInfo(interpreter)));
2225   LoadSubCommand("exception", CommandObjectSP(new CommandObjectThreadException(
2226                                   interpreter)));
2227   LoadSubCommand("step-in",
2228                  CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
2229                      interpreter, "thread step-in",
2230                      "Source level single step, stepping into calls.  Defaults "
2231                      "to current thread unless specified.",
2232                      nullptr, eStepTypeInto, eStepScopeSource)));
2233 
2234   LoadSubCommand("step-out",
2235                  CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
2236                      interpreter, "thread step-out",
2237                      "Finish executing the current stack frame and stop after "
2238                      "returning.  Defaults to current thread unless specified.",
2239                      nullptr, eStepTypeOut, eStepScopeSource)));
2240 
2241   LoadSubCommand("step-over",
2242                  CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
2243                      interpreter, "thread step-over",
2244                      "Source level single step, stepping over calls.  Defaults "
2245                      "to current thread unless specified.",
2246                      nullptr, eStepTypeOver, eStepScopeSource)));
2247 
2248   LoadSubCommand("step-inst",
2249                  CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
2250                      interpreter, "thread step-inst",
2251                      "Instruction level single step, stepping into calls.  "
2252                      "Defaults to current thread unless specified.",
2253                      nullptr, eStepTypeTrace, eStepScopeInstruction)));
2254 
2255   LoadSubCommand("step-inst-over",
2256                  CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
2257                      interpreter, "thread step-inst-over",
2258                      "Instruction level single step, stepping over calls.  "
2259                      "Defaults to current thread unless specified.",
2260                      nullptr, eStepTypeTraceOver, eStepScopeInstruction)));
2261 
2262   LoadSubCommand(
2263       "step-scripted",
2264       CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
2265           interpreter, "thread step-scripted",
2266           "Step as instructed by the script class passed in the -C option.  "
2267           "You can also specify a dictionary of key (-k) and value (-v) pairs "
2268           "that will be used to populate an SBStructuredData Dictionary, which "
2269           "will be passed to the constructor of the class implementing the "
2270           "scripted step.  See the Python Reference for more details.",
2271           nullptr, eStepTypeScripted, eStepScopeSource)));
2272 
2273   LoadSubCommand("plan", CommandObjectSP(new CommandObjectMultiwordThreadPlan(
2274                              interpreter)));
2275   LoadSubCommand("trace",
2276                  CommandObjectSP(new CommandObjectMultiwordTrace(interpreter)));
2277 }
2278 
2279 CommandObjectMultiwordThread::~CommandObjectMultiwordThread() = default;
2280