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