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