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