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