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