xref: /llvm-project/lldb/source/Commands/CommandObjectThread.cpp (revision 4b4b2478fc4a08d035a7653ae7acaa1853553b34)
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, 0, eArgTypeCount, "How many frames to display (-1 for all)"},
309 { LLDB_OPT_SET_1, false, "start", 's', OptionParser::eRequiredArgument, NULL, 0, eArgTypeFrameIndex, "Frame in which to start the backtrace"},
310 { LLDB_OPT_SET_1, false, "extended", 'e', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "Show the extended backtrace, if available"},
311 { 0, false, NULL, 0, 0, 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 'm':
375                 {
376                     OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
377                     m_run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
378                 }
379                 break;
380 
381             case 'r':
382                 {
383                     m_avoid_regexp.clear();
384                     m_avoid_regexp.assign(option_arg);
385                 }
386                 break;
387 
388             case 't':
389                 {
390                     m_step_in_target.clear();
391                     m_step_in_target.assign(option_arg);
392 
393                 }
394                 break;
395             default:
396                 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
397                 break;
398 
399             }
400             return error;
401         }
402 
403         void
404         OptionParsingStarting ()
405         {
406             m_step_in_avoid_no_debug = eLazyBoolCalculate;
407             m_step_out_avoid_no_debug = eLazyBoolCalculate;
408             m_run_mode = eOnlyDuringStepping;
409             m_avoid_regexp.clear();
410             m_step_in_target.clear();
411         }
412 
413         const OptionDefinition*
414         GetDefinitions ()
415         {
416             return g_option_table;
417         }
418 
419         // Options table: Required for subclasses of Options.
420 
421         static OptionDefinition g_option_table[];
422 
423         // Instance variables to hold the values for command options.
424         LazyBool m_step_in_avoid_no_debug;
425         LazyBool m_step_out_avoid_no_debug;
426         RunMode m_run_mode;
427         std::string m_avoid_regexp;
428         std::string m_step_in_target;
429     };
430 
431     CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter,
432                                              const char *name,
433                                              const char *help,
434                                              const char *syntax,
435                                              StepType step_type,
436                                              StepScope step_scope) :
437         CommandObjectParsed (interpreter, name, help, syntax,
438                              eFlagRequiresProcess       |
439                              eFlagRequiresThread        |
440                              eFlagTryTargetAPILock      |
441                              eFlagProcessMustBeLaunched |
442                              eFlagProcessMustBePaused   ),
443         m_step_type (step_type),
444         m_step_scope (step_scope),
445         m_options (interpreter)
446     {
447         CommandArgumentEntry arg;
448         CommandArgumentData thread_id_arg;
449 
450         // Define the first (and only) variant of this arg.
451         thread_id_arg.arg_type = eArgTypeThreadID;
452         thread_id_arg.arg_repetition = eArgRepeatOptional;
453 
454         // There is only one variant this argument could be; put it into the argument entry.
455         arg.push_back (thread_id_arg);
456 
457         // Push the data for the first argument into the m_arguments vector.
458         m_arguments.push_back (arg);
459     }
460 
461     virtual
462     ~CommandObjectThreadStepWithTypeAndScope ()
463     {
464     }
465 
466     virtual
467     Options *
468     GetOptions ()
469     {
470         return &m_options;
471     }
472 
473 protected:
474     virtual bool
475     DoExecute (Args& command, CommandReturnObject &result)
476     {
477         Process *process = m_exe_ctx.GetProcessPtr();
478         bool synchronous_execution = m_interpreter.GetSynchronous();
479 
480         const uint32_t num_threads = process->GetThreadList().GetSize();
481         Thread *thread = NULL;
482 
483         if (command.GetArgumentCount() == 0)
484         {
485             thread = process->GetThreadList().GetSelectedThread().get();
486             if (thread == NULL)
487             {
488                 result.AppendError ("no selected thread in process");
489                 result.SetStatus (eReturnStatusFailed);
490                 return false;
491             }
492         }
493         else
494         {
495             const char *thread_idx_cstr = command.GetArgumentAtIndex(0);
496             uint32_t step_thread_idx = Args::StringToUInt32 (thread_idx_cstr, LLDB_INVALID_INDEX32);
497             if (step_thread_idx == LLDB_INVALID_INDEX32)
498             {
499                 result.AppendErrorWithFormat ("invalid thread index '%s'.\n", thread_idx_cstr);
500                 result.SetStatus (eReturnStatusFailed);
501                 return false;
502             }
503             thread = process->GetThreadList().FindThreadByIndexID(step_thread_idx).get();
504             if (thread == NULL)
505             {
506                 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
507                                               step_thread_idx, num_threads);
508                 result.SetStatus (eReturnStatusFailed);
509                 return false;
510             }
511         }
512 
513         const bool abort_other_plans = false;
514         const lldb::RunMode stop_other_threads = m_options.m_run_mode;
515 
516         // This is a bit unfortunate, but not all the commands in this command object support
517         // only while stepping, so I use the bool for them.
518         bool bool_stop_other_threads;
519         if (m_options.m_run_mode == eAllThreads)
520             bool_stop_other_threads = false;
521         else if (m_options.m_run_mode == eOnlyDuringStepping)
522         {
523             if (m_step_type == eStepTypeOut)
524                 bool_stop_other_threads = false;
525             else
526                 bool_stop_other_threads = true;
527         }
528         else
529             bool_stop_other_threads = true;
530 
531         ThreadPlanSP new_plan_sp;
532 
533         if (m_step_type == eStepTypeInto)
534         {
535             StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
536 
537             if (frame->HasDebugInformation ())
538             {
539                 new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans,
540                                                                 frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
541                                                                 frame->GetSymbolContext(eSymbolContextEverything),
542                                                                 m_options.m_step_in_target.c_str(),
543                                                                 stop_other_threads,
544                                                                 m_options.m_step_in_avoid_no_debug,
545                                                                 m_options.m_step_out_avoid_no_debug);
546 
547                 if (new_plan_sp && !m_options.m_avoid_regexp.empty())
548                 {
549                     ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan_sp.get());
550                     step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str());
551                 }
552             }
553             else
554                 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
555 
556         }
557         else if (m_step_type == eStepTypeOver)
558         {
559             StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
560 
561             if (frame->HasDebugInformation())
562                 new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
563                                                                     frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
564                                                                     frame->GetSymbolContext(eSymbolContextEverything),
565                                                                     stop_other_threads,
566                                                                     m_options.m_step_out_avoid_no_debug);
567             else
568                 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true,
569                                                                             abort_other_plans,
570                                                                             bool_stop_other_threads);
571 
572         }
573         else if (m_step_type == eStepTypeTrace)
574         {
575             new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
576         }
577         else if (m_step_type == eStepTypeTraceOver)
578         {
579             new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads);
580         }
581         else if (m_step_type == eStepTypeOut)
582         {
583             new_plan_sp = thread->QueueThreadPlanForStepOut (abort_other_plans,
584                                                           NULL,
585                                                           false,
586                                                           bool_stop_other_threads,
587                                                           eVoteYes,
588                                                           eVoteNoOpinion,
589                                                           thread->GetSelectedFrameIndex(),
590                                                           m_options.m_step_out_avoid_no_debug);
591         }
592         else
593         {
594             result.AppendError ("step type is not supported");
595             result.SetStatus (eReturnStatusFailed);
596             return false;
597         }
598 
599         // If we got a new plan, then set it to be a master plan (User level Plans should be master plans
600         // so that they can be interruptible).  Then resume the process.
601 
602         if (new_plan_sp)
603         {
604             new_plan_sp->SetIsMasterPlan (true);
605             new_plan_sp->SetOkayToDiscard (false);
606 
607             process->GetThreadList().SetSelectedThreadByID (thread->GetID());
608             process->Resume ();
609 
610 
611             if (synchronous_execution)
612             {
613                 StateType state = process->WaitForProcessToStop (NULL);
614 
615                 //EventSP event_sp;
616                 //StateType state = process->WaitForStateChangedEvents (NULL, event_sp);
617                 //while (! StateIsStoppedState (state))
618                 //  {
619                 //    state = process->WaitForStateChangedEvents (NULL, event_sp);
620                 //  }
621                 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
622                 result.SetDidChangeProcessState (true);
623                 result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
624                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
625             }
626             else
627             {
628                 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
629             }
630         }
631         else
632         {
633             result.AppendError ("Couldn't find thread plan to implement step type.");
634             result.SetStatus (eReturnStatusFailed);
635         }
636         return result.Succeeded();
637     }
638 
639 protected:
640     StepType m_step_type;
641     StepScope m_step_scope;
642     CommandOptions m_options;
643 };
644 
645 static OptionEnumValueElement
646 g_tri_running_mode[] =
647 {
648 { eOnlyThisThread,     "this-thread",    "Run only this thread"},
649 { eAllThreads,         "all-threads",    "Run all threads"},
650 { eOnlyDuringStepping, "while-stepping", "Run only this thread while stepping"},
651 { 0, NULL, NULL }
652 };
653 
654 static OptionEnumValueElement
655 g_duo_running_mode[] =
656 {
657 { eOnlyThisThread,     "this-thread",    "Run only this thread"},
658 { eAllThreads,         "all-threads",    "Run all threads"},
659 { 0, NULL, NULL }
660 };
661 
662 OptionDefinition
663 CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] =
664 {
665 { LLDB_OPT_SET_1, false, "step-in-avoids-no-debug",   'a', OptionParser::eRequiredArgument, NULL,               0, eArgTypeBoolean,     "A boolean value that sets whether stepping into functions will step over functions with no debug information."},
666 { LLDB_OPT_SET_1, false, "step-out-avoids-no-debug",  'A', OptionParser::eRequiredArgument, 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."},
667 { LLDB_OPT_SET_1, false, "run-mode",        'm', OptionParser::eRequiredArgument, g_tri_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping the current thread."},
668 { LLDB_OPT_SET_1, false, "step-over-regexp",'r', OptionParser::eRequiredArgument, NULL,               0, eArgTypeRegularExpression,   "A regular expression that defines function names to not to stop at when stepping in."},
669 { LLDB_OPT_SET_1, false, "step-in-target",  't', OptionParser::eRequiredArgument, NULL,               0, eArgTypeFunctionName,   "The name of the directly called function step in should stop at when stepping into."},
670 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
671 };
672 
673 
674 //-------------------------------------------------------------------------
675 // CommandObjectThreadContinue
676 //-------------------------------------------------------------------------
677 
678 class CommandObjectThreadContinue : public CommandObjectParsed
679 {
680 public:
681 
682     CommandObjectThreadContinue (CommandInterpreter &interpreter) :
683         CommandObjectParsed (interpreter,
684                              "thread continue",
685                              "Continue execution of one or more threads in an active process.",
686                              NULL,
687                              eFlagRequiresThread        |
688                              eFlagTryTargetAPILock      |
689                              eFlagProcessMustBeLaunched |
690                              eFlagProcessMustBePaused)
691     {
692         CommandArgumentEntry arg;
693         CommandArgumentData thread_idx_arg;
694 
695         // Define the first (and only) variant of this arg.
696         thread_idx_arg.arg_type = eArgTypeThreadIndex;
697         thread_idx_arg.arg_repetition = eArgRepeatPlus;
698 
699         // There is only one variant this argument could be; put it into the argument entry.
700         arg.push_back (thread_idx_arg);
701 
702         // Push the data for the first argument into the m_arguments vector.
703         m_arguments.push_back (arg);
704     }
705 
706 
707     virtual
708     ~CommandObjectThreadContinue ()
709     {
710     }
711 
712     virtual bool
713     DoExecute (Args& command, CommandReturnObject &result)
714     {
715         bool synchronous_execution = m_interpreter.GetSynchronous ();
716 
717         if (!m_interpreter.GetDebugger().GetSelectedTarget().get())
718         {
719             result.AppendError ("invalid target, create a debug target using the 'target create' command");
720             result.SetStatus (eReturnStatusFailed);
721             return false;
722         }
723 
724         Process *process = m_exe_ctx.GetProcessPtr();
725         if (process == NULL)
726         {
727             result.AppendError ("no process exists. Cannot continue");
728             result.SetStatus (eReturnStatusFailed);
729             return false;
730         }
731 
732         StateType state = process->GetState();
733         if ((state == eStateCrashed) || (state == eStateStopped) || (state == eStateSuspended))
734         {
735             const size_t argc = command.GetArgumentCount();
736             if (argc > 0)
737             {
738                 // These two lines appear at the beginning of both blocks in
739                 // this if..else, but that is because we need to release the
740                 // lock before calling process->Resume below.
741                 Mutex::Locker locker (process->GetThreadList().GetMutex());
742                 const uint32_t num_threads = process->GetThreadList().GetSize();
743                 std::vector<Thread *> resume_threads;
744                 for (uint32_t i=0; i<argc; ++i)
745                 {
746                     bool success;
747                     const int base = 0;
748                     uint32_t thread_idx = Args::StringToUInt32 (command.GetArgumentAtIndex(i), LLDB_INVALID_INDEX32, base, &success);
749                     if (success)
750                     {
751                         Thread *thread = process->GetThreadList().FindThreadByIndexID(thread_idx).get();
752 
753                         if (thread)
754                         {
755                             resume_threads.push_back(thread);
756                         }
757                         else
758                         {
759                             result.AppendErrorWithFormat("invalid thread index %u.\n", thread_idx);
760                             result.SetStatus (eReturnStatusFailed);
761                             return false;
762                         }
763                     }
764                     else
765                     {
766                         result.AppendErrorWithFormat ("invalid thread index argument: \"%s\".\n", command.GetArgumentAtIndex(i));
767                         result.SetStatus (eReturnStatusFailed);
768                         return false;
769                     }
770                 }
771 
772                 if (resume_threads.empty())
773                 {
774                     result.AppendError ("no valid thread indexes were specified");
775                     result.SetStatus (eReturnStatusFailed);
776                     return false;
777                 }
778                 else
779                 {
780                     if (resume_threads.size() == 1)
781                         result.AppendMessageWithFormat ("Resuming thread: ");
782                     else
783                         result.AppendMessageWithFormat ("Resuming threads: ");
784 
785                     for (uint32_t idx=0; idx<num_threads; ++idx)
786                     {
787                         Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
788                         std::vector<Thread *>::iterator this_thread_pos = find(resume_threads.begin(), resume_threads.end(), thread);
789 
790                         if (this_thread_pos != resume_threads.end())
791                         {
792                             resume_threads.erase(this_thread_pos);
793                             if (resume_threads.size() > 0)
794                                 result.AppendMessageWithFormat ("%u, ", thread->GetIndexID());
795                             else
796                                 result.AppendMessageWithFormat ("%u ", thread->GetIndexID());
797 
798                             thread->SetResumeState (eStateRunning);
799                         }
800                         else
801                         {
802                             thread->SetResumeState (eStateSuspended);
803                         }
804                     }
805                     result.AppendMessageWithFormat ("in process %" PRIu64 "\n", process->GetID());
806                 }
807             }
808             else
809             {
810                 // These two lines appear at the beginning of both blocks in
811                 // this if..else, but that is because we need to release the
812                 // lock before calling process->Resume below.
813                 Mutex::Locker locker (process->GetThreadList().GetMutex());
814                 const uint32_t num_threads = process->GetThreadList().GetSize();
815                 Thread *current_thread = process->GetThreadList().GetSelectedThread().get();
816                 if (current_thread == NULL)
817                 {
818                     result.AppendError ("the process doesn't have a current thread");
819                     result.SetStatus (eReturnStatusFailed);
820                     return false;
821                 }
822                 // Set the actions that the threads should each take when resuming
823                 for (uint32_t idx=0; idx<num_threads; ++idx)
824                 {
825                     Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
826                     if (thread == current_thread)
827                     {
828                         result.AppendMessageWithFormat ("Resuming thread 0x%4.4" PRIx64 " in process %" PRIu64 "\n", thread->GetID(), process->GetID());
829                         thread->SetResumeState (eStateRunning);
830                     }
831                     else
832                     {
833                         thread->SetResumeState (eStateSuspended);
834                     }
835                 }
836             }
837 
838             // We should not be holding the thread list lock when we do this.
839             Error error (process->Resume());
840             if (error.Success())
841             {
842                 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
843                 if (synchronous_execution)
844                 {
845                     state = process->WaitForProcessToStop (NULL);
846 
847                     result.SetDidChangeProcessState (true);
848                     result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
849                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
850                 }
851                 else
852                 {
853                     result.SetStatus (eReturnStatusSuccessContinuingNoResult);
854                 }
855             }
856             else
857             {
858                 result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString());
859                 result.SetStatus (eReturnStatusFailed);
860             }
861         }
862         else
863         {
864             result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
865                                           StateAsCString(state));
866             result.SetStatus (eReturnStatusFailed);
867         }
868 
869         return result.Succeeded();
870     }
871 
872 };
873 
874 //-------------------------------------------------------------------------
875 // CommandObjectThreadUntil
876 //-------------------------------------------------------------------------
877 
878 class CommandObjectThreadUntil : public CommandObjectParsed
879 {
880 public:
881 
882     class CommandOptions : public Options
883     {
884     public:
885         uint32_t m_thread_idx;
886         uint32_t m_frame_idx;
887 
888         CommandOptions (CommandInterpreter &interpreter) :
889             Options (interpreter),
890             m_thread_idx(LLDB_INVALID_THREAD_ID),
891             m_frame_idx(LLDB_INVALID_FRAME_ID)
892         {
893             // Keep default values of all options in one place: OptionParsingStarting ()
894             OptionParsingStarting ();
895         }
896 
897         virtual
898         ~CommandOptions ()
899         {
900         }
901 
902         virtual Error
903         SetOptionValue (uint32_t option_idx, const char *option_arg)
904         {
905             Error error;
906             const int short_option = m_getopt_table[option_idx].val;
907 
908             switch (short_option)
909             {
910                 case 't':
911                 {
912                     m_thread_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_INDEX32);
913                     if (m_thread_idx == LLDB_INVALID_INDEX32)
914                     {
915                         error.SetErrorStringWithFormat ("invalid thread index '%s'", option_arg);
916                     }
917                 }
918                 break;
919                 case 'f':
920                 {
921                     m_frame_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_FRAME_ID);
922                     if (m_frame_idx == LLDB_INVALID_FRAME_ID)
923                     {
924                         error.SetErrorStringWithFormat ("invalid frame index '%s'", option_arg);
925                     }
926                 }
927                 break;
928                 case 'm':
929                 {
930                     OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
931                     lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
932 
933                     if (error.Success())
934                     {
935                         if (run_mode == eAllThreads)
936                             m_stop_others = false;
937                         else
938                             m_stop_others = true;
939                     }
940                 }
941                 break;
942                 default:
943                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
944                     break;
945 
946             }
947             return error;
948         }
949 
950         void
951         OptionParsingStarting ()
952         {
953             m_thread_idx = LLDB_INVALID_THREAD_ID;
954             m_frame_idx = 0;
955             m_stop_others = false;
956         }
957 
958         const OptionDefinition*
959         GetDefinitions ()
960         {
961             return g_option_table;
962         }
963 
964         uint32_t m_step_thread_idx;
965         bool m_stop_others;
966 
967         // Options table: Required for subclasses of Options.
968 
969         static OptionDefinition g_option_table[];
970 
971         // Instance variables to hold the values for command options.
972     };
973 
974     CommandObjectThreadUntil (CommandInterpreter &interpreter) :
975         CommandObjectParsed (interpreter,
976                              "thread until",
977                              "Run the current or specified thread until it reaches a given line number or leaves the current function.",
978                              NULL,
979                              eFlagRequiresThread        |
980                              eFlagTryTargetAPILock      |
981                              eFlagProcessMustBeLaunched |
982                              eFlagProcessMustBePaused   ),
983         m_options (interpreter)
984     {
985         CommandArgumentEntry arg;
986         CommandArgumentData line_num_arg;
987 
988         // Define the first (and only) variant of this arg.
989         line_num_arg.arg_type = eArgTypeLineNum;
990         line_num_arg.arg_repetition = eArgRepeatPlain;
991 
992         // There is only one variant this argument could be; put it into the argument entry.
993         arg.push_back (line_num_arg);
994 
995         // Push the data for the first argument into the m_arguments vector.
996         m_arguments.push_back (arg);
997     }
998 
999 
1000     virtual
1001     ~CommandObjectThreadUntil ()
1002     {
1003     }
1004 
1005     virtual
1006     Options *
1007     GetOptions ()
1008     {
1009         return &m_options;
1010     }
1011 
1012 protected:
1013     virtual bool
1014     DoExecute (Args& command, CommandReturnObject &result)
1015     {
1016         bool synchronous_execution = m_interpreter.GetSynchronous ();
1017 
1018         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1019         if (target == NULL)
1020         {
1021             result.AppendError ("invalid target, create a debug target using the 'target create' command");
1022             result.SetStatus (eReturnStatusFailed);
1023             return false;
1024         }
1025 
1026         Process *process = m_exe_ctx.GetProcessPtr();
1027         if (process == NULL)
1028         {
1029             result.AppendError ("need a valid process to step");
1030             result.SetStatus (eReturnStatusFailed);
1031 
1032         }
1033         else
1034         {
1035             Thread *thread = NULL;
1036             uint32_t line_number;
1037 
1038             if (command.GetArgumentCount() != 1)
1039             {
1040                 result.AppendErrorWithFormat ("No line number provided:\n%s", GetSyntax());
1041                 result.SetStatus (eReturnStatusFailed);
1042                 return false;
1043             }
1044 
1045             line_number = Args::StringToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX);
1046             if (line_number == UINT32_MAX)
1047             {
1048                 result.AppendErrorWithFormat ("invalid line number: '%s'.\n", command.GetArgumentAtIndex(0));
1049                 result.SetStatus (eReturnStatusFailed);
1050                 return false;
1051             }
1052 
1053             if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID)
1054             {
1055                 thread = process->GetThreadList().GetSelectedThread().get();
1056             }
1057             else
1058             {
1059                 thread = process->GetThreadList().FindThreadByIndexID(m_options.m_thread_idx).get();
1060             }
1061 
1062             if (thread == NULL)
1063             {
1064                 const uint32_t num_threads = process->GetThreadList().GetSize();
1065                 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
1066                                               m_options.m_thread_idx,
1067                                               num_threads);
1068                 result.SetStatus (eReturnStatusFailed);
1069                 return false;
1070             }
1071 
1072             const bool abort_other_plans = false;
1073 
1074             StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get();
1075             if (frame == NULL)
1076             {
1077 
1078                 result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n",
1079                                               m_options.m_frame_idx,
1080                                               m_options.m_thread_idx);
1081                 result.SetStatus (eReturnStatusFailed);
1082                 return false;
1083             }
1084 
1085             ThreadPlanSP new_plan_sp;
1086 
1087             if (frame->HasDebugInformation ())
1088             {
1089                 // Finally we got here...  Translate the given line number to a bunch of addresses:
1090                 SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit));
1091                 LineTable *line_table = NULL;
1092                 if (sc.comp_unit)
1093                     line_table = sc.comp_unit->GetLineTable();
1094 
1095                 if (line_table == NULL)
1096                 {
1097                     result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n",
1098                                                  m_options.m_frame_idx, m_options.m_thread_idx);
1099                     result.SetStatus (eReturnStatusFailed);
1100                     return false;
1101                 }
1102 
1103                 LineEntry function_start;
1104                 uint32_t index_ptr = 0, end_ptr;
1105                 std::vector<addr_t> address_list;
1106 
1107                 // Find the beginning & end index of the
1108                 AddressRange fun_addr_range = sc.function->GetAddressRange();
1109                 Address fun_start_addr = fun_addr_range.GetBaseAddress();
1110                 line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr);
1111 
1112                 Address fun_end_addr(fun_start_addr.GetSection(),
1113                                      fun_start_addr.GetOffset() + fun_addr_range.GetByteSize());
1114                 line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr);
1115 
1116                 bool all_in_function = true;
1117 
1118                 while (index_ptr <= end_ptr)
1119                 {
1120                     LineEntry line_entry;
1121                     const bool exact = false;
1122                     index_ptr = sc.comp_unit->FindLineEntry(index_ptr, line_number, sc.comp_unit, exact, &line_entry);
1123                     if (index_ptr == UINT32_MAX)
1124                         break;
1125 
1126                     addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target);
1127                     if (address != LLDB_INVALID_ADDRESS)
1128                     {
1129                         if (fun_addr_range.ContainsLoadAddress (address, target))
1130                             address_list.push_back (address);
1131                         else
1132                             all_in_function = false;
1133                     }
1134                     index_ptr++;
1135                 }
1136 
1137                 if (address_list.size() == 0)
1138                 {
1139                     if (all_in_function)
1140                         result.AppendErrorWithFormat ("No line entries matching until target.\n");
1141                     else
1142                         result.AppendErrorWithFormat ("Until target outside of the current function.\n");
1143 
1144                     result.SetStatus (eReturnStatusFailed);
1145                     return false;
1146                 }
1147 
1148                 new_plan_sp = thread->QueueThreadPlanForStepUntil (abort_other_plans,
1149                                                                 &address_list.front(),
1150                                                                 address_list.size(),
1151                                                                 m_options.m_stop_others,
1152                                                                 m_options.m_frame_idx);
1153                 // User level plans should be master plans so they can be interrupted (e.g. by hitting a breakpoint)
1154                 // and other plans executed by the user (stepping around the breakpoint) and then a "continue"
1155                 // will resume the original plan.
1156                 new_plan_sp->SetIsMasterPlan (true);
1157                 new_plan_sp->SetOkayToDiscard(false);
1158             }
1159             else
1160             {
1161                 result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n",
1162                                               m_options.m_frame_idx,
1163                                               m_options.m_thread_idx);
1164                 result.SetStatus (eReturnStatusFailed);
1165                 return false;
1166 
1167             }
1168 
1169             process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx);
1170             Error error (process->Resume ());
1171             if (error.Success())
1172             {
1173                 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
1174                 if (synchronous_execution)
1175                 {
1176                     StateType state = process->WaitForProcessToStop (NULL);
1177 
1178                     result.SetDidChangeProcessState (true);
1179                     result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
1180                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
1181                 }
1182                 else
1183                 {
1184                     result.SetStatus (eReturnStatusSuccessContinuingNoResult);
1185                 }
1186             }
1187             else
1188             {
1189                 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
1190                 result.SetStatus (eReturnStatusFailed);
1191             }
1192 
1193         }
1194         return result.Succeeded();
1195     }
1196 
1197     CommandOptions m_options;
1198 
1199 };
1200 
1201 OptionDefinition
1202 CommandObjectThreadUntil::CommandOptions::g_option_table[] =
1203 {
1204 { LLDB_OPT_SET_1, false, "frame",   'f', OptionParser::eRequiredArgument, NULL,               0, eArgTypeFrameIndex,   "Frame index for until operation - defaults to 0"},
1205 { LLDB_OPT_SET_1, false, "thread",  't', OptionParser::eRequiredArgument, NULL,               0, eArgTypeThreadIndex,  "Thread index for the thread for until operation"},
1206 { LLDB_OPT_SET_1, false, "run-mode",'m', OptionParser::eRequiredArgument, g_duo_running_mode, 0, eArgTypeRunMode,"Determine how to run other threads while stepping this one"},
1207 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1208 };
1209 
1210 
1211 //-------------------------------------------------------------------------
1212 // CommandObjectThreadSelect
1213 //-------------------------------------------------------------------------
1214 
1215 class CommandObjectThreadSelect : public CommandObjectParsed
1216 {
1217 public:
1218 
1219     CommandObjectThreadSelect (CommandInterpreter &interpreter) :
1220         CommandObjectParsed (interpreter,
1221                              "thread select",
1222                              "Select a thread as the currently active thread.",
1223                              NULL,
1224                              eFlagRequiresProcess       |
1225                              eFlagTryTargetAPILock      |
1226                              eFlagProcessMustBeLaunched |
1227                              eFlagProcessMustBePaused   )
1228     {
1229         CommandArgumentEntry arg;
1230         CommandArgumentData thread_idx_arg;
1231 
1232         // Define the first (and only) variant of this arg.
1233         thread_idx_arg.arg_type = eArgTypeThreadIndex;
1234         thread_idx_arg.arg_repetition = eArgRepeatPlain;
1235 
1236         // There is only one variant this argument could be; put it into the argument entry.
1237         arg.push_back (thread_idx_arg);
1238 
1239         // Push the data for the first argument into the m_arguments vector.
1240         m_arguments.push_back (arg);
1241     }
1242 
1243 
1244     virtual
1245     ~CommandObjectThreadSelect ()
1246     {
1247     }
1248 
1249 protected:
1250     virtual bool
1251     DoExecute (Args& command, CommandReturnObject &result)
1252     {
1253         Process *process = m_exe_ctx.GetProcessPtr();
1254         if (process == NULL)
1255         {
1256             result.AppendError ("no process");
1257             result.SetStatus (eReturnStatusFailed);
1258             return false;
1259         }
1260         else if (command.GetArgumentCount() != 1)
1261         {
1262             result.AppendErrorWithFormat("'%s' takes exactly one thread index argument:\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
1263             result.SetStatus (eReturnStatusFailed);
1264             return false;
1265         }
1266 
1267         uint32_t index_id = Args::StringToUInt32(command.GetArgumentAtIndex(0), 0, 0);
1268 
1269         Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get();
1270         if (new_thread == NULL)
1271         {
1272             result.AppendErrorWithFormat ("invalid thread #%s.\n", command.GetArgumentAtIndex(0));
1273             result.SetStatus (eReturnStatusFailed);
1274             return false;
1275         }
1276 
1277         process->GetThreadList().SetSelectedThreadByID(new_thread->GetID(), true);
1278         result.SetStatus (eReturnStatusSuccessFinishNoResult);
1279 
1280         return result.Succeeded();
1281     }
1282 
1283 };
1284 
1285 
1286 //-------------------------------------------------------------------------
1287 // CommandObjectThreadList
1288 //-------------------------------------------------------------------------
1289 
1290 class CommandObjectThreadList : public CommandObjectParsed
1291 {
1292 public:
1293 
1294 
1295     CommandObjectThreadList (CommandInterpreter &interpreter):
1296         CommandObjectParsed (interpreter,
1297                              "thread list",
1298                              "Show a summary of all current threads in a process.",
1299                              "thread list",
1300                              eFlagRequiresProcess       |
1301                              eFlagTryTargetAPILock      |
1302                              eFlagProcessMustBeLaunched |
1303                              eFlagProcessMustBePaused   )
1304     {
1305     }
1306 
1307     ~CommandObjectThreadList()
1308     {
1309     }
1310 
1311 protected:
1312     bool
1313     DoExecute (Args& command, CommandReturnObject &result)
1314     {
1315         Stream &strm = result.GetOutputStream();
1316         result.SetStatus (eReturnStatusSuccessFinishNoResult);
1317         Process *process = m_exe_ctx.GetProcessPtr();
1318         const bool only_threads_with_stop_reason = false;
1319         const uint32_t start_frame = 0;
1320         const uint32_t num_frames = 0;
1321         const uint32_t num_frames_with_source = 0;
1322         process->GetStatus(strm);
1323         process->GetThreadStatus (strm,
1324                                   only_threads_with_stop_reason,
1325                                   start_frame,
1326                                   num_frames,
1327                                   num_frames_with_source);
1328         return result.Succeeded();
1329     }
1330 };
1331 
1332 //-------------------------------------------------------------------------
1333 // CommandObjectThreadReturn
1334 //-------------------------------------------------------------------------
1335 
1336 class CommandObjectThreadReturn : public CommandObjectRaw
1337 {
1338 public:
1339     class CommandOptions : public Options
1340     {
1341     public:
1342 
1343         CommandOptions (CommandInterpreter &interpreter) :
1344             Options (interpreter),
1345             m_from_expression (false)
1346         {
1347             // Keep default values of all options in one place: OptionParsingStarting ()
1348             OptionParsingStarting ();
1349         }
1350 
1351         virtual
1352         ~CommandOptions ()
1353         {
1354         }
1355 
1356         virtual Error
1357         SetOptionValue (uint32_t option_idx, const char *option_arg)
1358         {
1359             Error error;
1360             const int short_option = m_getopt_table[option_idx].val;
1361 
1362             switch (short_option)
1363             {
1364                 case 'x':
1365                 {
1366                     bool success;
1367                     bool tmp_value = Args::StringToBoolean (option_arg, false, &success);
1368                     if (success)
1369                         m_from_expression = tmp_value;
1370                     else
1371                     {
1372                         error.SetErrorStringWithFormat ("invalid boolean value '%s' for 'x' option", option_arg);
1373                     }
1374                 }
1375                 break;
1376                 default:
1377                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
1378                     break;
1379 
1380             }
1381             return error;
1382         }
1383 
1384         void
1385         OptionParsingStarting ()
1386         {
1387             m_from_expression = false;
1388         }
1389 
1390         const OptionDefinition*
1391         GetDefinitions ()
1392         {
1393             return g_option_table;
1394         }
1395 
1396         bool m_from_expression;
1397 
1398         // Options table: Required for subclasses of Options.
1399 
1400         static OptionDefinition g_option_table[];
1401 
1402         // Instance variables to hold the values for command options.
1403     };
1404 
1405     virtual
1406     Options *
1407     GetOptions ()
1408     {
1409         return &m_options;
1410     }
1411 
1412     CommandObjectThreadReturn (CommandInterpreter &interpreter) :
1413         CommandObjectRaw (interpreter,
1414                           "thread return",
1415                           "Return from the currently selected frame, short-circuiting execution of the frames below it, with an optional return value,"
1416                           " or with the -x option from the innermost function evaluation.",
1417                           "thread return",
1418                           eFlagRequiresFrame         |
1419                           eFlagTryTargetAPILock      |
1420                           eFlagProcessMustBeLaunched |
1421                           eFlagProcessMustBePaused   ),
1422         m_options (interpreter)
1423     {
1424         CommandArgumentEntry arg;
1425         CommandArgumentData expression_arg;
1426 
1427         // Define the first (and only) variant of this arg.
1428         expression_arg.arg_type = eArgTypeExpression;
1429         expression_arg.arg_repetition = eArgRepeatOptional;
1430 
1431         // There is only one variant this argument could be; put it into the argument entry.
1432         arg.push_back (expression_arg);
1433 
1434         // Push the data for the first argument into the m_arguments vector.
1435         m_arguments.push_back (arg);
1436 
1437 
1438     }
1439 
1440     ~CommandObjectThreadReturn()
1441     {
1442     }
1443 
1444 protected:
1445 
1446     bool DoExecute
1447     (
1448         const char *command,
1449         CommandReturnObject &result
1450     )
1451     {
1452         // I am going to handle this by hand, because I don't want you to have to say:
1453         // "thread return -- -5".
1454         if (command[0] == '-' && command[1] == 'x')
1455         {
1456             if (command && command[2] != '\0')
1457                 result.AppendWarning("Return values ignored when returning from user called expressions");
1458 
1459             Thread *thread = m_exe_ctx.GetThreadPtr();
1460             Error error;
1461             error = thread->UnwindInnermostExpression();
1462             if (!error.Success())
1463             {
1464                 result.AppendErrorWithFormat ("Unwinding expression failed - %s.", error.AsCString());
1465                 result.SetStatus (eReturnStatusFailed);
1466             }
1467             else
1468             {
1469                 bool success = thread->SetSelectedFrameByIndexNoisily (0, result.GetOutputStream());
1470                 if (success)
1471                 {
1472                     m_exe_ctx.SetFrameSP(thread->GetSelectedFrame ());
1473                     result.SetStatus (eReturnStatusSuccessFinishResult);
1474                 }
1475                 else
1476                 {
1477                     result.AppendErrorWithFormat ("Could not select 0th frame after unwinding expression.");
1478                     result.SetStatus (eReturnStatusFailed);
1479                 }
1480             }
1481             return result.Succeeded();
1482         }
1483 
1484         ValueObjectSP return_valobj_sp;
1485 
1486         StackFrameSP frame_sp = m_exe_ctx.GetFrameSP();
1487         uint32_t frame_idx = frame_sp->GetFrameIndex();
1488 
1489         if (frame_sp->IsInlined())
1490         {
1491             result.AppendError("Don't know how to return from inlined frames.");
1492             result.SetStatus (eReturnStatusFailed);
1493             return false;
1494         }
1495 
1496         if (command && command[0] != '\0')
1497         {
1498             Target *target = m_exe_ctx.GetTargetPtr();
1499             EvaluateExpressionOptions options;
1500 
1501             options.SetUnwindOnError(true);
1502             options.SetUseDynamic(eNoDynamicValues);
1503 
1504             ExecutionResults exe_results = eExecutionSetupError;
1505             exe_results = target->EvaluateExpression (command,
1506                                                       frame_sp.get(),
1507                                                       return_valobj_sp,
1508                                                       options);
1509             if (exe_results != eExecutionCompleted)
1510             {
1511                 if (return_valobj_sp)
1512                     result.AppendErrorWithFormat("Error evaluating result expression: %s", return_valobj_sp->GetError().AsCString());
1513                 else
1514                     result.AppendErrorWithFormat("Unknown error evaluating result expression.");
1515                 result.SetStatus (eReturnStatusFailed);
1516                 return false;
1517 
1518             }
1519         }
1520 
1521         Error error;
1522         ThreadSP thread_sp = m_exe_ctx.GetThreadSP();
1523         const bool broadcast = true;
1524         error = thread_sp->ReturnFromFrame (frame_sp, return_valobj_sp, broadcast);
1525         if (!error.Success())
1526         {
1527             result.AppendErrorWithFormat("Error returning from frame %d of thread %d: %s.", frame_idx, thread_sp->GetIndexID(), error.AsCString());
1528             result.SetStatus (eReturnStatusFailed);
1529             return false;
1530         }
1531 
1532         result.SetStatus (eReturnStatusSuccessFinishResult);
1533         return true;
1534     }
1535 
1536     CommandOptions m_options;
1537 
1538 };
1539 OptionDefinition
1540 CommandObjectThreadReturn::CommandOptions::g_option_table[] =
1541 {
1542 { LLDB_OPT_SET_ALL, false, "from-expression",  'x', OptionParser::eNoArgument, NULL,               0, eArgTypeNone,     "Return from the innermost expression evaluation."},
1543 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1544 };
1545 
1546 //-------------------------------------------------------------------------
1547 // CommandObjectThreadJump
1548 //-------------------------------------------------------------------------
1549 
1550 class CommandObjectThreadJump : public CommandObjectParsed
1551 {
1552 public:
1553     class CommandOptions : public Options
1554     {
1555     public:
1556 
1557         CommandOptions (CommandInterpreter &interpreter) :
1558             Options (interpreter)
1559         {
1560             OptionParsingStarting ();
1561         }
1562 
1563         void
1564         OptionParsingStarting ()
1565         {
1566             m_filenames.Clear();
1567             m_line_num = 0;
1568             m_line_offset = 0;
1569             m_load_addr = LLDB_INVALID_ADDRESS;
1570             m_force = false;
1571         }
1572 
1573         virtual
1574         ~CommandOptions ()
1575         {
1576         }
1577 
1578         virtual Error
1579         SetOptionValue (uint32_t option_idx, const char *option_arg)
1580         {
1581             bool success;
1582             const int short_option = m_getopt_table[option_idx].val;
1583             Error error;
1584 
1585             switch (short_option)
1586             {
1587                 case 'f':
1588                     m_filenames.AppendIfUnique (FileSpec(option_arg, false));
1589                     if (m_filenames.GetSize() > 1)
1590                         return Error("only one source file expected.");
1591                     break;
1592                 case 'l':
1593                     m_line_num = Args::StringToUInt32 (option_arg, 0, 0, &success);
1594                     if (!success || m_line_num == 0)
1595                         return Error("invalid line number: '%s'.", option_arg);
1596                     break;
1597                 case 'b':
1598                     m_line_offset = Args::StringToSInt32 (option_arg, 0, 0, &success);
1599                     if (!success)
1600                         return Error("invalid line offset: '%s'.", option_arg);
1601                     break;
1602                 case 'a':
1603                     {
1604                         ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
1605                         m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
1606                     }
1607                     break;
1608                 case 'r':
1609                     m_force = true;
1610                     break;
1611 
1612                  default:
1613                     return Error("invalid short option character '%c'", short_option);
1614 
1615             }
1616             return error;
1617         }
1618 
1619         const OptionDefinition*
1620         GetDefinitions ()
1621         {
1622             return g_option_table;
1623         }
1624 
1625         FileSpecList m_filenames;
1626         uint32_t m_line_num;
1627         int32_t m_line_offset;
1628         lldb::addr_t m_load_addr;
1629         bool m_force;
1630 
1631         static OptionDefinition g_option_table[];
1632     };
1633 
1634     virtual
1635     Options *
1636     GetOptions ()
1637     {
1638         return &m_options;
1639     }
1640 
1641     CommandObjectThreadJump (CommandInterpreter &interpreter) :
1642         CommandObjectParsed (interpreter,
1643                           "thread jump",
1644                           "Sets the program counter to a new address.",
1645                           "thread jump",
1646                           eFlagRequiresFrame         |
1647                           eFlagTryTargetAPILock      |
1648                           eFlagProcessMustBeLaunched |
1649                           eFlagProcessMustBePaused   ),
1650         m_options (interpreter)
1651     {
1652     }
1653 
1654     ~CommandObjectThreadJump()
1655     {
1656     }
1657 
1658 protected:
1659 
1660     bool DoExecute (Args& args, CommandReturnObject &result)
1661     {
1662         RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext();
1663         StackFrame *frame = m_exe_ctx.GetFramePtr();
1664         Thread *thread = m_exe_ctx.GetThreadPtr();
1665         Target *target = m_exe_ctx.GetTargetPtr();
1666         const SymbolContext &sym_ctx = frame->GetSymbolContext (eSymbolContextLineEntry);
1667 
1668         if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
1669         {
1670             // Use this address directly.
1671             Address dest = Address(m_options.m_load_addr);
1672 
1673             lldb::addr_t callAddr = dest.GetCallableLoadAddress (target);
1674             if (callAddr == LLDB_INVALID_ADDRESS)
1675             {
1676                 result.AppendErrorWithFormat ("Invalid destination address.");
1677                 result.SetStatus (eReturnStatusFailed);
1678                 return false;
1679             }
1680 
1681             if (!reg_ctx->SetPC (callAddr))
1682             {
1683                 result.AppendErrorWithFormat ("Error changing PC value for thread %d.", thread->GetIndexID());
1684                 result.SetStatus (eReturnStatusFailed);
1685                 return false;
1686             }
1687         }
1688         else
1689         {
1690             // Pick either the absolute line, or work out a relative one.
1691             int32_t line = (int32_t)m_options.m_line_num;
1692             if (line == 0)
1693                 line = sym_ctx.line_entry.line + m_options.m_line_offset;
1694 
1695             // Try the current file, but override if asked.
1696             FileSpec file = sym_ctx.line_entry.file;
1697             if (m_options.m_filenames.GetSize() == 1)
1698                 file = m_options.m_filenames.GetFileSpecAtIndex(0);
1699 
1700             if (!file)
1701             {
1702                 result.AppendErrorWithFormat ("No source file available for the current location.");
1703                 result.SetStatus (eReturnStatusFailed);
1704                 return false;
1705             }
1706 
1707             std::string warnings;
1708             Error err = thread->JumpToLine (file, line, m_options.m_force, &warnings);
1709 
1710             if (err.Fail())
1711             {
1712                 result.SetError (err);
1713                 return false;
1714             }
1715 
1716             if (!warnings.empty())
1717                 result.AppendWarning (warnings.c_str());
1718         }
1719 
1720         result.SetStatus (eReturnStatusSuccessFinishResult);
1721         return true;
1722     }
1723 
1724     CommandOptions m_options;
1725 };
1726 OptionDefinition
1727 CommandObjectThreadJump::CommandOptions::g_option_table[] =
1728 {
1729     { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
1730         "Specifies the source file to jump to."},
1731 
1732     { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, 0, eArgTypeLineNum,
1733         "Specifies the line number to jump to."},
1734 
1735     { LLDB_OPT_SET_2, true, "by", 'b', OptionParser::eRequiredArgument, NULL, 0, eArgTypeOffset,
1736         "Jumps by a relative line offset from the current line."},
1737 
1738     { LLDB_OPT_SET_3, true, "address", 'a', OptionParser::eRequiredArgument, NULL, 0, eArgTypeAddressOrExpression,
1739         "Jumps to a specific address."},
1740 
1741     { LLDB_OPT_SET_1|
1742       LLDB_OPT_SET_2|
1743       LLDB_OPT_SET_3, false, "force",'r', OptionParser::eNoArgument, NULL, 0, eArgTypeNone,"Allows the PC to leave the current function."},
1744 
1745     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1746 };
1747 
1748 //-------------------------------------------------------------------------
1749 // CommandObjectMultiwordThread
1750 //-------------------------------------------------------------------------
1751 
1752 CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) :
1753     CommandObjectMultiword (interpreter,
1754                             "thread",
1755                             "A set of commands for operating on one or more threads within a running process.",
1756                             "thread <subcommand> [<subcommand-options>]")
1757 {
1758     LoadSubCommand ("backtrace",  CommandObjectSP (new CommandObjectThreadBacktrace (interpreter)));
1759     LoadSubCommand ("continue",   CommandObjectSP (new CommandObjectThreadContinue (interpreter)));
1760     LoadSubCommand ("list",       CommandObjectSP (new CommandObjectThreadList (interpreter)));
1761     LoadSubCommand ("return",     CommandObjectSP (new CommandObjectThreadReturn (interpreter)));
1762     LoadSubCommand ("jump",       CommandObjectSP (new CommandObjectThreadJump (interpreter)));
1763     LoadSubCommand ("select",     CommandObjectSP (new CommandObjectThreadSelect (interpreter)));
1764     LoadSubCommand ("until",      CommandObjectSP (new CommandObjectThreadUntil (interpreter)));
1765     LoadSubCommand ("step-in",    CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1766                                                     interpreter,
1767                                                     "thread step-in",
1768                                                     "Source level single step in specified thread (current thread, if none specified).",
1769                                                     NULL,
1770                                                     eStepTypeInto,
1771                                                     eStepScopeSource)));
1772 
1773     LoadSubCommand ("step-out",   CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1774                                                     interpreter,
1775                                                     "thread step-out",
1776                                                     "Finish executing the function of the currently selected frame and return to its call site in specified thread (current thread, if none specified).",
1777                                                     NULL,
1778                                                     eStepTypeOut,
1779                                                     eStepScopeSource)));
1780 
1781     LoadSubCommand ("step-over",   CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1782                                                     interpreter,
1783                                                     "thread step-over",
1784                                                     "Source level single step in specified thread (current thread, if none specified), stepping over calls.",
1785                                                     NULL,
1786                                                     eStepTypeOver,
1787                                                     eStepScopeSource)));
1788 
1789     LoadSubCommand ("step-inst",   CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1790                                                     interpreter,
1791                                                     "thread step-inst",
1792                                                     "Single step one instruction in specified thread (current thread, if none specified).",
1793                                                     NULL,
1794                                                     eStepTypeTrace,
1795                                                     eStepScopeInstruction)));
1796 
1797     LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1798                                                     interpreter,
1799                                                     "thread step-inst-over",
1800                                                     "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.",
1801                                                     NULL,
1802                                                     eStepTypeTraceOver,
1803                                                     eStepScopeInstruction)));
1804 }
1805 
1806 CommandObjectMultiwordThread::~CommandObjectMultiwordThread ()
1807 {
1808 }
1809 
1810 
1811