xref: /llvm-project/lldb/source/Commands/CommandObjectThread.cpp (revision 1624a2d3c8a9558840b5e17623d232c0aa3c01cd)
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                             const bool override_suspend = true;
799                             thread->SetResumeState (eStateRunning, override_suspend);
800                         }
801                         else
802                         {
803                             thread->SetResumeState (eStateSuspended);
804                         }
805                     }
806                     result.AppendMessageWithFormat ("in process %" PRIu64 "\n", process->GetID());
807                 }
808             }
809             else
810             {
811                 // These two lines appear at the beginning of both blocks in
812                 // this if..else, but that is because we need to release the
813                 // lock before calling process->Resume below.
814                 Mutex::Locker locker (process->GetThreadList().GetMutex());
815                 const uint32_t num_threads = process->GetThreadList().GetSize();
816                 Thread *current_thread = process->GetThreadList().GetSelectedThread().get();
817                 if (current_thread == NULL)
818                 {
819                     result.AppendError ("the process doesn't have a current thread");
820                     result.SetStatus (eReturnStatusFailed);
821                     return false;
822                 }
823                 // Set the actions that the threads should each take when resuming
824                 for (uint32_t idx=0; idx<num_threads; ++idx)
825                 {
826                     Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
827                     if (thread == current_thread)
828                     {
829                         result.AppendMessageWithFormat ("Resuming thread 0x%4.4" PRIx64 " in process %" PRIu64 "\n", thread->GetID(), process->GetID());
830                         const bool override_suspend = true;
831                         thread->SetResumeState (eStateRunning, override_suspend);
832                     }
833                     else
834                     {
835                         thread->SetResumeState (eStateSuspended);
836                     }
837                 }
838             }
839 
840             // We should not be holding the thread list lock when we do this.
841             Error error (process->Resume());
842             if (error.Success())
843             {
844                 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
845                 if (synchronous_execution)
846                 {
847                     state = process->WaitForProcessToStop (NULL);
848 
849                     result.SetDidChangeProcessState (true);
850                     result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
851                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
852                 }
853                 else
854                 {
855                     result.SetStatus (eReturnStatusSuccessContinuingNoResult);
856                 }
857             }
858             else
859             {
860                 result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString());
861                 result.SetStatus (eReturnStatusFailed);
862             }
863         }
864         else
865         {
866             result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
867                                           StateAsCString(state));
868             result.SetStatus (eReturnStatusFailed);
869         }
870 
871         return result.Succeeded();
872     }
873 
874 };
875 
876 //-------------------------------------------------------------------------
877 // CommandObjectThreadUntil
878 //-------------------------------------------------------------------------
879 
880 class CommandObjectThreadUntil : public CommandObjectParsed
881 {
882 public:
883 
884     class CommandOptions : public Options
885     {
886     public:
887         uint32_t m_thread_idx;
888         uint32_t m_frame_idx;
889 
890         CommandOptions (CommandInterpreter &interpreter) :
891             Options (interpreter),
892             m_thread_idx(LLDB_INVALID_THREAD_ID),
893             m_frame_idx(LLDB_INVALID_FRAME_ID)
894         {
895             // Keep default values of all options in one place: OptionParsingStarting ()
896             OptionParsingStarting ();
897         }
898 
899         virtual
900         ~CommandOptions ()
901         {
902         }
903 
904         virtual Error
905         SetOptionValue (uint32_t option_idx, const char *option_arg)
906         {
907             Error error;
908             const int short_option = m_getopt_table[option_idx].val;
909 
910             switch (short_option)
911             {
912                 case 't':
913                 {
914                     m_thread_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_INDEX32);
915                     if (m_thread_idx == LLDB_INVALID_INDEX32)
916                     {
917                         error.SetErrorStringWithFormat ("invalid thread index '%s'", option_arg);
918                     }
919                 }
920                 break;
921                 case 'f':
922                 {
923                     m_frame_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_FRAME_ID);
924                     if (m_frame_idx == LLDB_INVALID_FRAME_ID)
925                     {
926                         error.SetErrorStringWithFormat ("invalid frame index '%s'", option_arg);
927                     }
928                 }
929                 break;
930                 case 'm':
931                 {
932                     OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
933                     lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
934 
935                     if (error.Success())
936                     {
937                         if (run_mode == eAllThreads)
938                             m_stop_others = false;
939                         else
940                             m_stop_others = true;
941                     }
942                 }
943                 break;
944                 default:
945                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
946                     break;
947 
948             }
949             return error;
950         }
951 
952         void
953         OptionParsingStarting ()
954         {
955             m_thread_idx = LLDB_INVALID_THREAD_ID;
956             m_frame_idx = 0;
957             m_stop_others = false;
958         }
959 
960         const OptionDefinition*
961         GetDefinitions ()
962         {
963             return g_option_table;
964         }
965 
966         uint32_t m_step_thread_idx;
967         bool m_stop_others;
968 
969         // Options table: Required for subclasses of Options.
970 
971         static OptionDefinition g_option_table[];
972 
973         // Instance variables to hold the values for command options.
974     };
975 
976     CommandObjectThreadUntil (CommandInterpreter &interpreter) :
977         CommandObjectParsed (interpreter,
978                              "thread until",
979                              "Run the current or specified thread until it reaches a given line number or leaves the current function.",
980                              NULL,
981                              eFlagRequiresThread        |
982                              eFlagTryTargetAPILock      |
983                              eFlagProcessMustBeLaunched |
984                              eFlagProcessMustBePaused   ),
985         m_options (interpreter)
986     {
987         CommandArgumentEntry arg;
988         CommandArgumentData line_num_arg;
989 
990         // Define the first (and only) variant of this arg.
991         line_num_arg.arg_type = eArgTypeLineNum;
992         line_num_arg.arg_repetition = eArgRepeatPlain;
993 
994         // There is only one variant this argument could be; put it into the argument entry.
995         arg.push_back (line_num_arg);
996 
997         // Push the data for the first argument into the m_arguments vector.
998         m_arguments.push_back (arg);
999     }
1000 
1001 
1002     virtual
1003     ~CommandObjectThreadUntil ()
1004     {
1005     }
1006 
1007     virtual
1008     Options *
1009     GetOptions ()
1010     {
1011         return &m_options;
1012     }
1013 
1014 protected:
1015     virtual bool
1016     DoExecute (Args& command, CommandReturnObject &result)
1017     {
1018         bool synchronous_execution = m_interpreter.GetSynchronous ();
1019 
1020         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1021         if (target == NULL)
1022         {
1023             result.AppendError ("invalid target, create a debug target using the 'target create' command");
1024             result.SetStatus (eReturnStatusFailed);
1025             return false;
1026         }
1027 
1028         Process *process = m_exe_ctx.GetProcessPtr();
1029         if (process == NULL)
1030         {
1031             result.AppendError ("need a valid process to step");
1032             result.SetStatus (eReturnStatusFailed);
1033 
1034         }
1035         else
1036         {
1037             Thread *thread = NULL;
1038             uint32_t line_number;
1039 
1040             if (command.GetArgumentCount() != 1)
1041             {
1042                 result.AppendErrorWithFormat ("No line number provided:\n%s", GetSyntax());
1043                 result.SetStatus (eReturnStatusFailed);
1044                 return false;
1045             }
1046 
1047             line_number = Args::StringToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX);
1048             if (line_number == UINT32_MAX)
1049             {
1050                 result.AppendErrorWithFormat ("invalid line number: '%s'.\n", command.GetArgumentAtIndex(0));
1051                 result.SetStatus (eReturnStatusFailed);
1052                 return false;
1053             }
1054 
1055             if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID)
1056             {
1057                 thread = process->GetThreadList().GetSelectedThread().get();
1058             }
1059             else
1060             {
1061                 thread = process->GetThreadList().FindThreadByIndexID(m_options.m_thread_idx).get();
1062             }
1063 
1064             if (thread == NULL)
1065             {
1066                 const uint32_t num_threads = process->GetThreadList().GetSize();
1067                 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
1068                                               m_options.m_thread_idx,
1069                                               num_threads);
1070                 result.SetStatus (eReturnStatusFailed);
1071                 return false;
1072             }
1073 
1074             const bool abort_other_plans = false;
1075 
1076             StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get();
1077             if (frame == NULL)
1078             {
1079 
1080                 result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n",
1081                                               m_options.m_frame_idx,
1082                                               m_options.m_thread_idx);
1083                 result.SetStatus (eReturnStatusFailed);
1084                 return false;
1085             }
1086 
1087             ThreadPlanSP new_plan_sp;
1088 
1089             if (frame->HasDebugInformation ())
1090             {
1091                 // Finally we got here...  Translate the given line number to a bunch of addresses:
1092                 SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit));
1093                 LineTable *line_table = NULL;
1094                 if (sc.comp_unit)
1095                     line_table = sc.comp_unit->GetLineTable();
1096 
1097                 if (line_table == NULL)
1098                 {
1099                     result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n",
1100                                                  m_options.m_frame_idx, m_options.m_thread_idx);
1101                     result.SetStatus (eReturnStatusFailed);
1102                     return false;
1103                 }
1104 
1105                 LineEntry function_start;
1106                 uint32_t index_ptr = 0, end_ptr;
1107                 std::vector<addr_t> address_list;
1108 
1109                 // Find the beginning & end index of the
1110                 AddressRange fun_addr_range = sc.function->GetAddressRange();
1111                 Address fun_start_addr = fun_addr_range.GetBaseAddress();
1112                 line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr);
1113 
1114                 Address fun_end_addr(fun_start_addr.GetSection(),
1115                                      fun_start_addr.GetOffset() + fun_addr_range.GetByteSize());
1116                 line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr);
1117 
1118                 bool all_in_function = true;
1119 
1120                 while (index_ptr <= end_ptr)
1121                 {
1122                     LineEntry line_entry;
1123                     const bool exact = false;
1124                     index_ptr = sc.comp_unit->FindLineEntry(index_ptr, line_number, sc.comp_unit, exact, &line_entry);
1125                     if (index_ptr == UINT32_MAX)
1126                         break;
1127 
1128                     addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target);
1129                     if (address != LLDB_INVALID_ADDRESS)
1130                     {
1131                         if (fun_addr_range.ContainsLoadAddress (address, target))
1132                             address_list.push_back (address);
1133                         else
1134                             all_in_function = false;
1135                     }
1136                     index_ptr++;
1137                 }
1138 
1139                 if (address_list.size() == 0)
1140                 {
1141                     if (all_in_function)
1142                         result.AppendErrorWithFormat ("No line entries matching until target.\n");
1143                     else
1144                         result.AppendErrorWithFormat ("Until target outside of the current function.\n");
1145 
1146                     result.SetStatus (eReturnStatusFailed);
1147                     return false;
1148                 }
1149 
1150                 new_plan_sp = thread->QueueThreadPlanForStepUntil (abort_other_plans,
1151                                                                 &address_list.front(),
1152                                                                 address_list.size(),
1153                                                                 m_options.m_stop_others,
1154                                                                 m_options.m_frame_idx);
1155                 // User level plans should be master plans so they can be interrupted (e.g. by hitting a breakpoint)
1156                 // and other plans executed by the user (stepping around the breakpoint) and then a "continue"
1157                 // will resume the original plan.
1158                 new_plan_sp->SetIsMasterPlan (true);
1159                 new_plan_sp->SetOkayToDiscard(false);
1160             }
1161             else
1162             {
1163                 result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n",
1164                                               m_options.m_frame_idx,
1165                                               m_options.m_thread_idx);
1166                 result.SetStatus (eReturnStatusFailed);
1167                 return false;
1168 
1169             }
1170 
1171             process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx);
1172             Error error (process->Resume ());
1173             if (error.Success())
1174             {
1175                 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
1176                 if (synchronous_execution)
1177                 {
1178                     StateType state = process->WaitForProcessToStop (NULL);
1179 
1180                     result.SetDidChangeProcessState (true);
1181                     result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
1182                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
1183                 }
1184                 else
1185                 {
1186                     result.SetStatus (eReturnStatusSuccessContinuingNoResult);
1187                 }
1188             }
1189             else
1190             {
1191                 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
1192                 result.SetStatus (eReturnStatusFailed);
1193             }
1194 
1195         }
1196         return result.Succeeded();
1197     }
1198 
1199     CommandOptions m_options;
1200 
1201 };
1202 
1203 OptionDefinition
1204 CommandObjectThreadUntil::CommandOptions::g_option_table[] =
1205 {
1206 { LLDB_OPT_SET_1, false, "frame",   'f', OptionParser::eRequiredArgument, NULL,               0, eArgTypeFrameIndex,   "Frame index for until operation - defaults to 0"},
1207 { LLDB_OPT_SET_1, false, "thread",  't', OptionParser::eRequiredArgument, NULL,               0, eArgTypeThreadIndex,  "Thread index for the thread for until operation"},
1208 { 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"},
1209 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1210 };
1211 
1212 
1213 //-------------------------------------------------------------------------
1214 // CommandObjectThreadSelect
1215 //-------------------------------------------------------------------------
1216 
1217 class CommandObjectThreadSelect : public CommandObjectParsed
1218 {
1219 public:
1220 
1221     CommandObjectThreadSelect (CommandInterpreter &interpreter) :
1222         CommandObjectParsed (interpreter,
1223                              "thread select",
1224                              "Select a thread as the currently active thread.",
1225                              NULL,
1226                              eFlagRequiresProcess       |
1227                              eFlagTryTargetAPILock      |
1228                              eFlagProcessMustBeLaunched |
1229                              eFlagProcessMustBePaused   )
1230     {
1231         CommandArgumentEntry arg;
1232         CommandArgumentData thread_idx_arg;
1233 
1234         // Define the first (and only) variant of this arg.
1235         thread_idx_arg.arg_type = eArgTypeThreadIndex;
1236         thread_idx_arg.arg_repetition = eArgRepeatPlain;
1237 
1238         // There is only one variant this argument could be; put it into the argument entry.
1239         arg.push_back (thread_idx_arg);
1240 
1241         // Push the data for the first argument into the m_arguments vector.
1242         m_arguments.push_back (arg);
1243     }
1244 
1245 
1246     virtual
1247     ~CommandObjectThreadSelect ()
1248     {
1249     }
1250 
1251 protected:
1252     virtual bool
1253     DoExecute (Args& command, CommandReturnObject &result)
1254     {
1255         Process *process = m_exe_ctx.GetProcessPtr();
1256         if (process == NULL)
1257         {
1258             result.AppendError ("no process");
1259             result.SetStatus (eReturnStatusFailed);
1260             return false;
1261         }
1262         else if (command.GetArgumentCount() != 1)
1263         {
1264             result.AppendErrorWithFormat("'%s' takes exactly one thread index argument:\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
1265             result.SetStatus (eReturnStatusFailed);
1266             return false;
1267         }
1268 
1269         uint32_t index_id = Args::StringToUInt32(command.GetArgumentAtIndex(0), 0, 0);
1270 
1271         Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get();
1272         if (new_thread == NULL)
1273         {
1274             result.AppendErrorWithFormat ("invalid thread #%s.\n", command.GetArgumentAtIndex(0));
1275             result.SetStatus (eReturnStatusFailed);
1276             return false;
1277         }
1278 
1279         process->GetThreadList().SetSelectedThreadByID(new_thread->GetID(), true);
1280         result.SetStatus (eReturnStatusSuccessFinishNoResult);
1281 
1282         return result.Succeeded();
1283     }
1284 
1285 };
1286 
1287 
1288 //-------------------------------------------------------------------------
1289 // CommandObjectThreadList
1290 //-------------------------------------------------------------------------
1291 
1292 class CommandObjectThreadList : public CommandObjectParsed
1293 {
1294 public:
1295 
1296 
1297     CommandObjectThreadList (CommandInterpreter &interpreter):
1298         CommandObjectParsed (interpreter,
1299                              "thread list",
1300                              "Show a summary of all current threads in a process.",
1301                              "thread list",
1302                              eFlagRequiresProcess       |
1303                              eFlagTryTargetAPILock      |
1304                              eFlagProcessMustBeLaunched |
1305                              eFlagProcessMustBePaused   )
1306     {
1307     }
1308 
1309     ~CommandObjectThreadList()
1310     {
1311     }
1312 
1313 protected:
1314     bool
1315     DoExecute (Args& command, CommandReturnObject &result)
1316     {
1317         Stream &strm = result.GetOutputStream();
1318         result.SetStatus (eReturnStatusSuccessFinishNoResult);
1319         Process *process = m_exe_ctx.GetProcessPtr();
1320         const bool only_threads_with_stop_reason = false;
1321         const uint32_t start_frame = 0;
1322         const uint32_t num_frames = 0;
1323         const uint32_t num_frames_with_source = 0;
1324         process->GetStatus(strm);
1325         process->GetThreadStatus (strm,
1326                                   only_threads_with_stop_reason,
1327                                   start_frame,
1328                                   num_frames,
1329                                   num_frames_with_source);
1330         return result.Succeeded();
1331     }
1332 };
1333 
1334 //-------------------------------------------------------------------------
1335 // CommandObjectThreadReturn
1336 //-------------------------------------------------------------------------
1337 
1338 class CommandObjectThreadReturn : public CommandObjectRaw
1339 {
1340 public:
1341     class CommandOptions : public Options
1342     {
1343     public:
1344 
1345         CommandOptions (CommandInterpreter &interpreter) :
1346             Options (interpreter),
1347             m_from_expression (false)
1348         {
1349             // Keep default values of all options in one place: OptionParsingStarting ()
1350             OptionParsingStarting ();
1351         }
1352 
1353         virtual
1354         ~CommandOptions ()
1355         {
1356         }
1357 
1358         virtual Error
1359         SetOptionValue (uint32_t option_idx, const char *option_arg)
1360         {
1361             Error error;
1362             const int short_option = m_getopt_table[option_idx].val;
1363 
1364             switch (short_option)
1365             {
1366                 case 'x':
1367                 {
1368                     bool success;
1369                     bool tmp_value = Args::StringToBoolean (option_arg, false, &success);
1370                     if (success)
1371                         m_from_expression = tmp_value;
1372                     else
1373                     {
1374                         error.SetErrorStringWithFormat ("invalid boolean value '%s' for 'x' option", option_arg);
1375                     }
1376                 }
1377                 break;
1378                 default:
1379                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
1380                     break;
1381 
1382             }
1383             return error;
1384         }
1385 
1386         void
1387         OptionParsingStarting ()
1388         {
1389             m_from_expression = false;
1390         }
1391 
1392         const OptionDefinition*
1393         GetDefinitions ()
1394         {
1395             return g_option_table;
1396         }
1397 
1398         bool m_from_expression;
1399 
1400         // Options table: Required for subclasses of Options.
1401 
1402         static OptionDefinition g_option_table[];
1403 
1404         // Instance variables to hold the values for command options.
1405     };
1406 
1407     virtual
1408     Options *
1409     GetOptions ()
1410     {
1411         return &m_options;
1412     }
1413 
1414     CommandObjectThreadReturn (CommandInterpreter &interpreter) :
1415         CommandObjectRaw (interpreter,
1416                           "thread return",
1417                           "Return from the currently selected frame, short-circuiting execution of the frames below it, with an optional return value,"
1418                           " or with the -x option from the innermost function evaluation.",
1419                           "thread return",
1420                           eFlagRequiresFrame         |
1421                           eFlagTryTargetAPILock      |
1422                           eFlagProcessMustBeLaunched |
1423                           eFlagProcessMustBePaused   ),
1424         m_options (interpreter)
1425     {
1426         CommandArgumentEntry arg;
1427         CommandArgumentData expression_arg;
1428 
1429         // Define the first (and only) variant of this arg.
1430         expression_arg.arg_type = eArgTypeExpression;
1431         expression_arg.arg_repetition = eArgRepeatOptional;
1432 
1433         // There is only one variant this argument could be; put it into the argument entry.
1434         arg.push_back (expression_arg);
1435 
1436         // Push the data for the first argument into the m_arguments vector.
1437         m_arguments.push_back (arg);
1438 
1439 
1440     }
1441 
1442     ~CommandObjectThreadReturn()
1443     {
1444     }
1445 
1446 protected:
1447 
1448     bool DoExecute
1449     (
1450         const char *command,
1451         CommandReturnObject &result
1452     )
1453     {
1454         // I am going to handle this by hand, because I don't want you to have to say:
1455         // "thread return -- -5".
1456         if (command[0] == '-' && command[1] == 'x')
1457         {
1458             if (command && command[2] != '\0')
1459                 result.AppendWarning("Return values ignored when returning from user called expressions");
1460 
1461             Thread *thread = m_exe_ctx.GetThreadPtr();
1462             Error error;
1463             error = thread->UnwindInnermostExpression();
1464             if (!error.Success())
1465             {
1466                 result.AppendErrorWithFormat ("Unwinding expression failed - %s.", error.AsCString());
1467                 result.SetStatus (eReturnStatusFailed);
1468             }
1469             else
1470             {
1471                 bool success = thread->SetSelectedFrameByIndexNoisily (0, result.GetOutputStream());
1472                 if (success)
1473                 {
1474                     m_exe_ctx.SetFrameSP(thread->GetSelectedFrame ());
1475                     result.SetStatus (eReturnStatusSuccessFinishResult);
1476                 }
1477                 else
1478                 {
1479                     result.AppendErrorWithFormat ("Could not select 0th frame after unwinding expression.");
1480                     result.SetStatus (eReturnStatusFailed);
1481                 }
1482             }
1483             return result.Succeeded();
1484         }
1485 
1486         ValueObjectSP return_valobj_sp;
1487 
1488         StackFrameSP frame_sp = m_exe_ctx.GetFrameSP();
1489         uint32_t frame_idx = frame_sp->GetFrameIndex();
1490 
1491         if (frame_sp->IsInlined())
1492         {
1493             result.AppendError("Don't know how to return from inlined frames.");
1494             result.SetStatus (eReturnStatusFailed);
1495             return false;
1496         }
1497 
1498         if (command && command[0] != '\0')
1499         {
1500             Target *target = m_exe_ctx.GetTargetPtr();
1501             EvaluateExpressionOptions options;
1502 
1503             options.SetUnwindOnError(true);
1504             options.SetUseDynamic(eNoDynamicValues);
1505 
1506             ExpressionResults exe_results = eExecutionSetupError;
1507             exe_results = target->EvaluateExpression (command,
1508                                                       frame_sp.get(),
1509                                                       return_valobj_sp,
1510                                                       options);
1511             if (exe_results != eExecutionCompleted)
1512             {
1513                 if (return_valobj_sp)
1514                     result.AppendErrorWithFormat("Error evaluating result expression: %s", return_valobj_sp->GetError().AsCString());
1515                 else
1516                     result.AppendErrorWithFormat("Unknown error evaluating result expression.");
1517                 result.SetStatus (eReturnStatusFailed);
1518                 return false;
1519 
1520             }
1521         }
1522 
1523         Error error;
1524         ThreadSP thread_sp = m_exe_ctx.GetThreadSP();
1525         const bool broadcast = true;
1526         error = thread_sp->ReturnFromFrame (frame_sp, return_valobj_sp, broadcast);
1527         if (!error.Success())
1528         {
1529             result.AppendErrorWithFormat("Error returning from frame %d of thread %d: %s.", frame_idx, thread_sp->GetIndexID(), error.AsCString());
1530             result.SetStatus (eReturnStatusFailed);
1531             return false;
1532         }
1533 
1534         result.SetStatus (eReturnStatusSuccessFinishResult);
1535         return true;
1536     }
1537 
1538     CommandOptions m_options;
1539 
1540 };
1541 OptionDefinition
1542 CommandObjectThreadReturn::CommandOptions::g_option_table[] =
1543 {
1544 { LLDB_OPT_SET_ALL, false, "from-expression",  'x', OptionParser::eNoArgument, NULL,               0, eArgTypeNone,     "Return from the innermost expression evaluation."},
1545 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1546 };
1547 
1548 //-------------------------------------------------------------------------
1549 // CommandObjectThreadJump
1550 //-------------------------------------------------------------------------
1551 
1552 class CommandObjectThreadJump : public CommandObjectParsed
1553 {
1554 public:
1555     class CommandOptions : public Options
1556     {
1557     public:
1558 
1559         CommandOptions (CommandInterpreter &interpreter) :
1560             Options (interpreter)
1561         {
1562             OptionParsingStarting ();
1563         }
1564 
1565         void
1566         OptionParsingStarting ()
1567         {
1568             m_filenames.Clear();
1569             m_line_num = 0;
1570             m_line_offset = 0;
1571             m_load_addr = LLDB_INVALID_ADDRESS;
1572             m_force = false;
1573         }
1574 
1575         virtual
1576         ~CommandOptions ()
1577         {
1578         }
1579 
1580         virtual Error
1581         SetOptionValue (uint32_t option_idx, const char *option_arg)
1582         {
1583             bool success;
1584             const int short_option = m_getopt_table[option_idx].val;
1585             Error error;
1586 
1587             switch (short_option)
1588             {
1589                 case 'f':
1590                     m_filenames.AppendIfUnique (FileSpec(option_arg, false));
1591                     if (m_filenames.GetSize() > 1)
1592                         return Error("only one source file expected.");
1593                     break;
1594                 case 'l':
1595                     m_line_num = Args::StringToUInt32 (option_arg, 0, 0, &success);
1596                     if (!success || m_line_num == 0)
1597                         return Error("invalid line number: '%s'.", option_arg);
1598                     break;
1599                 case 'b':
1600                     m_line_offset = Args::StringToSInt32 (option_arg, 0, 0, &success);
1601                     if (!success)
1602                         return Error("invalid line offset: '%s'.", option_arg);
1603                     break;
1604                 case 'a':
1605                     {
1606                         ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
1607                         m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
1608                     }
1609                     break;
1610                 case 'r':
1611                     m_force = true;
1612                     break;
1613 
1614                  default:
1615                     return Error("invalid short option character '%c'", short_option);
1616 
1617             }
1618             return error;
1619         }
1620 
1621         const OptionDefinition*
1622         GetDefinitions ()
1623         {
1624             return g_option_table;
1625         }
1626 
1627         FileSpecList m_filenames;
1628         uint32_t m_line_num;
1629         int32_t m_line_offset;
1630         lldb::addr_t m_load_addr;
1631         bool m_force;
1632 
1633         static OptionDefinition g_option_table[];
1634     };
1635 
1636     virtual
1637     Options *
1638     GetOptions ()
1639     {
1640         return &m_options;
1641     }
1642 
1643     CommandObjectThreadJump (CommandInterpreter &interpreter) :
1644         CommandObjectParsed (interpreter,
1645                           "thread jump",
1646                           "Sets the program counter to a new address.",
1647                           "thread jump",
1648                           eFlagRequiresFrame         |
1649                           eFlagTryTargetAPILock      |
1650                           eFlagProcessMustBeLaunched |
1651                           eFlagProcessMustBePaused   ),
1652         m_options (interpreter)
1653     {
1654     }
1655 
1656     ~CommandObjectThreadJump()
1657     {
1658     }
1659 
1660 protected:
1661 
1662     bool DoExecute (Args& args, CommandReturnObject &result)
1663     {
1664         RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext();
1665         StackFrame *frame = m_exe_ctx.GetFramePtr();
1666         Thread *thread = m_exe_ctx.GetThreadPtr();
1667         Target *target = m_exe_ctx.GetTargetPtr();
1668         const SymbolContext &sym_ctx = frame->GetSymbolContext (eSymbolContextLineEntry);
1669 
1670         if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
1671         {
1672             // Use this address directly.
1673             Address dest = Address(m_options.m_load_addr);
1674 
1675             lldb::addr_t callAddr = dest.GetCallableLoadAddress (target);
1676             if (callAddr == LLDB_INVALID_ADDRESS)
1677             {
1678                 result.AppendErrorWithFormat ("Invalid destination address.");
1679                 result.SetStatus (eReturnStatusFailed);
1680                 return false;
1681             }
1682 
1683             if (!reg_ctx->SetPC (callAddr))
1684             {
1685                 result.AppendErrorWithFormat ("Error changing PC value for thread %d.", thread->GetIndexID());
1686                 result.SetStatus (eReturnStatusFailed);
1687                 return false;
1688             }
1689         }
1690         else
1691         {
1692             // Pick either the absolute line, or work out a relative one.
1693             int32_t line = (int32_t)m_options.m_line_num;
1694             if (line == 0)
1695                 line = sym_ctx.line_entry.line + m_options.m_line_offset;
1696 
1697             // Try the current file, but override if asked.
1698             FileSpec file = sym_ctx.line_entry.file;
1699             if (m_options.m_filenames.GetSize() == 1)
1700                 file = m_options.m_filenames.GetFileSpecAtIndex(0);
1701 
1702             if (!file)
1703             {
1704                 result.AppendErrorWithFormat ("No source file available for the current location.");
1705                 result.SetStatus (eReturnStatusFailed);
1706                 return false;
1707             }
1708 
1709             std::string warnings;
1710             Error err = thread->JumpToLine (file, line, m_options.m_force, &warnings);
1711 
1712             if (err.Fail())
1713             {
1714                 result.SetError (err);
1715                 return false;
1716             }
1717 
1718             if (!warnings.empty())
1719                 result.AppendWarning (warnings.c_str());
1720         }
1721 
1722         result.SetStatus (eReturnStatusSuccessFinishResult);
1723         return true;
1724     }
1725 
1726     CommandOptions m_options;
1727 };
1728 OptionDefinition
1729 CommandObjectThreadJump::CommandOptions::g_option_table[] =
1730 {
1731     { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
1732         "Specifies the source file to jump to."},
1733 
1734     { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, 0, eArgTypeLineNum,
1735         "Specifies the line number to jump to."},
1736 
1737     { LLDB_OPT_SET_2, true, "by", 'b', OptionParser::eRequiredArgument, NULL, 0, eArgTypeOffset,
1738         "Jumps by a relative line offset from the current line."},
1739 
1740     { LLDB_OPT_SET_3, true, "address", 'a', OptionParser::eRequiredArgument, NULL, 0, eArgTypeAddressOrExpression,
1741         "Jumps to a specific address."},
1742 
1743     { LLDB_OPT_SET_1|
1744       LLDB_OPT_SET_2|
1745       LLDB_OPT_SET_3, false, "force",'r', OptionParser::eNoArgument, NULL, 0, eArgTypeNone,"Allows the PC to leave the current function."},
1746 
1747     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1748 };
1749 
1750 //-------------------------------------------------------------------------
1751 // CommandObjectMultiwordThread
1752 //-------------------------------------------------------------------------
1753 
1754 CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) :
1755     CommandObjectMultiword (interpreter,
1756                             "thread",
1757                             "A set of commands for operating on one or more threads within a running process.",
1758                             "thread <subcommand> [<subcommand-options>]")
1759 {
1760     LoadSubCommand ("backtrace",  CommandObjectSP (new CommandObjectThreadBacktrace (interpreter)));
1761     LoadSubCommand ("continue",   CommandObjectSP (new CommandObjectThreadContinue (interpreter)));
1762     LoadSubCommand ("list",       CommandObjectSP (new CommandObjectThreadList (interpreter)));
1763     LoadSubCommand ("return",     CommandObjectSP (new CommandObjectThreadReturn (interpreter)));
1764     LoadSubCommand ("jump",       CommandObjectSP (new CommandObjectThreadJump (interpreter)));
1765     LoadSubCommand ("select",     CommandObjectSP (new CommandObjectThreadSelect (interpreter)));
1766     LoadSubCommand ("until",      CommandObjectSP (new CommandObjectThreadUntil (interpreter)));
1767     LoadSubCommand ("step-in",    CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1768                                                     interpreter,
1769                                                     "thread step-in",
1770                                                     "Source level single step in specified thread (current thread, if none specified).",
1771                                                     NULL,
1772                                                     eStepTypeInto,
1773                                                     eStepScopeSource)));
1774 
1775     LoadSubCommand ("step-out",   CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1776                                                     interpreter,
1777                                                     "thread step-out",
1778                                                     "Finish executing the function of the currently selected frame and return to its call site in specified thread (current thread, if none specified).",
1779                                                     NULL,
1780                                                     eStepTypeOut,
1781                                                     eStepScopeSource)));
1782 
1783     LoadSubCommand ("step-over",   CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1784                                                     interpreter,
1785                                                     "thread step-over",
1786                                                     "Source level single step in specified thread (current thread, if none specified), stepping over calls.",
1787                                                     NULL,
1788                                                     eStepTypeOver,
1789                                                     eStepScopeSource)));
1790 
1791     LoadSubCommand ("step-inst",   CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1792                                                     interpreter,
1793                                                     "thread step-inst",
1794                                                     "Single step one instruction in specified thread (current thread, if none specified).",
1795                                                     NULL,
1796                                                     eStepTypeTrace,
1797                                                     eStepScopeInstruction)));
1798 
1799     LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1800                                                     interpreter,
1801                                                     "thread step-inst-over",
1802                                                     "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.",
1803                                                     NULL,
1804                                                     eStepTypeTraceOver,
1805                                                     eStepScopeInstruction)));
1806 }
1807 
1808 CommandObjectMultiwordThread::~CommandObjectMultiwordThread ()
1809 {
1810 }
1811 
1812 
1813