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