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