xref: /llvm-project/lldb/source/Commands/CommandObjectThread.cpp (revision f6b8b581846b3d7a0853d89f54b4ac9f94ff5a0e)
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.AppendMessage (strm.GetString().c_str());
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 (CommandInterpreter &interpreter) :
253             Options(interpreter)
254         {
255             // Keep default values of all options in one place: OptionParsingStarting ()
256             OptionParsingStarting ();
257         }
258 
259         virtual
260         ~CommandOptions ()
261         {
262         }
263 
264         virtual Error
265         SetOptionValue (uint32_t 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         OptionParsingStarting ()
302         {
303             m_count = -1;
304             m_start = 0;
305         }
306 
307         const OptionDefinition*
308         GetDefinitions ()
309         {
310             return g_option_table;
311         }
312 
313         // Options table: Required for subclasses of Options.
314 
315         static OptionDefinition g_option_table[];
316 
317         // Instance variables to hold the values for command options.
318         uint32_t m_count;
319         uint32_t m_start;
320     };
321 
322     CommandObjectThreadBacktrace (CommandInterpreter &interpreter) :
323         CommandObject (interpreter,
324                        "thread backtrace",
325                        "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.",
326                        NULL,
327                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
328         m_options(interpreter)
329     {
330         CommandArgumentEntry arg;
331         CommandArgumentData thread_idx_arg;
332 
333         // Define the first (and only) variant of this arg.
334         thread_idx_arg.arg_type = eArgTypeThreadIndex;
335         thread_idx_arg.arg_repetition = eArgRepeatStar;
336 
337         // There is only one variant this argument could be; put it into the argument entry.
338         arg.push_back (thread_idx_arg);
339 
340         // Push the data for the first argument into the m_arguments vector.
341         m_arguments.push_back (arg);
342     }
343 
344     ~CommandObjectThreadBacktrace()
345     {
346     }
347 
348     virtual Options *
349     GetOptions ()
350     {
351         return &m_options;
352     }
353 
354     virtual bool
355     Execute (Args& command, CommandReturnObject &result)
356     {
357 
358         bool show_frame_info = true;
359         uint32_t num_frames_with_source = 0; // Don't show any frames with source when backtracing
360 
361         result.SetStatus (eReturnStatusSuccessFinishResult);
362 
363         if (command.GetArgumentCount() == 0)
364         {
365             ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
366             if (exe_ctx.thread)
367             {
368                 if (DisplayFramesForExecutionContext (exe_ctx.thread,
369                                                       m_interpreter,
370                                                       result.GetOutputStream(),
371                                                       m_options.m_start,
372                                                       m_options.m_count,
373                                                       show_frame_info,
374                                                       num_frames_with_source,
375                                                       3,
376                                                       3))
377                 {
378                     result.SetStatus (eReturnStatusSuccessFinishResult);
379                 }
380             }
381             else
382             {
383                 result.AppendError ("invalid thread");
384                 result.SetStatus (eReturnStatusFailed);
385             }
386         }
387         else if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0)
388         {
389             Process *process = m_interpreter.GetExecutionContext().process;
390             uint32_t num_threads = process->GetThreadList().GetSize();
391             for (uint32_t i = 0; i < num_threads; i++)
392             {
393                 ThreadSP thread_sp = process->GetThreadList().GetThreadAtIndex(i);
394                 if (!DisplayFramesForExecutionContext (thread_sp.get(),
395                                                       m_interpreter,
396                                                       result.GetOutputStream(),
397                                                       m_options.m_start,
398                                                       m_options.m_count,
399                                                       show_frame_info,
400                                                       num_frames_with_source,
401                                                       3,
402                                                       3))
403                 {
404                     result.AppendErrorWithFormat ("error displaying backtrace for thread: \"0x%4.4x\"\n", i);
405                     result.SetStatus (eReturnStatusFailed);
406                     return false;
407                 }
408                 if (i < num_threads - 1)
409                     result.AppendMessage("");
410             }
411         }
412         else
413         {
414             uint32_t num_args = command.GetArgumentCount();
415             Process *process = m_interpreter.GetExecutionContext().process;
416             std::vector<ThreadSP> thread_sps;
417 
418             for (uint32_t i = 0; i < num_args; i++)
419             {
420                 bool success;
421 
422                 uint32_t thread_idx = Args::StringToUInt32(command.GetArgumentAtIndex(i), 0, 0, &success);
423                 if (!success)
424                 {
425                     result.AppendErrorWithFormat ("invalid thread specification: \"%s\"\n", command.GetArgumentAtIndex(i));
426                     result.SetStatus (eReturnStatusFailed);
427                     return false;
428                 }
429 
430                 thread_sps.push_back(process->GetThreadList().FindThreadByIndexID(thread_idx));
431 
432                 if (!thread_sps[i])
433                 {
434                     result.AppendErrorWithFormat ("no thread with index: \"%s\"\n", command.GetArgumentAtIndex(i));
435                     result.SetStatus (eReturnStatusFailed);
436                     return false;
437                 }
438 
439             }
440 
441             for (uint32_t i = 0; i < num_args; i++)
442             {
443                 if (!DisplayFramesForExecutionContext (thread_sps[i].get(),
444                                                       m_interpreter,
445                                                       result.GetOutputStream(),
446                                                       m_options.m_start,
447                                                       m_options.m_count,
448                                                       show_frame_info,
449                                                       num_frames_with_source,
450                                                       3,
451                                                       3))
452                 {
453                     result.AppendErrorWithFormat ("error displaying backtrace for thread: \"%s\"\n", command.GetArgumentAtIndex(i));
454                     result.SetStatus (eReturnStatusFailed);
455                     return false;
456                 }
457 
458                 if (i < num_args - 1)
459                     result.AppendMessage("");
460             }
461         }
462         return result.Succeeded();
463     }
464 protected:
465     CommandOptions m_options;
466 };
467 
468 OptionDefinition
469 CommandObjectThreadBacktrace::CommandOptions::g_option_table[] =
470 {
471 { LLDB_OPT_SET_1, false, "count", 'c', required_argument, NULL, 0, eArgTypeCount, "How many frames to display (-1 for all)"},
472 { LLDB_OPT_SET_1, false, "start", 's', required_argument, NULL, 0, eArgTypeFrameIndex, "Frame in which to start the backtrace"},
473 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
474 };
475 
476 enum StepScope
477 {
478     eStepScopeSource,
479     eStepScopeInstruction
480 };
481 
482 class CommandObjectThreadStepWithTypeAndScope : public CommandObject
483 {
484 public:
485 
486     class CommandOptions : public Options
487     {
488     public:
489 
490         CommandOptions (CommandInterpreter &interpreter) :
491             Options (interpreter)
492         {
493             // Keep default values of all options in one place: OptionParsingStarting ()
494             OptionParsingStarting ();
495         }
496 
497         virtual
498         ~CommandOptions ()
499         {
500         }
501 
502         virtual Error
503         SetOptionValue (uint32_t option_idx, const char *option_arg)
504         {
505             Error error;
506             char short_option = (char) m_getopt_table[option_idx].val;
507 
508             switch (short_option)
509             {
510             case 'a':
511                 {
512                     bool success;
513                     m_avoid_no_debug =  Args::StringToBoolean (option_arg, true, &success);
514                     if (!success)
515                         error.SetErrorStringWithFormat("Invalid boolean value for option '%c'.\n", short_option);
516                 }
517                 break;
518 
519             case 'm':
520                 {
521                     bool found_one = false;
522                     OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
523                     m_run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, &found_one);
524                     if (!found_one)
525                         error.SetErrorStringWithFormat("Invalid enumeration value for option '%c'.\n", short_option);
526                 }
527                 break;
528 
529             case 'r':
530                 {
531                     m_avoid_regexp.clear();
532                     m_avoid_regexp.assign(option_arg);
533                 }
534                 break;
535 
536             default:
537                 error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
538                 break;
539 
540             }
541             return error;
542         }
543 
544         void
545         OptionParsingStarting ()
546         {
547             m_avoid_no_debug = true;
548             m_run_mode = eOnlyDuringStepping;
549             m_avoid_regexp.clear();
550         }
551 
552         const OptionDefinition*
553         GetDefinitions ()
554         {
555             return g_option_table;
556         }
557 
558         // Options table: Required for subclasses of Options.
559 
560         static 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 (interpreter)
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.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 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 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 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.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 (CommandInterpreter &interpreter) :
980             Options (interpreter),
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: OptionParsingStarting ()
985             OptionParsingStarting ();
986         }
987 
988         virtual
989         ~CommandOptions ()
990         {
991         }
992 
993         virtual Error
994         SetOptionValue (uint32_t 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         OptionParsingStarting ()
1044         {
1045             m_thread_idx = LLDB_INVALID_THREAD_ID;
1046             m_frame_idx = 0;
1047             m_stop_others = false;
1048         }
1049 
1050         const OptionDefinition*
1051         GetDefinitions ()
1052         {
1053             return g_option_table;
1054         }
1055 
1056         uint32_t m_step_thread_idx;
1057         bool m_stop_others;
1058 
1059         // Options table: Required for subclasses of Options.
1060 
1061         static OptionDefinition g_option_table[];
1062 
1063         // Instance variables to hold the values for command options.
1064     };
1065 
1066     CommandObjectThreadUntil (CommandInterpreter &interpreter) :
1067         CommandObject (interpreter,
1068                        "thread until",
1069                        "Run the current or specified thread until it reaches a given line number or leaves the current function.",
1070                        NULL,
1071                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
1072         m_options (interpreter)
1073     {
1074         CommandArgumentEntry arg;
1075         CommandArgumentData line_num_arg;
1076 
1077         // Define the first (and only) variant of this arg.
1078         line_num_arg.arg_type = eArgTypeLineNum;
1079         line_num_arg.arg_repetition = eArgRepeatPlain;
1080 
1081         // There is only one variant this argument could be; put it into the argument entry.
1082         arg.push_back (line_num_arg);
1083 
1084         // Push the data for the first argument into the m_arguments vector.
1085         m_arguments.push_back (arg);
1086     }
1087 
1088 
1089     virtual
1090     ~CommandObjectThreadUntil ()
1091     {
1092     }
1093 
1094     virtual
1095     Options *
1096     GetOptions ()
1097     {
1098         return &m_options;
1099     }
1100 
1101     virtual bool
1102     Execute
1103     (
1104         Args& command,
1105         CommandReturnObject &result
1106     )
1107     {
1108         bool synchronous_execution = m_interpreter.GetSynchronous ();
1109 
1110         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1111         if (target == NULL)
1112         {
1113             result.AppendError ("invalid target, set executable file using 'file' command");
1114             result.SetStatus (eReturnStatusFailed);
1115             return false;
1116         }
1117 
1118         Process *process = m_interpreter.GetExecutionContext().process;
1119         if (process == NULL)
1120         {
1121             result.AppendError ("need a valid process to step");
1122             result.SetStatus (eReturnStatusFailed);
1123 
1124         }
1125         else
1126         {
1127             Thread *thread = NULL;
1128             uint32_t line_number;
1129 
1130             if (command.GetArgumentCount() != 1)
1131             {
1132                 result.AppendErrorWithFormat ("No line number provided:\n%s", GetSyntax());
1133                 result.SetStatus (eReturnStatusFailed);
1134                 return false;
1135             }
1136 
1137             line_number = Args::StringToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX);
1138             if (line_number == UINT32_MAX)
1139             {
1140                 result.AppendErrorWithFormat ("Invalid line number: '%s'.\n", command.GetArgumentAtIndex(0));
1141                 result.SetStatus (eReturnStatusFailed);
1142                 return false;
1143             }
1144 
1145             if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID)
1146             {
1147                 thread = process->GetThreadList().GetSelectedThread().get();
1148             }
1149             else
1150             {
1151                 thread = process->GetThreadList().GetThreadAtIndex(m_options.m_thread_idx).get();
1152             }
1153 
1154             if (thread == NULL)
1155             {
1156                 const uint32_t num_threads = process->GetThreadList().GetSize();
1157                 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n", m_options.m_thread_idx, 0, num_threads);
1158                 result.SetStatus (eReturnStatusFailed);
1159                 return false;
1160             }
1161 
1162             const bool abort_other_plans = true;
1163 
1164             StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get();
1165             if (frame == NULL)
1166             {
1167 
1168                 result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n", m_options.m_frame_idx, m_options.m_thread_idx);
1169                 result.SetStatus (eReturnStatusFailed);
1170                 return false;
1171             }
1172 
1173             ThreadPlan *new_plan;
1174 
1175             if (frame->HasDebugInformation ())
1176             {
1177                 // Finally we got here...  Translate the given line number to a bunch of addresses:
1178                 SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit));
1179                 LineTable *line_table = NULL;
1180                 if (sc.comp_unit)
1181                     line_table = sc.comp_unit->GetLineTable();
1182 
1183                 if (line_table == NULL)
1184                 {
1185                     result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n",
1186                                                  m_options.m_frame_idx, m_options.m_thread_idx);
1187                     result.SetStatus (eReturnStatusFailed);
1188                     return false;
1189                 }
1190 
1191                 LineEntry function_start;
1192                 uint32_t index_ptr = 0, end_ptr;
1193                 std::vector<addr_t> address_list;
1194 
1195                 // Find the beginning & end index of the
1196                 AddressRange fun_addr_range = sc.function->GetAddressRange();
1197                 Address fun_start_addr = fun_addr_range.GetBaseAddress();
1198                 line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr);
1199 
1200                 Address fun_end_addr(fun_start_addr.GetSection(), fun_start_addr.GetOffset() + fun_addr_range.GetByteSize());
1201                 line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr);
1202 
1203                 while (index_ptr <= end_ptr)
1204                 {
1205                     LineEntry line_entry;
1206                     index_ptr = sc.comp_unit->FindLineEntry(index_ptr, line_number, sc.comp_unit, &line_entry);
1207                     if (index_ptr == UINT32_MAX)
1208                         break;
1209 
1210                     addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target);
1211                     if (address != LLDB_INVALID_ADDRESS)
1212                         address_list.push_back (address);
1213                     index_ptr++;
1214                 }
1215 
1216                 new_plan = thread->QueueThreadPlanForStepUntil (abort_other_plans, &address_list.front(), address_list.size(), m_options.m_stop_others, thread->GetSelectedFrameIndex ());
1217                 new_plan->SetOkayToDiscard(false);
1218             }
1219             else
1220             {
1221                 result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n", m_options.m_frame_idx, m_options.m_thread_idx);
1222                 result.SetStatus (eReturnStatusFailed);
1223                 return false;
1224 
1225             }
1226 
1227             process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx);
1228             Error error (process->Resume ());
1229             if (error.Success())
1230             {
1231                 result.AppendMessageWithFormat ("Process %i resuming\n", process->GetID());
1232                 if (synchronous_execution)
1233                 {
1234                     StateType state = process->WaitForProcessToStop (NULL);
1235 
1236                     result.SetDidChangeProcessState (true);
1237                     result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state));
1238                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
1239                 }
1240                 else
1241                 {
1242                     result.SetStatus (eReturnStatusSuccessContinuingNoResult);
1243                 }
1244             }
1245             else
1246             {
1247                 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
1248                 result.SetStatus (eReturnStatusFailed);
1249             }
1250 
1251         }
1252         return result.Succeeded();
1253     }
1254 protected:
1255     CommandOptions m_options;
1256 
1257 };
1258 
1259 OptionDefinition
1260 CommandObjectThreadUntil::CommandOptions::g_option_table[] =
1261 {
1262 { LLDB_OPT_SET_1, false, "frame",   'f', required_argument, NULL,               0, eArgTypeFrameIndex,   "Frame index for until operation - defaults to 0"},
1263 { LLDB_OPT_SET_1, false, "thread",  't', required_argument, NULL,               0, eArgTypeThreadIndex,  "Thread index for the thread for until operation"},
1264 { 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"},
1265 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1266 };
1267 
1268 
1269 //-------------------------------------------------------------------------
1270 // CommandObjectThreadSelect
1271 //-------------------------------------------------------------------------
1272 
1273 class CommandObjectThreadSelect : public CommandObject
1274 {
1275 public:
1276 
1277     CommandObjectThreadSelect (CommandInterpreter &interpreter) :
1278         CommandObject (interpreter,
1279                        "thread select",
1280                        "Select a thread as the currently active thread.",
1281                        NULL,
1282                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
1283     {
1284         CommandArgumentEntry arg;
1285         CommandArgumentData thread_idx_arg;
1286 
1287         // Define the first (and only) variant of this arg.
1288         thread_idx_arg.arg_type = eArgTypeThreadIndex;
1289         thread_idx_arg.arg_repetition = eArgRepeatPlain;
1290 
1291         // There is only one variant this argument could be; put it into the argument entry.
1292         arg.push_back (thread_idx_arg);
1293 
1294         // Push the data for the first argument into the m_arguments vector.
1295         m_arguments.push_back (arg);
1296     }
1297 
1298 
1299     virtual
1300     ~CommandObjectThreadSelect ()
1301     {
1302     }
1303 
1304     virtual bool
1305     Execute
1306     (
1307         Args& command,
1308         CommandReturnObject &result
1309     )
1310     {
1311         Process *process = m_interpreter.GetExecutionContext().process;
1312         if (process == NULL)
1313         {
1314             result.AppendError ("no process");
1315             result.SetStatus (eReturnStatusFailed);
1316             return false;
1317         }
1318         else if (command.GetArgumentCount() != 1)
1319         {
1320             result.AppendErrorWithFormat("'%s' takes exactly one thread index argument:\nUsage: \n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
1321             result.SetStatus (eReturnStatusFailed);
1322             return false;
1323         }
1324 
1325         uint32_t index_id = Args::StringToUInt32(command.GetArgumentAtIndex(0), 0, 0);
1326 
1327         Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get();
1328         if (new_thread == NULL)
1329         {
1330             result.AppendErrorWithFormat ("Invalid thread #%s.\n", command.GetArgumentAtIndex(0));
1331             result.SetStatus (eReturnStatusFailed);
1332             return false;
1333         }
1334 
1335         process->GetThreadList().SetSelectedThreadByID(new_thread->GetID());
1336         result.SetStatus (eReturnStatusSuccessFinishNoResult);
1337 
1338         DisplayThreadInfo (m_interpreter,
1339                            result.GetOutputStream(),
1340                            new_thread,
1341                            false,
1342                            true);
1343 
1344         return result.Succeeded();
1345     }
1346 
1347 };
1348 
1349 
1350 //-------------------------------------------------------------------------
1351 // CommandObjectThreadList
1352 //-------------------------------------------------------------------------
1353 
1354 class CommandObjectThreadList : public CommandObject
1355 {
1356 public:
1357 
1358 
1359     CommandObjectThreadList (CommandInterpreter &interpreter):
1360         CommandObject (interpreter,
1361                        "thread list",
1362                        "Show a summary of all current threads in a process.",
1363                        "thread list",
1364                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
1365     {
1366     }
1367 
1368     ~CommandObjectThreadList()
1369     {
1370     }
1371 
1372     bool
1373     Execute
1374     (
1375         Args& command,
1376         CommandReturnObject &result
1377     )
1378     {
1379         Stream &strm = result.GetOutputStream();
1380         result.SetStatus (eReturnStatusSuccessFinishNoResult);
1381         ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
1382         if (exe_ctx.process)
1383         {
1384             const StateType state = exe_ctx.process->GetState();
1385 
1386             if (StateIsStoppedState(state))
1387             {
1388                 if (state == eStateExited)
1389                 {
1390                     int exit_status = exe_ctx.process->GetExitStatus();
1391                     const char *exit_description = exe_ctx.process->GetExitDescription();
1392                     strm.Printf ("Process %d exited with status = %i (0x%8.8x) %s\n",
1393                                           exe_ctx.process->GetID(),
1394                                           exit_status,
1395                                           exit_status,
1396                                           exit_description ? exit_description : "");
1397                 }
1398                 else
1399                 {
1400                     strm.Printf ("Process %d state is %s\n", exe_ctx.process->GetID(), StateAsCString (state));
1401                     if (exe_ctx.thread == NULL)
1402                         exe_ctx.thread = exe_ctx.process->GetThreadList().GetThreadAtIndex(0).get();
1403                     if (exe_ctx.thread != NULL)
1404                     {
1405                         DisplayThreadsInfo (m_interpreter, &exe_ctx, result, false, false);
1406                     }
1407                     else
1408                     {
1409                         result.AppendError ("no valid thread found in current process");
1410                         result.SetStatus (eReturnStatusFailed);
1411                     }
1412                 }
1413             }
1414             else
1415             {
1416                 result.AppendError ("process is currently running");
1417                 result.SetStatus (eReturnStatusFailed);
1418             }
1419         }
1420         else
1421         {
1422             result.AppendError ("no current location or status available");
1423             result.SetStatus (eReturnStatusFailed);
1424         }
1425         return result.Succeeded();
1426     }
1427 };
1428 
1429 //-------------------------------------------------------------------------
1430 // CommandObjectMultiwordThread
1431 //-------------------------------------------------------------------------
1432 
1433 CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) :
1434     CommandObjectMultiword (interpreter,
1435                             "thread",
1436                             "A set of commands for operating on one or more threads within a running process.",
1437                             "thread <subcommand> [<subcommand-options>]")
1438 {
1439     LoadSubCommand ("backtrace",  CommandObjectSP (new CommandObjectThreadBacktrace (interpreter)));
1440     LoadSubCommand ("continue",   CommandObjectSP (new CommandObjectThreadContinue (interpreter)));
1441     LoadSubCommand ("list",       CommandObjectSP (new CommandObjectThreadList (interpreter)));
1442     LoadSubCommand ("select",     CommandObjectSP (new CommandObjectThreadSelect (interpreter)));
1443     LoadSubCommand ("until",      CommandObjectSP (new CommandObjectThreadUntil (interpreter)));
1444     LoadSubCommand ("step-in",    CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1445                                                     interpreter,
1446                                                     "thread step-in",
1447                                                     "Source level single step in specified thread (current thread, if none specified).",
1448                                                     NULL,
1449                                                     eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1450                                                     eStepTypeInto,
1451                                                     eStepScopeSource)));
1452 
1453     LoadSubCommand ("step-out",   CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1454                                                     interpreter,
1455                                                     "thread step-out",
1456                                                     "Finish executing the current fucntion and return to its call site in specified thread (current thread, if none specified).",
1457                                                     NULL,
1458                                                     eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1459                                                     eStepTypeOut,
1460                                                     eStepScopeSource)));
1461 
1462     LoadSubCommand ("step-over",   CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1463                                                     interpreter,
1464                                                     "thread step-over",
1465                                                     "Source level single step in specified thread (current thread, if none specified), stepping over calls.",
1466                                                     NULL,
1467                                                     eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1468                                                     eStepTypeOver,
1469                                                     eStepScopeSource)));
1470 
1471     LoadSubCommand ("step-inst",   CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1472                                                     interpreter,
1473                                                     "thread step-inst",
1474                                                     "Single step one instruction in specified thread (current thread, if none specified).",
1475                                                     NULL,
1476                                                     eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1477                                                     eStepTypeTrace,
1478                                                     eStepScopeInstruction)));
1479 
1480     LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1481                                                     interpreter,
1482                                                     "thread step-inst-over",
1483                                                     "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.",
1484                                                     NULL,
1485                                                     eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1486                                                     eStepTypeTraceOver,
1487                                                     eStepScopeInstruction)));
1488 }
1489 
1490 CommandObjectMultiwordThread::~CommandObjectMultiwordThread ()
1491 {
1492 }
1493 
1494 
1495