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