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