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