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