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/Target.h"
32 #include "lldb/Target/Thread.h"
33 #include "lldb/Target/ThreadPlan.h"
34 #include "lldb/Target/ThreadPlanStepInstruction.h"
35 #include "lldb/Target/ThreadPlanStepOut.h"
36 #include "lldb/Target/ThreadPlanStepRange.h"
37 #include "lldb/Target/ThreadPlanStepInRange.h"
38 
39 
40 using namespace lldb;
41 using namespace lldb_private;
42 
43 
44 //-------------------------------------------------------------------------
45 // CommandObjectThreadBacktrace
46 //-------------------------------------------------------------------------
47 
48 class CommandObjectThreadBacktrace : public CommandObjectParsed
49 {
50 public:
51 
52     class CommandOptions : public Options
53     {
54     public:
55 
56         CommandOptions (CommandInterpreter &interpreter) :
57             Options(interpreter)
58         {
59             // Keep default values of all options in one place: OptionParsingStarting ()
60             OptionParsingStarting ();
61         }
62 
63         virtual
64         ~CommandOptions ()
65         {
66         }
67 
68         virtual Error
69         SetOptionValue (uint32_t option_idx, const char *option_arg)
70         {
71             Error error;
72             const int short_option = m_getopt_table[option_idx].val;
73 
74             switch (short_option)
75             {
76                 case 'c':
77                 {
78                     bool success;
79                     int32_t input_count =  Args::StringToSInt32 (option_arg, -1, 0, &success);
80                     if (!success)
81                         error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option);
82                     if (input_count < -1)
83                         m_count = UINT32_MAX;
84                     else
85                         m_count = input_count;
86                 }
87                 break;
88                 case 's':
89                 {
90                     bool success;
91                     m_start =  Args::StringToUInt32 (option_arg, 0, 0, &success);
92                     if (!success)
93                         error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option);
94                 }
95                 break;
96                 default:
97                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
98                     break;
99 
100             }
101             return error;
102         }
103 
104         void
105         OptionParsingStarting ()
106         {
107             m_count = UINT32_MAX;
108             m_start = 0;
109         }
110 
111         const OptionDefinition*
112         GetDefinitions ()
113         {
114             return g_option_table;
115         }
116 
117         // Options table: Required for subclasses of Options.
118 
119         static OptionDefinition g_option_table[];
120 
121         // Instance variables to hold the values for command options.
122         uint32_t m_count;
123         uint32_t m_start;
124     };
125 
126     CommandObjectThreadBacktrace (CommandInterpreter &interpreter) :
127         CommandObjectParsed (interpreter,
128                            "thread backtrace",
129                            "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.",
130                            NULL,
131                            eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
132         m_options(interpreter)
133     {
134         CommandArgumentEntry arg;
135         CommandArgumentData thread_idx_arg;
136 
137         // Define the first (and only) variant of this arg.
138         thread_idx_arg.arg_type = eArgTypeThreadIndex;
139         thread_idx_arg.arg_repetition = eArgRepeatStar;
140 
141         // There is only one variant this argument could be; put it into the argument entry.
142         arg.push_back (thread_idx_arg);
143 
144         // Push the data for the first argument into the m_arguments vector.
145         m_arguments.push_back (arg);
146     }
147 
148     ~CommandObjectThreadBacktrace()
149     {
150     }
151 
152     virtual Options *
153     GetOptions ()
154     {
155         return &m_options;
156     }
157 
158 protected:
159     virtual bool
160     DoExecute (Args& command, CommandReturnObject &result)
161     {
162         result.SetStatus (eReturnStatusSuccessFinishResult);
163         Stream &strm = result.GetOutputStream();
164 
165         // Don't show source context when doing backtraces.
166         const uint32_t num_frames_with_source = 0;
167         if (command.GetArgumentCount() == 0)
168         {
169             ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
170             Thread *thread = exe_ctx.GetThreadPtr();
171             if (thread)
172             {
173                 // Thread::GetStatus() returns the number of frames shown.
174                 if (thread->GetStatus (strm,
175                                        m_options.m_start,
176                                        m_options.m_count,
177                                        num_frames_with_source))
178                 {
179                     result.SetStatus (eReturnStatusSuccessFinishResult);
180                 }
181             }
182             else
183             {
184                 result.AppendError ("invalid thread");
185                 result.SetStatus (eReturnStatusFailed);
186             }
187         }
188         else if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0)
189         {
190             Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
191             Mutex::Locker locker (process->GetThreadList().GetMutex());
192             uint32_t num_threads = process->GetThreadList().GetSize();
193             for (uint32_t i = 0; i < num_threads; i++)
194             {
195                 ThreadSP thread_sp = process->GetThreadList().GetThreadAtIndex(i);
196                 if (!thread_sp->GetStatus (strm,
197                                            m_options.m_start,
198                                            m_options.m_count,
199                                            num_frames_with_source))
200                 {
201                     result.AppendErrorWithFormat ("error displaying backtrace for thread: \"0x%4.4x\"\n", i);
202                     result.SetStatus (eReturnStatusFailed);
203                     return false;
204                 }
205 
206                 if (i < num_threads - 1)
207                     result.AppendMessage("");
208 
209             }
210         }
211         else
212         {
213             uint32_t num_args = command.GetArgumentCount();
214             Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
215             Mutex::Locker locker (process->GetThreadList().GetMutex());
216             std::vector<ThreadSP> thread_sps;
217 
218             for (uint32_t i = 0; i < num_args; i++)
219             {
220                 bool success;
221 
222                 uint32_t thread_idx = Args::StringToUInt32(command.GetArgumentAtIndex(i), 0, 0, &success);
223                 if (!success)
224                 {
225                     result.AppendErrorWithFormat ("invalid thread specification: \"%s\"\n", command.GetArgumentAtIndex(i));
226                     result.SetStatus (eReturnStatusFailed);
227                     return false;
228                 }
229 
230                 thread_sps.push_back(process->GetThreadList().FindThreadByIndexID(thread_idx));
231 
232                 if (!thread_sps[i])
233                 {
234                     result.AppendErrorWithFormat ("no thread with index: \"%s\"\n", command.GetArgumentAtIndex(i));
235                     result.SetStatus (eReturnStatusFailed);
236                     return false;
237                 }
238 
239             }
240 
241             for (uint32_t i = 0; i < num_args; i++)
242             {
243                 if (!thread_sps[i]->GetStatus (strm,
244                                                m_options.m_start,
245                                                m_options.m_count,
246                                                num_frames_with_source))
247                 {
248                     result.AppendErrorWithFormat ("error displaying backtrace for thread: \"%s\"\n", command.GetArgumentAtIndex(i));
249                     result.SetStatus (eReturnStatusFailed);
250                     return false;
251                 }
252 
253                 if (i < num_args - 1)
254                     result.AppendMessage("");
255             }
256         }
257         return result.Succeeded();
258     }
259 
260     CommandOptions m_options;
261 };
262 
263 OptionDefinition
264 CommandObjectThreadBacktrace::CommandOptions::g_option_table[] =
265 {
266 { LLDB_OPT_SET_1, false, "count", 'c', required_argument, NULL, 0, eArgTypeCount, "How many frames to display (-1 for all)"},
267 { LLDB_OPT_SET_1, false, "start", 's', required_argument, NULL, 0, eArgTypeFrameIndex, "Frame in which to start the backtrace"},
268 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
269 };
270 
271 enum StepScope
272 {
273     eStepScopeSource,
274     eStepScopeInstruction
275 };
276 
277 class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed
278 {
279 public:
280 
281     class CommandOptions : public Options
282     {
283     public:
284 
285         CommandOptions (CommandInterpreter &interpreter) :
286             Options (interpreter)
287         {
288             // Keep default values of all options in one place: OptionParsingStarting ()
289             OptionParsingStarting ();
290         }
291 
292         virtual
293         ~CommandOptions ()
294         {
295         }
296 
297         virtual Error
298         SetOptionValue (uint32_t option_idx, const char *option_arg)
299         {
300             Error error;
301             const int short_option = m_getopt_table[option_idx].val;
302 
303             switch (short_option)
304             {
305             case 'a':
306                 {
307                     bool success;
308                     m_avoid_no_debug =  Args::StringToBoolean (option_arg, true, &success);
309                     if (!success)
310                         error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option);
311                 }
312                 break;
313 
314             case 'm':
315                 {
316                     OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
317                     m_run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
318                 }
319                 break;
320 
321             case 'r':
322                 {
323                     m_avoid_regexp.clear();
324                     m_avoid_regexp.assign(option_arg);
325                 }
326                 break;
327 
328             case 't':
329                 {
330                     m_step_in_target.clear();
331                     m_step_in_target.assign(option_arg);
332 
333                 }
334                 break;
335             default:
336                 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
337                 break;
338 
339             }
340             return error;
341         }
342 
343         void
344         OptionParsingStarting ()
345         {
346             m_avoid_no_debug = true;
347             m_run_mode = eOnlyDuringStepping;
348             m_avoid_regexp.clear();
349             m_step_in_target.clear();
350         }
351 
352         const OptionDefinition*
353         GetDefinitions ()
354         {
355             return g_option_table;
356         }
357 
358         // Options table: Required for subclasses of Options.
359 
360         static OptionDefinition g_option_table[];
361 
362         // Instance variables to hold the values for command options.
363         bool m_avoid_no_debug;
364         RunMode m_run_mode;
365         std::string m_avoid_regexp;
366         std::string m_step_in_target;
367     };
368 
369     CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter,
370                                              const char *name,
371                                              const char *help,
372                                              const char *syntax,
373                                              uint32_t flags,
374                                              StepType step_type,
375                                              StepScope step_scope) :
376         CommandObjectParsed (interpreter, name, help, syntax, flags),
377         m_step_type (step_type),
378         m_step_scope (step_scope),
379         m_options (interpreter)
380     {
381         CommandArgumentEntry arg;
382         CommandArgumentData thread_id_arg;
383 
384         // Define the first (and only) variant of this arg.
385         thread_id_arg.arg_type = eArgTypeThreadID;
386         thread_id_arg.arg_repetition = eArgRepeatOptional;
387 
388         // There is only one variant this argument could be; put it into the argument entry.
389         arg.push_back (thread_id_arg);
390 
391         // Push the data for the first argument into the m_arguments vector.
392         m_arguments.push_back (arg);
393     }
394 
395     virtual
396     ~CommandObjectThreadStepWithTypeAndScope ()
397     {
398     }
399 
400     virtual
401     Options *
402     GetOptions ()
403     {
404         return &m_options;
405     }
406 
407 protected:
408     virtual bool
409     DoExecute (Args& command, CommandReturnObject &result)
410     {
411         Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
412         bool synchronous_execution = m_interpreter.GetSynchronous();
413 
414         if (process == NULL)
415         {
416             result.AppendError ("need a valid process to step");
417             result.SetStatus (eReturnStatusFailed);
418 
419         }
420         else
421         {
422             const uint32_t num_threads = process->GetThreadList().GetSize();
423             Thread *thread = NULL;
424 
425             if (command.GetArgumentCount() == 0)
426             {
427                 thread = process->GetThreadList().GetSelectedThread().get();
428                 if (thread == NULL)
429                 {
430                     result.AppendError ("no selected thread in process");
431                     result.SetStatus (eReturnStatusFailed);
432                     return false;
433                 }
434             }
435             else
436             {
437                 const char *thread_idx_cstr = command.GetArgumentAtIndex(0);
438                 uint32_t step_thread_idx = Args::StringToUInt32 (thread_idx_cstr, LLDB_INVALID_INDEX32);
439                 if (step_thread_idx == LLDB_INVALID_INDEX32)
440                 {
441                     result.AppendErrorWithFormat ("invalid thread index '%s'.\n", thread_idx_cstr);
442                     result.SetStatus (eReturnStatusFailed);
443                     return false;
444                 }
445                 thread = process->GetThreadList().FindThreadByIndexID(step_thread_idx).get();
446                 if (thread == NULL)
447                 {
448                     result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
449                                                   step_thread_idx, num_threads);
450                     result.SetStatus (eReturnStatusFailed);
451                     return false;
452                 }
453             }
454 
455             const bool abort_other_plans = false;
456             const lldb::RunMode stop_other_threads = m_options.m_run_mode;
457 
458             // This is a bit unfortunate, but not all the commands in this command object support
459             // only while stepping, so I use the bool for them.
460             bool bool_stop_other_threads;
461             if (m_options.m_run_mode == eAllThreads)
462                 bool_stop_other_threads = false;
463             else if (m_options.m_run_mode == eOnlyDuringStepping)
464             {
465                 if (m_step_type == eStepTypeOut)
466                     bool_stop_other_threads = false;
467                 else
468                     bool_stop_other_threads = true;
469             }
470             else
471                 bool_stop_other_threads = true;
472 
473             ThreadPlan *new_plan = NULL;
474 
475             if (m_step_type == eStepTypeInto)
476             {
477                 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
478 
479                 if (frame->HasDebugInformation ())
480                 {
481                     new_plan = thread->QueueThreadPlanForStepInRange (abort_other_plans,
482                                                                     frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
483                                                                     frame->GetSymbolContext(eSymbolContextEverything),
484                                                                     m_options.m_step_in_target.c_str(),
485                                                                     stop_other_threads,
486                                                                     m_options.m_avoid_no_debug);
487                     if (new_plan && !m_options.m_avoid_regexp.empty())
488                     {
489                         ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan);
490                         step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str());
491                     }
492                 }
493                 else
494                     new_plan = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
495 
496             }
497             else if (m_step_type == eStepTypeOver)
498             {
499                 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
500 
501                 if (frame->HasDebugInformation())
502                     new_plan = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
503                                                                         frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
504                                                                         frame->GetSymbolContext(eSymbolContextEverything),
505                                                                         stop_other_threads);
506                 else
507                     new_plan = thread->QueueThreadPlanForStepSingleInstruction (true,
508                                                                                 abort_other_plans,
509                                                                                 bool_stop_other_threads);
510 
511             }
512             else if (m_step_type == eStepTypeTrace)
513             {
514                 new_plan = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
515             }
516             else if (m_step_type == eStepTypeTraceOver)
517             {
518                 new_plan = thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads);
519             }
520             else if (m_step_type == eStepTypeOut)
521             {
522                 new_plan = thread->QueueThreadPlanForStepOut (abort_other_plans,
523                                                               NULL,
524                                                               false,
525                                                               bool_stop_other_threads,
526                                                               eVoteYes,
527                                                               eVoteNoOpinion,
528                                                               thread->GetSelectedFrameIndex());
529             }
530             else
531             {
532                 result.AppendError ("step type is not supported");
533                 result.SetStatus (eReturnStatusFailed);
534                 return false;
535             }
536 
537             // If we got a new plan, then set it to be a master plan (User level Plans should be master plans
538             // so that they can be interruptible).  Then resume the process.
539 
540             if (new_plan != NULL)
541             {
542                 new_plan->SetIsMasterPlan (true);
543                 new_plan->SetOkayToDiscard (false);
544 
545                 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
546                 process->Resume ();
547 
548 
549                 if (synchronous_execution)
550                 {
551                     StateType state = process->WaitForProcessToStop (NULL);
552 
553                     //EventSP event_sp;
554                     //StateType state = process->WaitForStateChangedEvents (NULL, event_sp);
555                     //while (! StateIsStoppedState (state))
556                     //  {
557                     //    state = process->WaitForStateChangedEvents (NULL, event_sp);
558                     //  }
559                     process->GetThreadList().SetSelectedThreadByID (thread->GetID());
560                     result.SetDidChangeProcessState (true);
561                     result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
562                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
563                 }
564                 else
565                 {
566                     result.SetStatus (eReturnStatusSuccessContinuingNoResult);
567                 }
568             }
569             else
570             {
571                 result.AppendError ("Couldn't find thread plan to implement step type.");
572                 result.SetStatus (eReturnStatusFailed);
573             }
574         }
575         return result.Succeeded();
576     }
577 
578 protected:
579     StepType m_step_type;
580     StepScope m_step_scope;
581     CommandOptions m_options;
582 };
583 
584 static OptionEnumValueElement
585 g_tri_running_mode[] =
586 {
587 { eOnlyThisThread,     "this-thread",    "Run only this thread"},
588 { eAllThreads,         "all-threads",    "Run all threads"},
589 { eOnlyDuringStepping, "while-stepping", "Run only this thread while stepping"},
590 { 0, NULL, NULL }
591 };
592 
593 static OptionEnumValueElement
594 g_duo_running_mode[] =
595 {
596 { eOnlyThisThread,     "this-thread",    "Run only this thread"},
597 { eAllThreads,         "all-threads",    "Run all threads"},
598 { 0, NULL, NULL }
599 };
600 
601 OptionDefinition
602 CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] =
603 {
604 { LLDB_OPT_SET_1, false, "avoid-no-debug",  'a', required_argument, NULL,               0, eArgTypeBoolean,     "A boolean value that sets whether step-in will step over functions with no debug information."},
605 { LLDB_OPT_SET_1, false, "run-mode",        'm', required_argument, g_tri_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping the current thread."},
606 { LLDB_OPT_SET_1, false, "step-over-regexp",'r', required_argument, NULL,               0, eArgTypeRegularExpression,   "A regular expression that defines function names to not to stop at when stepping in."},
607 { LLDB_OPT_SET_1, false, "step-in-target",  't', required_argument, NULL,               0, eArgTypeFunctionName,   "The name of the directly called function step in should stop at when stepping into."},
608 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
609 };
610 
611 
612 //-------------------------------------------------------------------------
613 // CommandObjectThreadContinue
614 //-------------------------------------------------------------------------
615 
616 class CommandObjectThreadContinue : public CommandObjectParsed
617 {
618 public:
619 
620     CommandObjectThreadContinue (CommandInterpreter &interpreter) :
621         CommandObjectParsed (interpreter,
622                              "thread continue",
623                              "Continue execution of one or more threads in an active process.",
624                              NULL,
625                              eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
626     {
627         CommandArgumentEntry arg;
628         CommandArgumentData thread_idx_arg;
629 
630         // Define the first (and only) variant of this arg.
631         thread_idx_arg.arg_type = eArgTypeThreadIndex;
632         thread_idx_arg.arg_repetition = eArgRepeatPlus;
633 
634         // There is only one variant this argument could be; put it into the argument entry.
635         arg.push_back (thread_idx_arg);
636 
637         // Push the data for the first argument into the m_arguments vector.
638         m_arguments.push_back (arg);
639     }
640 
641 
642     virtual
643     ~CommandObjectThreadContinue ()
644     {
645     }
646 
647     virtual bool
648     DoExecute (Args& command, CommandReturnObject &result)
649     {
650         bool synchronous_execution = m_interpreter.GetSynchronous ();
651 
652         if (!m_interpreter.GetDebugger().GetSelectedTarget().get())
653         {
654             result.AppendError ("invalid target, create a debug target using the 'target create' command");
655             result.SetStatus (eReturnStatusFailed);
656             return false;
657         }
658 
659         Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
660         if (process == NULL)
661         {
662             result.AppendError ("no process exists. Cannot continue");
663             result.SetStatus (eReturnStatusFailed);
664             return false;
665         }
666 
667         StateType state = process->GetState();
668         if ((state == eStateCrashed) || (state == eStateStopped) || (state == eStateSuspended))
669         {
670             Mutex::Locker locker (process->GetThreadList().GetMutex());
671             const uint32_t num_threads = process->GetThreadList().GetSize();
672             const size_t argc = command.GetArgumentCount();
673             if (argc > 0)
674             {
675                 std::vector<Thread *> resume_threads;
676                 for (uint32_t i=0; i<argc; ++i)
677                 {
678                     bool success;
679                     const int base = 0;
680                     uint32_t thread_idx = Args::StringToUInt32 (command.GetArgumentAtIndex(i), LLDB_INVALID_INDEX32, base, &success);
681                     if (success)
682                     {
683                         Thread *thread = process->GetThreadList().FindThreadByIndexID(thread_idx).get();
684 
685                         if (thread)
686                         {
687                             resume_threads.push_back(thread);
688                         }
689                         else
690                         {
691                             result.AppendErrorWithFormat("invalid thread index %u.\n", thread_idx);
692                             result.SetStatus (eReturnStatusFailed);
693                             return false;
694                         }
695                     }
696                     else
697                     {
698                         result.AppendErrorWithFormat ("invalid thread index argument: \"%s\".\n", command.GetArgumentAtIndex(i));
699                         result.SetStatus (eReturnStatusFailed);
700                         return false;
701                     }
702                 }
703 
704                 if (resume_threads.empty())
705                 {
706                     result.AppendError ("no valid thread indexes were specified");
707                     result.SetStatus (eReturnStatusFailed);
708                     return false;
709                 }
710                 else
711                 {
712                     if (resume_threads.size() == 1)
713                         result.AppendMessageWithFormat ("Resuming thread: ");
714                     else
715                         result.AppendMessageWithFormat ("Resuming threads: ");
716 
717                     for (uint32_t idx=0; idx<num_threads; ++idx)
718                     {
719                         Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
720                         std::vector<Thread *>::iterator this_thread_pos = find(resume_threads.begin(), resume_threads.end(), thread);
721 
722                         if (this_thread_pos != resume_threads.end())
723                         {
724                             resume_threads.erase(this_thread_pos);
725                             if (resume_threads.size() > 0)
726                                 result.AppendMessageWithFormat ("%u, ", thread->GetIndexID());
727                             else
728                                 result.AppendMessageWithFormat ("%u ", thread->GetIndexID());
729 
730                             thread->SetResumeState (eStateRunning);
731                         }
732                         else
733                         {
734                             thread->SetResumeState (eStateSuspended);
735                         }
736                     }
737                     result.AppendMessageWithFormat ("in process %" PRIu64 "\n", process->GetID());
738                 }
739             }
740             else
741             {
742                 Thread *current_thread = process->GetThreadList().GetSelectedThread().get();
743                 if (current_thread == NULL)
744                 {
745                     result.AppendError ("the process doesn't have a current thread");
746                     result.SetStatus (eReturnStatusFailed);
747                     return false;
748                 }
749                 // Set the actions that the threads should each take when resuming
750                 for (uint32_t idx=0; idx<num_threads; ++idx)
751                 {
752                     Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
753                     if (thread == current_thread)
754                     {
755                         result.AppendMessageWithFormat ("Resuming thread 0x%4.4" PRIx64 " in process %" PRIu64 "\n", thread->GetID(), process->GetID());
756                         thread->SetResumeState (eStateRunning);
757                     }
758                     else
759                     {
760                         thread->SetResumeState (eStateSuspended);
761                     }
762                 }
763             }
764 
765             Error error (process->Resume());
766             if (error.Success())
767             {
768                 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
769                 if (synchronous_execution)
770                 {
771                     state = process->WaitForProcessToStop (NULL);
772 
773                     result.SetDidChangeProcessState (true);
774                     result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
775                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
776                 }
777                 else
778                 {
779                     result.SetStatus (eReturnStatusSuccessContinuingNoResult);
780                 }
781             }
782             else
783             {
784                 result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString());
785                 result.SetStatus (eReturnStatusFailed);
786             }
787         }
788         else
789         {
790             result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
791                                           StateAsCString(state));
792             result.SetStatus (eReturnStatusFailed);
793         }
794 
795         return result.Succeeded();
796     }
797 
798 };
799 
800 //-------------------------------------------------------------------------
801 // CommandObjectThreadUntil
802 //-------------------------------------------------------------------------
803 
804 class CommandObjectThreadUntil : public CommandObjectParsed
805 {
806 public:
807 
808     class CommandOptions : public Options
809     {
810     public:
811         uint32_t m_thread_idx;
812         uint32_t m_frame_idx;
813 
814         CommandOptions (CommandInterpreter &interpreter) :
815             Options (interpreter),
816             m_thread_idx(LLDB_INVALID_THREAD_ID),
817             m_frame_idx(LLDB_INVALID_FRAME_ID)
818         {
819             // Keep default values of all options in one place: OptionParsingStarting ()
820             OptionParsingStarting ();
821         }
822 
823         virtual
824         ~CommandOptions ()
825         {
826         }
827 
828         virtual Error
829         SetOptionValue (uint32_t option_idx, const char *option_arg)
830         {
831             Error error;
832             const int short_option = m_getopt_table[option_idx].val;
833 
834             switch (short_option)
835             {
836                 case 't':
837                 {
838                     m_thread_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_INDEX32);
839                     if (m_thread_idx == LLDB_INVALID_INDEX32)
840                     {
841                         error.SetErrorStringWithFormat ("invalid thread index '%s'", option_arg);
842                     }
843                 }
844                 break;
845                 case 'f':
846                 {
847                     m_frame_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_FRAME_ID);
848                     if (m_frame_idx == LLDB_INVALID_FRAME_ID)
849                     {
850                         error.SetErrorStringWithFormat ("invalid frame index '%s'", option_arg);
851                     }
852                 }
853                 break;
854                 case 'm':
855                 {
856                     OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
857                     lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
858 
859                     if (error.Success())
860                     {
861                         if (run_mode == eAllThreads)
862                             m_stop_others = false;
863                         else
864                             m_stop_others = true;
865                     }
866                 }
867                 break;
868                 default:
869                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
870                     break;
871 
872             }
873             return error;
874         }
875 
876         void
877         OptionParsingStarting ()
878         {
879             m_thread_idx = LLDB_INVALID_THREAD_ID;
880             m_frame_idx = 0;
881             m_stop_others = false;
882         }
883 
884         const OptionDefinition*
885         GetDefinitions ()
886         {
887             return g_option_table;
888         }
889 
890         uint32_t m_step_thread_idx;
891         bool m_stop_others;
892 
893         // Options table: Required for subclasses of Options.
894 
895         static OptionDefinition g_option_table[];
896 
897         // Instance variables to hold the values for command options.
898     };
899 
900     CommandObjectThreadUntil (CommandInterpreter &interpreter) :
901         CommandObjectParsed (interpreter,
902                              "thread until",
903                              "Run the current or specified thread until it reaches a given line number or leaves the current function.",
904                              NULL,
905                              eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
906         m_options (interpreter)
907     {
908         CommandArgumentEntry arg;
909         CommandArgumentData line_num_arg;
910 
911         // Define the first (and only) variant of this arg.
912         line_num_arg.arg_type = eArgTypeLineNum;
913         line_num_arg.arg_repetition = eArgRepeatPlain;
914 
915         // There is only one variant this argument could be; put it into the argument entry.
916         arg.push_back (line_num_arg);
917 
918         // Push the data for the first argument into the m_arguments vector.
919         m_arguments.push_back (arg);
920     }
921 
922 
923     virtual
924     ~CommandObjectThreadUntil ()
925     {
926     }
927 
928     virtual
929     Options *
930     GetOptions ()
931     {
932         return &m_options;
933     }
934 
935 protected:
936     virtual bool
937     DoExecute (Args& command, CommandReturnObject &result)
938     {
939         bool synchronous_execution = m_interpreter.GetSynchronous ();
940 
941         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
942         if (target == NULL)
943         {
944             result.AppendError ("invalid target, create a debug target using the 'target create' command");
945             result.SetStatus (eReturnStatusFailed);
946             return false;
947         }
948 
949         Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
950         if (process == NULL)
951         {
952             result.AppendError ("need a valid process to step");
953             result.SetStatus (eReturnStatusFailed);
954 
955         }
956         else
957         {
958             Thread *thread = NULL;
959             uint32_t line_number;
960 
961             if (command.GetArgumentCount() != 1)
962             {
963                 result.AppendErrorWithFormat ("No line number provided:\n%s", GetSyntax());
964                 result.SetStatus (eReturnStatusFailed);
965                 return false;
966             }
967 
968             line_number = Args::StringToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX);
969             if (line_number == UINT32_MAX)
970             {
971                 result.AppendErrorWithFormat ("invalid line number: '%s'.\n", command.GetArgumentAtIndex(0));
972                 result.SetStatus (eReturnStatusFailed);
973                 return false;
974             }
975 
976             if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID)
977             {
978                 thread = process->GetThreadList().GetSelectedThread().get();
979             }
980             else
981             {
982                 thread = process->GetThreadList().FindThreadByIndexID(m_options.m_thread_idx).get();
983             }
984 
985             if (thread == NULL)
986             {
987                 const uint32_t num_threads = process->GetThreadList().GetSize();
988                 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
989                                               m_options.m_thread_idx,
990                                               num_threads);
991                 result.SetStatus (eReturnStatusFailed);
992                 return false;
993             }
994 
995             const bool abort_other_plans = false;
996 
997             StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get();
998             if (frame == NULL)
999             {
1000 
1001                 result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n",
1002                                               m_options.m_frame_idx,
1003                                               m_options.m_thread_idx);
1004                 result.SetStatus (eReturnStatusFailed);
1005                 return false;
1006             }
1007 
1008             ThreadPlan *new_plan = NULL;
1009 
1010             if (frame->HasDebugInformation ())
1011             {
1012                 // Finally we got here...  Translate the given line number to a bunch of addresses:
1013                 SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit));
1014                 LineTable *line_table = NULL;
1015                 if (sc.comp_unit)
1016                     line_table = sc.comp_unit->GetLineTable();
1017 
1018                 if (line_table == NULL)
1019                 {
1020                     result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n",
1021                                                  m_options.m_frame_idx, m_options.m_thread_idx);
1022                     result.SetStatus (eReturnStatusFailed);
1023                     return false;
1024                 }
1025 
1026                 LineEntry function_start;
1027                 uint32_t index_ptr = 0, end_ptr;
1028                 std::vector<addr_t> address_list;
1029 
1030                 // Find the beginning & end index of the
1031                 AddressRange fun_addr_range = sc.function->GetAddressRange();
1032                 Address fun_start_addr = fun_addr_range.GetBaseAddress();
1033                 line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr);
1034 
1035                 Address fun_end_addr(fun_start_addr.GetSection(),
1036                                      fun_start_addr.GetOffset() + fun_addr_range.GetByteSize());
1037                 line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr);
1038 
1039                 bool all_in_function = true;
1040 
1041                 while (index_ptr <= end_ptr)
1042                 {
1043                     LineEntry line_entry;
1044                     const bool exact = false;
1045                     index_ptr = sc.comp_unit->FindLineEntry(index_ptr, line_number, sc.comp_unit, exact, &line_entry);
1046                     if (index_ptr == UINT32_MAX)
1047                         break;
1048 
1049                     addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target);
1050                     if (address != LLDB_INVALID_ADDRESS)
1051                     {
1052                         if (fun_addr_range.ContainsLoadAddress (address, target))
1053                             address_list.push_back (address);
1054                         else
1055                             all_in_function = false;
1056                     }
1057                     index_ptr++;
1058                 }
1059 
1060                 if (address_list.size() == 0)
1061                 {
1062                     if (all_in_function)
1063                         result.AppendErrorWithFormat ("No line entries matching until target.\n");
1064                     else
1065                         result.AppendErrorWithFormat ("Until target outside of the current function.\n");
1066 
1067                     result.SetStatus (eReturnStatusFailed);
1068                     return false;
1069                 }
1070 
1071                 new_plan = thread->QueueThreadPlanForStepUntil (abort_other_plans,
1072                                                                 &address_list.front(),
1073                                                                 address_list.size(),
1074                                                                 m_options.m_stop_others,
1075                                                                 m_options.m_frame_idx);
1076                 // User level plans should be master plans so they can be interrupted (e.g. by hitting a breakpoint)
1077                 // and other plans executed by the user (stepping around the breakpoint) and then a "continue"
1078                 // will resume the original plan.
1079                 new_plan->SetIsMasterPlan (true);
1080                 new_plan->SetOkayToDiscard(false);
1081             }
1082             else
1083             {
1084                 result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n",
1085                                               m_options.m_frame_idx,
1086                                               m_options.m_thread_idx);
1087                 result.SetStatus (eReturnStatusFailed);
1088                 return false;
1089 
1090             }
1091 
1092             process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx);
1093             Error error (process->Resume ());
1094             if (error.Success())
1095             {
1096                 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
1097                 if (synchronous_execution)
1098                 {
1099                     StateType state = process->WaitForProcessToStop (NULL);
1100 
1101                     result.SetDidChangeProcessState (true);
1102                     result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
1103                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
1104                 }
1105                 else
1106                 {
1107                     result.SetStatus (eReturnStatusSuccessContinuingNoResult);
1108                 }
1109             }
1110             else
1111             {
1112                 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
1113                 result.SetStatus (eReturnStatusFailed);
1114             }
1115 
1116         }
1117         return result.Succeeded();
1118     }
1119 
1120     CommandOptions m_options;
1121 
1122 };
1123 
1124 OptionDefinition
1125 CommandObjectThreadUntil::CommandOptions::g_option_table[] =
1126 {
1127 { LLDB_OPT_SET_1, false, "frame",   'f', required_argument, NULL,               0, eArgTypeFrameIndex,   "Frame index for until operation - defaults to 0"},
1128 { LLDB_OPT_SET_1, false, "thread",  't', required_argument, NULL,               0, eArgTypeThreadIndex,  "Thread index for the thread for until operation"},
1129 { LLDB_OPT_SET_1, false, "run-mode",'m', required_argument, g_duo_running_mode, 0, eArgTypeRunMode,"Determine how to run other threads while stepping this one"},
1130 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1131 };
1132 
1133 
1134 //-------------------------------------------------------------------------
1135 // CommandObjectThreadSelect
1136 //-------------------------------------------------------------------------
1137 
1138 class CommandObjectThreadSelect : public CommandObjectParsed
1139 {
1140 public:
1141 
1142     CommandObjectThreadSelect (CommandInterpreter &interpreter) :
1143         CommandObjectParsed (interpreter,
1144                              "thread select",
1145                              "Select a thread as the currently active thread.",
1146                              NULL,
1147                              eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
1148     {
1149         CommandArgumentEntry arg;
1150         CommandArgumentData thread_idx_arg;
1151 
1152         // Define the first (and only) variant of this arg.
1153         thread_idx_arg.arg_type = eArgTypeThreadIndex;
1154         thread_idx_arg.arg_repetition = eArgRepeatPlain;
1155 
1156         // There is only one variant this argument could be; put it into the argument entry.
1157         arg.push_back (thread_idx_arg);
1158 
1159         // Push the data for the first argument into the m_arguments vector.
1160         m_arguments.push_back (arg);
1161     }
1162 
1163 
1164     virtual
1165     ~CommandObjectThreadSelect ()
1166     {
1167     }
1168 
1169 protected:
1170     virtual bool
1171     DoExecute (Args& command, CommandReturnObject &result)
1172     {
1173         Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
1174         if (process == NULL)
1175         {
1176             result.AppendError ("no process");
1177             result.SetStatus (eReturnStatusFailed);
1178             return false;
1179         }
1180         else if (command.GetArgumentCount() != 1)
1181         {
1182             result.AppendErrorWithFormat("'%s' takes exactly one thread index argument:\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
1183             result.SetStatus (eReturnStatusFailed);
1184             return false;
1185         }
1186 
1187         uint32_t index_id = Args::StringToUInt32(command.GetArgumentAtIndex(0), 0, 0);
1188 
1189         Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get();
1190         if (new_thread == NULL)
1191         {
1192             result.AppendErrorWithFormat ("invalid thread #%s.\n", command.GetArgumentAtIndex(0));
1193             result.SetStatus (eReturnStatusFailed);
1194             return false;
1195         }
1196 
1197         process->GetThreadList().SetSelectedThreadByID(new_thread->GetID(), true);
1198         result.SetStatus (eReturnStatusSuccessFinishNoResult);
1199 
1200         return result.Succeeded();
1201     }
1202 
1203 };
1204 
1205 
1206 //-------------------------------------------------------------------------
1207 // CommandObjectThreadList
1208 //-------------------------------------------------------------------------
1209 
1210 class CommandObjectThreadList : public CommandObjectParsed
1211 {
1212 public:
1213 
1214 
1215     CommandObjectThreadList (CommandInterpreter &interpreter):
1216         CommandObjectParsed (interpreter,
1217                              "thread list",
1218                              "Show a summary of all current threads in a process.",
1219                              "thread list",
1220                              eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
1221     {
1222     }
1223 
1224     ~CommandObjectThreadList()
1225     {
1226     }
1227 
1228 protected:
1229     bool
1230     DoExecute (Args& command, CommandReturnObject &result)
1231     {
1232         Stream &strm = result.GetOutputStream();
1233         result.SetStatus (eReturnStatusSuccessFinishNoResult);
1234         ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
1235         Process *process = exe_ctx.GetProcessPtr();
1236         if (process)
1237         {
1238             const bool only_threads_with_stop_reason = false;
1239             const uint32_t start_frame = 0;
1240             const uint32_t num_frames = 0;
1241             const uint32_t num_frames_with_source = 0;
1242             process->GetStatus(strm);
1243             process->GetThreadStatus (strm,
1244                                       only_threads_with_stop_reason,
1245                                       start_frame,
1246                                       num_frames,
1247                                       num_frames_with_source);
1248         }
1249         else
1250         {
1251             result.AppendError ("no current location or status available");
1252             result.SetStatus (eReturnStatusFailed);
1253         }
1254         return result.Succeeded();
1255     }
1256 };
1257 
1258 class CommandObjectThreadReturn : public CommandObjectRaw
1259 {
1260 public:
1261     CommandObjectThreadReturn (CommandInterpreter &interpreter) :
1262         CommandObjectRaw (interpreter,
1263                           "thread return",
1264                           "Return from the currently selected frame, short-circuiting execution of the frames below it, with an optional return value.",
1265                           "thread return",
1266                           eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
1267     {
1268         CommandArgumentEntry arg;
1269         CommandArgumentData expression_arg;
1270 
1271         // Define the first (and only) variant of this arg.
1272         expression_arg.arg_type = eArgTypeExpression;
1273         expression_arg.arg_repetition = eArgRepeatPlain;
1274 
1275         // There is only one variant this argument could be; put it into the argument entry.
1276         arg.push_back (expression_arg);
1277 
1278         // Push the data for the first argument into the m_arguments vector.
1279         m_arguments.push_back (arg);
1280 
1281 
1282     }
1283 
1284     ~CommandObjectThreadReturn()
1285     {
1286     }
1287 
1288 protected:
1289 
1290     bool DoExecute
1291     (
1292         const char *command,
1293         CommandReturnObject &result
1294     )
1295     {
1296         // If there is a command string, pass it to the expression parser:
1297         ExecutionContext exe_ctx = m_interpreter.GetExecutionContext();
1298         if (!(exe_ctx.HasProcessScope() && exe_ctx.HasThreadScope() && exe_ctx.HasFrameScope()))
1299         {
1300             result.AppendError("Must have selected process, thread and frame for thread return.");
1301             result.SetStatus (eReturnStatusFailed);
1302             return false;
1303         }
1304 
1305         ValueObjectSP return_valobj_sp;
1306 
1307         StackFrameSP frame_sp = exe_ctx.GetFrameSP();
1308         uint32_t frame_idx = frame_sp->GetFrameIndex();
1309 
1310         if (frame_sp->IsInlined())
1311         {
1312             result.AppendError("Don't know how to return from inlined frames.");
1313             result.SetStatus (eReturnStatusFailed);
1314             return false;
1315         }
1316 
1317         if (command && command[0] != '\0')
1318         {
1319             Target *target = exe_ctx.GetTargetPtr();
1320             EvaluateExpressionOptions options;
1321 
1322             options.SetUnwindOnError(true);
1323             options.SetUseDynamic(eNoDynamicValues);
1324 
1325             ExecutionResults exe_results = eExecutionSetupError;
1326             exe_results = target->EvaluateExpression (command,
1327                                                       frame_sp.get(),
1328                                                       return_valobj_sp,
1329                                                       options);
1330             if (exe_results != eExecutionCompleted)
1331             {
1332                 if (return_valobj_sp)
1333                     result.AppendErrorWithFormat("Error evaluating result expression: %s", return_valobj_sp->GetError().AsCString());
1334                 else
1335                     result.AppendErrorWithFormat("Unknown error evaluating result expression.");
1336                 result.SetStatus (eReturnStatusFailed);
1337                 return false;
1338 
1339             }
1340         }
1341 
1342         Error error;
1343         ThreadSP thread_sp = exe_ctx.GetThreadSP();
1344         const bool broadcast = true;
1345         error = thread_sp->ReturnFromFrame (frame_sp, return_valobj_sp, broadcast);
1346         if (!error.Success())
1347         {
1348             result.AppendErrorWithFormat("Error returning from frame %d of thread %d: %s.", frame_idx, thread_sp->GetIndexID(), error.AsCString());
1349             result.SetStatus (eReturnStatusFailed);
1350             return false;
1351         }
1352 
1353         result.SetStatus (eReturnStatusSuccessFinishResult);
1354         return true;
1355     }
1356 
1357 };
1358 
1359 //-------------------------------------------------------------------------
1360 // CommandObjectMultiwordThread
1361 //-------------------------------------------------------------------------
1362 
1363 CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) :
1364     CommandObjectMultiword (interpreter,
1365                             "thread",
1366                             "A set of commands for operating on one or more threads within a running process.",
1367                             "thread <subcommand> [<subcommand-options>]")
1368 {
1369     LoadSubCommand ("backtrace",  CommandObjectSP (new CommandObjectThreadBacktrace (interpreter)));
1370     LoadSubCommand ("continue",   CommandObjectSP (new CommandObjectThreadContinue (interpreter)));
1371     LoadSubCommand ("list",       CommandObjectSP (new CommandObjectThreadList (interpreter)));
1372     LoadSubCommand ("return",     CommandObjectSP (new CommandObjectThreadReturn (interpreter)));
1373     LoadSubCommand ("select",     CommandObjectSP (new CommandObjectThreadSelect (interpreter)));
1374     LoadSubCommand ("until",      CommandObjectSP (new CommandObjectThreadUntil (interpreter)));
1375     LoadSubCommand ("step-in",    CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1376                                                     interpreter,
1377                                                     "thread step-in",
1378                                                     "Source level single step in specified thread (current thread, if none specified).",
1379                                                     NULL,
1380                                                     eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1381                                                     eStepTypeInto,
1382                                                     eStepScopeSource)));
1383 
1384     LoadSubCommand ("step-out",   CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1385                                                     interpreter,
1386                                                     "thread step-out",
1387                                                     "Finish executing the function of the currently selected frame and return to its call site in specified thread (current thread, if none specified).",
1388                                                     NULL,
1389                                                     eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1390                                                     eStepTypeOut,
1391                                                     eStepScopeSource)));
1392 
1393     LoadSubCommand ("step-over",   CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1394                                                     interpreter,
1395                                                     "thread step-over",
1396                                                     "Source level single step in specified thread (current thread, if none specified), stepping over calls.",
1397                                                     NULL,
1398                                                     eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1399                                                     eStepTypeOver,
1400                                                     eStepScopeSource)));
1401 
1402     LoadSubCommand ("step-inst",   CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1403                                                     interpreter,
1404                                                     "thread step-inst",
1405                                                     "Single step one instruction in specified thread (current thread, if none specified).",
1406                                                     NULL,
1407                                                     eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1408                                                     eStepTypeTrace,
1409                                                     eStepScopeInstruction)));
1410 
1411     LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1412                                                     interpreter,
1413                                                     "thread step-inst-over",
1414                                                     "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.",
1415                                                     NULL,
1416                                                     eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1417                                                     eStepTypeTraceOver,
1418                                                     eStepScopeInstruction)));
1419 }
1420 
1421 CommandObjectMultiwordThread::~CommandObjectMultiwordThread ()
1422 {
1423 }
1424 
1425 
1426