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