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