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