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