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