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