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