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