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