]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Commands/CommandObjectThread.cpp
Merge ^/head r327169 through r327340.
[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 (!thread || !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       if (!error.Success()) {
779         result.AppendMessage(error.AsCString());
780         result.SetStatus(eReturnStatusFailed);
781         return false;
782       }
783
784       // There is a race condition where this thread will return up the call
785       // stack to the main command handler
786       // and show an (lldb) prompt before HandlePrivateEvent (from
787       // PrivateStateThread) has
788       // a chance to call PushProcessIOHandler().
789       process->SyncIOHandler(iohandler_id, 2000);
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
871         // this if..else, but that is because we need to release the
872         // lock before 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
932         // this if..else, but that is because we need to release the
933         // lock before 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 = Args::StringToAddress(
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)Args::StringToOptionEnum(
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 of
1196         // 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)
1276         // and other plans executed by the user (stepping around the breakpoint)
1277         // and then a "continue"
1278         // will resume the original plan.
1279         new_plan_sp->SetIsMasterPlan(true);
1280         new_plan_sp->SetOkayToDiscard(false);
1281       } else {
1282         result.AppendErrorWithFormat(
1283             "Frame index %u of thread %u has no debug information.\n",
1284             m_options.m_frame_idx, m_options.m_thread_idx);
1285         result.SetStatus(eReturnStatusFailed);
1286         return false;
1287       }
1288
1289       process->GetThreadList().SetSelectedThreadByID(m_options.m_thread_idx);
1290
1291       StreamString stream;
1292       Status error;
1293       if (synchronous_execution)
1294         error = process->ResumeSynchronous(&stream);
1295       else
1296         error = process->Resume();
1297
1298       if (error.Success()) {
1299         result.AppendMessageWithFormat("Process %" PRIu64 " resuming\n",
1300                                        process->GetID());
1301         if (synchronous_execution) {
1302           // If any state changed events had anything to say, add that to the
1303           // result
1304           if (stream.GetSize() > 0)
1305             result.AppendMessage(stream.GetString());
1306
1307           result.SetDidChangeProcessState(true);
1308           result.SetStatus(eReturnStatusSuccessFinishNoResult);
1309         } else {
1310           result.SetStatus(eReturnStatusSuccessContinuingNoResult);
1311         }
1312       } else {
1313         result.AppendErrorWithFormat("Failed to resume process: %s.\n",
1314                                      error.AsCString());
1315         result.SetStatus(eReturnStatusFailed);
1316       }
1317     }
1318     return result.Succeeded();
1319   }
1320
1321   CommandOptions m_options;
1322 };
1323
1324 //-------------------------------------------------------------------------
1325 // CommandObjectThreadSelect
1326 //-------------------------------------------------------------------------
1327
1328 class CommandObjectThreadSelect : public CommandObjectParsed {
1329 public:
1330   CommandObjectThreadSelect(CommandInterpreter &interpreter)
1331       : CommandObjectParsed(interpreter, "thread select",
1332                             "Change the currently selected thread.", nullptr,
1333                             eCommandRequiresProcess | eCommandTryTargetAPILock |
1334                                 eCommandProcessMustBeLaunched |
1335                                 eCommandProcessMustBePaused) {
1336     CommandArgumentEntry arg;
1337     CommandArgumentData thread_idx_arg;
1338
1339     // Define the first (and only) variant of this arg.
1340     thread_idx_arg.arg_type = eArgTypeThreadIndex;
1341     thread_idx_arg.arg_repetition = eArgRepeatPlain;
1342
1343     // There is only one variant this argument could be; put it into the
1344     // argument entry.
1345     arg.push_back(thread_idx_arg);
1346
1347     // Push the data for the first argument into the m_arguments vector.
1348     m_arguments.push_back(arg);
1349   }
1350
1351   ~CommandObjectThreadSelect() override = default;
1352
1353 protected:
1354   bool DoExecute(Args &command, CommandReturnObject &result) override {
1355     Process *process = m_exe_ctx.GetProcessPtr();
1356     if (process == nullptr) {
1357       result.AppendError("no process");
1358       result.SetStatus(eReturnStatusFailed);
1359       return false;
1360     } else if (command.GetArgumentCount() != 1) {
1361       result.AppendErrorWithFormat(
1362           "'%s' takes exactly one thread index argument:\nUsage: %s\n",
1363           m_cmd_name.c_str(), m_cmd_syntax.c_str());
1364       result.SetStatus(eReturnStatusFailed);
1365       return false;
1366     }
1367
1368     uint32_t index_id =
1369         StringConvert::ToUInt32(command.GetArgumentAtIndex(0), 0, 0);
1370
1371     Thread *new_thread =
1372         process->GetThreadList().FindThreadByIndexID(index_id).get();
1373     if (new_thread == nullptr) {
1374       result.AppendErrorWithFormat("invalid thread #%s.\n",
1375                                    command.GetArgumentAtIndex(0));
1376       result.SetStatus(eReturnStatusFailed);
1377       return false;
1378     }
1379
1380     process->GetThreadList().SetSelectedThreadByID(new_thread->GetID(), true);
1381     result.SetStatus(eReturnStatusSuccessFinishNoResult);
1382
1383     return result.Succeeded();
1384   }
1385 };
1386
1387 //-------------------------------------------------------------------------
1388 // CommandObjectThreadList
1389 //-------------------------------------------------------------------------
1390
1391 class CommandObjectThreadList : public CommandObjectParsed {
1392 public:
1393   CommandObjectThreadList(CommandInterpreter &interpreter)
1394       : CommandObjectParsed(
1395             interpreter, "thread list",
1396             "Show a summary of each thread in the current target process.",
1397             "thread list",
1398             eCommandRequiresProcess | eCommandTryTargetAPILock |
1399                 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {}
1400
1401   ~CommandObjectThreadList() override = default;
1402
1403 protected:
1404   bool DoExecute(Args &command, CommandReturnObject &result) override {
1405     Stream &strm = result.GetOutputStream();
1406     result.SetStatus(eReturnStatusSuccessFinishNoResult);
1407     Process *process = m_exe_ctx.GetProcessPtr();
1408     const bool only_threads_with_stop_reason = false;
1409     const uint32_t start_frame = 0;
1410     const uint32_t num_frames = 0;
1411     const uint32_t num_frames_with_source = 0;
1412     process->GetStatus(strm);
1413     process->GetThreadStatus(strm, only_threads_with_stop_reason, start_frame,
1414                              num_frames, num_frames_with_source, false);
1415     return result.Succeeded();
1416   }
1417 };
1418
1419 //-------------------------------------------------------------------------
1420 // CommandObjectThreadInfo
1421 //-------------------------------------------------------------------------
1422
1423 static OptionDefinition g_thread_info_options[] = {
1424     // clang-format off
1425   { LLDB_OPT_SET_ALL, false, "json",      'j', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the thread info in JSON format." },
1426   { LLDB_OPT_SET_ALL, false, "stop-info", 's', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the extended stop info in JSON format." }
1427     // clang-format on
1428 };
1429
1430 class CommandObjectThreadInfo : public CommandObjectIterateOverThreads {
1431 public:
1432   class CommandOptions : public Options {
1433   public:
1434     CommandOptions() : Options() { OptionParsingStarting(nullptr); }
1435
1436     ~CommandOptions() override = default;
1437
1438     void OptionParsingStarting(ExecutionContext *execution_context) override {
1439       m_json_thread = false;
1440       m_json_stopinfo = false;
1441     }
1442
1443     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1444                           ExecutionContext *execution_context) override {
1445       const int short_option = m_getopt_table[option_idx].val;
1446       Status error;
1447
1448       switch (short_option) {
1449       case 'j':
1450         m_json_thread = true;
1451         break;
1452
1453       case 's':
1454         m_json_stopinfo = true;
1455         break;
1456
1457       default:
1458         return Status("invalid short option character '%c'", short_option);
1459       }
1460       return error;
1461     }
1462
1463     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1464       return llvm::makeArrayRef(g_thread_info_options);
1465     }
1466
1467     bool m_json_thread;
1468     bool m_json_stopinfo;
1469   };
1470
1471   CommandObjectThreadInfo(CommandInterpreter &interpreter)
1472       : CommandObjectIterateOverThreads(
1473             interpreter, "thread info", "Show an extended summary of one or "
1474                                         "more threads.  Defaults to the "
1475                                         "current thread.",
1476             "thread info",
1477             eCommandRequiresProcess | eCommandTryTargetAPILock |
1478                 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
1479         m_options() {
1480     m_add_return = false;
1481   }
1482
1483   ~CommandObjectThreadInfo() override = default;
1484
1485   Options *GetOptions() override { return &m_options; }
1486
1487   bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override {
1488     ThreadSP thread_sp =
1489         m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid);
1490     if (!thread_sp) {
1491       result.AppendErrorWithFormat("thread no longer exists: 0x%" PRIx64 "\n",
1492                                    tid);
1493       result.SetStatus(eReturnStatusFailed);
1494       return false;
1495     }
1496
1497     Thread *thread = thread_sp.get();
1498
1499     Stream &strm = result.GetOutputStream();
1500     if (!thread->GetDescription(strm, eDescriptionLevelFull,
1501                                 m_options.m_json_thread,
1502                                 m_options.m_json_stopinfo)) {
1503       result.AppendErrorWithFormat("error displaying info for thread: \"%d\"\n",
1504                                    thread->GetIndexID());
1505       result.SetStatus(eReturnStatusFailed);
1506       return false;
1507     }
1508     return true;
1509   }
1510
1511   CommandOptions m_options;
1512 };
1513
1514 //-------------------------------------------------------------------------
1515 // CommandObjectThreadReturn
1516 //-------------------------------------------------------------------------
1517
1518 static OptionDefinition g_thread_return_options[] = {
1519     // clang-format off
1520   { LLDB_OPT_SET_ALL, false, "from-expression", 'x', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Return from the innermost expression evaluation." }
1521     // clang-format on
1522 };
1523
1524 class CommandObjectThreadReturn : public CommandObjectRaw {
1525 public:
1526   class CommandOptions : public Options {
1527   public:
1528     CommandOptions() : Options(), m_from_expression(false) {
1529       // Keep default values of all options in one place: OptionParsingStarting
1530       // ()
1531       OptionParsingStarting(nullptr);
1532     }
1533
1534     ~CommandOptions() override = default;
1535
1536     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1537                           ExecutionContext *execution_context) override {
1538       Status error;
1539       const int short_option = m_getopt_table[option_idx].val;
1540
1541       switch (short_option) {
1542       case 'x': {
1543         bool success;
1544         bool tmp_value = Args::StringToBoolean(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(const char *command, CommandReturnObject &result) override {
1607     // I am going to handle this by hand, because I don't want you to have to
1608     // say:
1609     // "thread return -- -5".
1610     if (command[0] == '-' && command[1] == 'x') {
1611       if (command && command[2] != '\0')
1612         result.AppendWarning("Return values ignored when returning from user "
1613                              "called expressions");
1614
1615       Thread *thread = m_exe_ctx.GetThreadPtr();
1616       Status error;
1617       error = thread->UnwindInnermostExpression();
1618       if (!error.Success()) {
1619         result.AppendErrorWithFormat("Unwinding expression failed - %s.",
1620                                      error.AsCString());
1621         result.SetStatus(eReturnStatusFailed);
1622       } else {
1623         bool success =
1624             thread->SetSelectedFrameByIndexNoisily(0, result.GetOutputStream());
1625         if (success) {
1626           m_exe_ctx.SetFrameSP(thread->GetSelectedFrame());
1627           result.SetStatus(eReturnStatusSuccessFinishResult);
1628         } else {
1629           result.AppendErrorWithFormat(
1630               "Could not select 0th frame after unwinding expression.");
1631           result.SetStatus(eReturnStatusFailed);
1632         }
1633       }
1634       return result.Succeeded();
1635     }
1636
1637     ValueObjectSP return_valobj_sp;
1638
1639     StackFrameSP frame_sp = m_exe_ctx.GetFrameSP();
1640     uint32_t frame_idx = frame_sp->GetFrameIndex();
1641
1642     if (frame_sp->IsInlined()) {
1643       result.AppendError("Don't know how to return from inlined frames.");
1644       result.SetStatus(eReturnStatusFailed);
1645       return false;
1646     }
1647
1648     if (command && command[0] != '\0') {
1649       Target *target = m_exe_ctx.GetTargetPtr();
1650       EvaluateExpressionOptions options;
1651
1652       options.SetUnwindOnError(true);
1653       options.SetUseDynamic(eNoDynamicValues);
1654
1655       ExpressionResults exe_results = eExpressionSetupError;
1656       exe_results = target->EvaluateExpression(command, frame_sp.get(),
1657                                                return_valobj_sp, options);
1658       if (exe_results != eExpressionCompleted) {
1659         if (return_valobj_sp)
1660           result.AppendErrorWithFormat(
1661               "Error evaluating result expression: %s",
1662               return_valobj_sp->GetError().AsCString());
1663         else
1664           result.AppendErrorWithFormat(
1665               "Unknown error evaluating result expression.");
1666         result.SetStatus(eReturnStatusFailed);
1667         return false;
1668       }
1669     }
1670
1671     Status error;
1672     ThreadSP thread_sp = m_exe_ctx.GetThreadSP();
1673     const bool broadcast = true;
1674     error = thread_sp->ReturnFromFrame(frame_sp, return_valobj_sp, broadcast);
1675     if (!error.Success()) {
1676       result.AppendErrorWithFormat(
1677           "Error returning from frame %d of thread %d: %s.", frame_idx,
1678           thread_sp->GetIndexID(), error.AsCString());
1679       result.SetStatus(eReturnStatusFailed);
1680       return false;
1681     }
1682
1683     result.SetStatus(eReturnStatusSuccessFinishResult);
1684     return true;
1685   }
1686
1687   CommandOptions m_options;
1688 };
1689
1690 //-------------------------------------------------------------------------
1691 // CommandObjectThreadJump
1692 //-------------------------------------------------------------------------
1693
1694 static OptionDefinition g_thread_jump_options[] = {
1695     // clang-format off
1696   { LLDB_OPT_SET_1,                                   false, "file",    'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,            "Specifies the source file to jump to." },
1697   { LLDB_OPT_SET_1,                                   true,  "line",    'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0,                                         eArgTypeLineNum,             "Specifies the line number to jump to." },
1698   { LLDB_OPT_SET_2,                                   true,  "by",      'b', OptionParser::eRequiredArgument, nullptr, nullptr, 0,                                         eArgTypeOffset,              "Jumps by a relative line offset from the current line." },
1699   { LLDB_OPT_SET_3,                                   true,  "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0,                                         eArgTypeAddressOrExpression, "Jumps to a specific address." },
1700   { 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." }
1701     // clang-format on
1702 };
1703
1704 class CommandObjectThreadJump : public CommandObjectParsed {
1705 public:
1706   class CommandOptions : public Options {
1707   public:
1708     CommandOptions() : Options() { OptionParsingStarting(nullptr); }
1709
1710     ~CommandOptions() override = default;
1711
1712     void OptionParsingStarting(ExecutionContext *execution_context) override {
1713       m_filenames.Clear();
1714       m_line_num = 0;
1715       m_line_offset = 0;
1716       m_load_addr = LLDB_INVALID_ADDRESS;
1717       m_force = false;
1718     }
1719
1720     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1721                           ExecutionContext *execution_context) override {
1722       const int short_option = m_getopt_table[option_idx].val;
1723       Status error;
1724
1725       switch (short_option) {
1726       case 'f':
1727         m_filenames.AppendIfUnique(FileSpec(option_arg, false));
1728         if (m_filenames.GetSize() > 1)
1729           return Status("only one source file expected.");
1730         break;
1731       case 'l':
1732         if (option_arg.getAsInteger(0, m_line_num))
1733           return Status("invalid line number: '%s'.", option_arg.str().c_str());
1734         break;
1735       case 'b':
1736         if (option_arg.getAsInteger(0, m_line_offset))
1737           return Status("invalid line offset: '%s'.", option_arg.str().c_str());
1738         break;
1739       case 'a':
1740         m_load_addr = Args::StringToAddress(execution_context, option_arg,
1741                                             LLDB_INVALID_ADDRESS, &error);
1742         break;
1743       case 'r':
1744         m_force = true;
1745         break;
1746       default:
1747         return Status("invalid short option character '%c'", short_option);
1748       }
1749       return error;
1750     }
1751
1752     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1753       return llvm::makeArrayRef(g_thread_jump_options);
1754     }
1755
1756     FileSpecList m_filenames;
1757     uint32_t m_line_num;
1758     int32_t m_line_offset;
1759     lldb::addr_t m_load_addr;
1760     bool m_force;
1761   };
1762
1763   CommandObjectThreadJump(CommandInterpreter &interpreter)
1764       : CommandObjectParsed(
1765             interpreter, "thread jump",
1766             "Sets the program counter to a new address.", "thread jump",
1767             eCommandRequiresFrame | eCommandTryTargetAPILock |
1768                 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
1769         m_options() {}
1770
1771   ~CommandObjectThreadJump() override = default;
1772
1773   Options *GetOptions() override { return &m_options; }
1774
1775 protected:
1776   bool DoExecute(Args &args, CommandReturnObject &result) override {
1777     RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext();
1778     StackFrame *frame = m_exe_ctx.GetFramePtr();
1779     Thread *thread = m_exe_ctx.GetThreadPtr();
1780     Target *target = m_exe_ctx.GetTargetPtr();
1781     const SymbolContext &sym_ctx =
1782         frame->GetSymbolContext(eSymbolContextLineEntry);
1783
1784     if (m_options.m_load_addr != LLDB_INVALID_ADDRESS) {
1785       // Use this address directly.
1786       Address dest = Address(m_options.m_load_addr);
1787
1788       lldb::addr_t callAddr = dest.GetCallableLoadAddress(target);
1789       if (callAddr == LLDB_INVALID_ADDRESS) {
1790         result.AppendErrorWithFormat("Invalid destination address.");
1791         result.SetStatus(eReturnStatusFailed);
1792         return false;
1793       }
1794
1795       if (!reg_ctx->SetPC(callAddr)) {
1796         result.AppendErrorWithFormat("Error changing PC value for thread %d.",
1797                                      thread->GetIndexID());
1798         result.SetStatus(eReturnStatusFailed);
1799         return false;
1800       }
1801     } else {
1802       // Pick either the absolute line, or work out a relative one.
1803       int32_t line = (int32_t)m_options.m_line_num;
1804       if (line == 0)
1805         line = sym_ctx.line_entry.line + m_options.m_line_offset;
1806
1807       // Try the current file, but override if asked.
1808       FileSpec file = sym_ctx.line_entry.file;
1809       if (m_options.m_filenames.GetSize() == 1)
1810         file = m_options.m_filenames.GetFileSpecAtIndex(0);
1811
1812       if (!file) {
1813         result.AppendErrorWithFormat(
1814             "No source file available for the current location.");
1815         result.SetStatus(eReturnStatusFailed);
1816         return false;
1817       }
1818
1819       std::string warnings;
1820       Status err = thread->JumpToLine(file, line, m_options.m_force, &warnings);
1821
1822       if (err.Fail()) {
1823         result.SetError(err);
1824         return false;
1825       }
1826
1827       if (!warnings.empty())
1828         result.AppendWarning(warnings.c_str());
1829     }
1830
1831     result.SetStatus(eReturnStatusSuccessFinishResult);
1832     return true;
1833   }
1834
1835   CommandOptions m_options;
1836 };
1837
1838 //-------------------------------------------------------------------------
1839 // Next are the subcommands of CommandObjectMultiwordThreadPlan
1840 //-------------------------------------------------------------------------
1841
1842 //-------------------------------------------------------------------------
1843 // CommandObjectThreadPlanList
1844 //-------------------------------------------------------------------------
1845
1846 static OptionDefinition g_thread_plan_list_options[] = {
1847     // clang-format off
1848   { LLDB_OPT_SET_1, false, "verbose",  'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display more information about the thread plans" },
1849   { LLDB_OPT_SET_1, false, "internal", 'i', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display internal as well as user thread plans" }
1850     // clang-format on
1851 };
1852
1853 class CommandObjectThreadPlanList : public CommandObjectIterateOverThreads {
1854 public:
1855   class CommandOptions : public Options {
1856   public:
1857     CommandOptions() : Options() {
1858       // Keep default values of all options in one place: OptionParsingStarting
1859       // ()
1860       OptionParsingStarting(nullptr);
1861     }
1862
1863     ~CommandOptions() override = default;
1864
1865     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1866                           ExecutionContext *execution_context) override {
1867       Status error;
1868       const int short_option = m_getopt_table[option_idx].val;
1869
1870       switch (short_option) {
1871       case 'i':
1872         m_internal = true;
1873         break;
1874       case 'v':
1875         m_verbose = true;
1876         break;
1877       default:
1878         error.SetErrorStringWithFormat("invalid short option character '%c'",
1879                                        short_option);
1880         break;
1881       }
1882       return error;
1883     }
1884
1885     void OptionParsingStarting(ExecutionContext *execution_context) override {
1886       m_verbose = false;
1887       m_internal = false;
1888     }
1889
1890     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1891       return llvm::makeArrayRef(g_thread_plan_list_options);
1892     }
1893
1894     // Instance variables to hold the values for command options.
1895     bool m_verbose;
1896     bool m_internal;
1897   };
1898
1899   CommandObjectThreadPlanList(CommandInterpreter &interpreter)
1900       : CommandObjectIterateOverThreads(
1901             interpreter, "thread plan list",
1902             "Show thread plans for one or more threads.  If no threads are "
1903             "specified, show the "
1904             "current thread.  Use the thread-index \"all\" to see all threads.",
1905             nullptr,
1906             eCommandRequiresProcess | eCommandRequiresThread |
1907                 eCommandTryTargetAPILock | eCommandProcessMustBeLaunched |
1908                 eCommandProcessMustBePaused),
1909         m_options() {}
1910
1911   ~CommandObjectThreadPlanList() override = default;
1912
1913   Options *GetOptions() override { return &m_options; }
1914
1915 protected:
1916   bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override {
1917     ThreadSP thread_sp =
1918         m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid);
1919     if (!thread_sp) {
1920       result.AppendErrorWithFormat("thread no longer exists: 0x%" PRIx64 "\n",
1921                                    tid);
1922       result.SetStatus(eReturnStatusFailed);
1923       return false;
1924     }
1925
1926     Thread *thread = thread_sp.get();
1927
1928     Stream &strm = result.GetOutputStream();
1929     DescriptionLevel desc_level = eDescriptionLevelFull;
1930     if (m_options.m_verbose)
1931       desc_level = eDescriptionLevelVerbose;
1932
1933     thread->DumpThreadPlans(&strm, desc_level, m_options.m_internal, true);
1934     return true;
1935   }
1936
1937   CommandOptions m_options;
1938 };
1939
1940 class CommandObjectThreadPlanDiscard : public CommandObjectParsed {
1941 public:
1942   CommandObjectThreadPlanDiscard(CommandInterpreter &interpreter)
1943       : CommandObjectParsed(interpreter, "thread plan discard",
1944                             "Discards thread plans up to and including the "
1945                             "specified index (see 'thread plan list'.)  "
1946                             "Only user visible plans can be discarded.",
1947                             nullptr,
1948                             eCommandRequiresProcess | eCommandRequiresThread |
1949                                 eCommandTryTargetAPILock |
1950                                 eCommandProcessMustBeLaunched |
1951                                 eCommandProcessMustBePaused) {
1952     CommandArgumentEntry arg;
1953     CommandArgumentData plan_index_arg;
1954
1955     // Define the first (and only) variant of this arg.
1956     plan_index_arg.arg_type = eArgTypeUnsignedInteger;
1957     plan_index_arg.arg_repetition = eArgRepeatPlain;
1958
1959     // There is only one variant this argument could be; put it into the
1960     // argument entry.
1961     arg.push_back(plan_index_arg);
1962
1963     // Push the data for the first argument into the m_arguments vector.
1964     m_arguments.push_back(arg);
1965   }
1966
1967   ~CommandObjectThreadPlanDiscard() override = default;
1968
1969   bool DoExecute(Args &args, CommandReturnObject &result) override {
1970     Thread *thread = m_exe_ctx.GetThreadPtr();
1971     if (args.GetArgumentCount() != 1) {
1972       result.AppendErrorWithFormat("Too many arguments, expected one - the "
1973                                    "thread plan index - but got %zu.",
1974                                    args.GetArgumentCount());
1975       result.SetStatus(eReturnStatusFailed);
1976       return false;
1977     }
1978
1979     bool success;
1980     uint32_t thread_plan_idx =
1981         StringConvert::ToUInt32(args.GetArgumentAtIndex(0), 0, 0, &success);
1982     if (!success) {
1983       result.AppendErrorWithFormat(
1984           "Invalid thread index: \"%s\" - should be unsigned int.",
1985           args.GetArgumentAtIndex(0));
1986       result.SetStatus(eReturnStatusFailed);
1987       return false;
1988     }
1989
1990     if (thread_plan_idx == 0) {
1991       result.AppendErrorWithFormat(
1992           "You wouldn't really want me to discard the base thread plan.");
1993       result.SetStatus(eReturnStatusFailed);
1994       return false;
1995     }
1996
1997     if (thread->DiscardUserThreadPlansUpToIndex(thread_plan_idx)) {
1998       result.SetStatus(eReturnStatusSuccessFinishNoResult);
1999       return true;
2000     } else {
2001       result.AppendErrorWithFormat(
2002           "Could not find User thread plan with index %s.",
2003           args.GetArgumentAtIndex(0));
2004       result.SetStatus(eReturnStatusFailed);
2005       return false;
2006     }
2007   }
2008 };
2009
2010 //-------------------------------------------------------------------------
2011 // CommandObjectMultiwordThreadPlan
2012 //-------------------------------------------------------------------------
2013
2014 class CommandObjectMultiwordThreadPlan : public CommandObjectMultiword {
2015 public:
2016   CommandObjectMultiwordThreadPlan(CommandInterpreter &interpreter)
2017       : CommandObjectMultiword(
2018             interpreter, "plan",
2019             "Commands for managing thread plans that control execution.",
2020             "thread plan <subcommand> [<subcommand objects]") {
2021     LoadSubCommand(
2022         "list", CommandObjectSP(new CommandObjectThreadPlanList(interpreter)));
2023     LoadSubCommand(
2024         "discard",
2025         CommandObjectSP(new CommandObjectThreadPlanDiscard(interpreter)));
2026   }
2027
2028   ~CommandObjectMultiwordThreadPlan() override = default;
2029 };
2030
2031 //-------------------------------------------------------------------------
2032 // CommandObjectMultiwordThread
2033 //-------------------------------------------------------------------------
2034
2035 CommandObjectMultiwordThread::CommandObjectMultiwordThread(
2036     CommandInterpreter &interpreter)
2037     : CommandObjectMultiword(interpreter, "thread", "Commands for operating on "
2038                                                     "one or more threads in "
2039                                                     "the current process.",
2040                              "thread <subcommand> [<subcommand-options>]") {
2041   LoadSubCommand("backtrace", CommandObjectSP(new CommandObjectThreadBacktrace(
2042                                   interpreter)));
2043   LoadSubCommand("continue",
2044                  CommandObjectSP(new CommandObjectThreadContinue(interpreter)));
2045   LoadSubCommand("list",
2046                  CommandObjectSP(new CommandObjectThreadList(interpreter)));
2047   LoadSubCommand("return",
2048                  CommandObjectSP(new CommandObjectThreadReturn(interpreter)));
2049   LoadSubCommand("jump",
2050                  CommandObjectSP(new CommandObjectThreadJump(interpreter)));
2051   LoadSubCommand("select",
2052                  CommandObjectSP(new CommandObjectThreadSelect(interpreter)));
2053   LoadSubCommand("until",
2054                  CommandObjectSP(new CommandObjectThreadUntil(interpreter)));
2055   LoadSubCommand("info",
2056                  CommandObjectSP(new CommandObjectThreadInfo(interpreter)));
2057   LoadSubCommand("step-in",
2058                  CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
2059                      interpreter, "thread step-in",
2060                      "Source level single step, stepping into calls.  Defaults "
2061                      "to current thread unless specified.",
2062                      nullptr, eStepTypeInto, eStepScopeSource)));
2063
2064   LoadSubCommand("step-out",
2065                  CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
2066                      interpreter, "thread step-out",
2067                      "Finish executing the current stack frame and stop after "
2068                      "returning.  Defaults to current thread unless specified.",
2069                      nullptr, eStepTypeOut, eStepScopeSource)));
2070
2071   LoadSubCommand("step-over",
2072                  CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
2073                      interpreter, "thread step-over",
2074                      "Source level single step, stepping over calls.  Defaults "
2075                      "to current thread unless specified.",
2076                      nullptr, eStepTypeOver, eStepScopeSource)));
2077
2078   LoadSubCommand("step-inst",
2079                  CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
2080                      interpreter, "thread step-inst",
2081                      "Instruction level single step, stepping into calls.  "
2082                      "Defaults to current thread unless specified.",
2083                      nullptr, eStepTypeTrace, eStepScopeInstruction)));
2084
2085   LoadSubCommand("step-inst-over",
2086                  CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
2087                      interpreter, "thread step-inst-over",
2088                      "Instruction level single step, stepping over calls.  "
2089                      "Defaults to current thread unless specified.",
2090                      nullptr, eStepTypeTraceOver, eStepScopeInstruction)));
2091
2092   LoadSubCommand(
2093       "step-scripted",
2094       CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
2095           interpreter, "thread step-scripted",
2096           "Step as instructed by the script class passed in the -C option.",
2097           nullptr, eStepTypeScripted, eStepScopeSource)));
2098
2099   LoadSubCommand("plan", CommandObjectSP(new CommandObjectMultiwordThreadPlan(
2100                              interpreter)));
2101 }
2102
2103 CommandObjectMultiwordThread::~CommandObjectMultiwordThread() = default;