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