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