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