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