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