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