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