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