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