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