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 "lldb/lldb-python.h"
11
12#include "CommandObjectThread.h"
13
14// C Includes
15// C++ Includes
16// Other libraries and framework includes
17// Project includes
18#include "lldb/lldb-private.h"
19#include "lldb/Core/State.h"
20#include "lldb/Core/SourceManager.h"
21#include "lldb/Host/Host.h"
22#include "lldb/Interpreter/CommandInterpreter.h"
23#include "lldb/Interpreter/CommandReturnObject.h"
24#include "lldb/Interpreter/Options.h"
25#include "lldb/Symbol/CompileUnit.h"
26#include "lldb/Symbol/Function.h"
27#include "lldb/Symbol/LineTable.h"
28#include "lldb/Symbol/LineEntry.h"
29#include "lldb/Target/Process.h"
30#include "lldb/Target/RegisterContext.h"
31#include "lldb/Target/Target.h"
32#include "lldb/Target/Thread.h"
33#include "lldb/Target/ThreadPlan.h"
34#include "lldb/Target/ThreadPlanStepInstruction.h"
35#include "lldb/Target/ThreadPlanStepOut.h"
36#include "lldb/Target/ThreadPlanStepRange.h"
37#include "lldb/Target/ThreadPlanStepInRange.h"
38
39
40using namespace lldb;
41using namespace lldb_private;
42
43
44//-------------------------------------------------------------------------
45// CommandObjectThreadBacktrace
46//-------------------------------------------------------------------------
47
48class CommandObjectThreadBacktrace : public CommandObjectParsed
49{
50public:
51
52    class CommandOptions : public Options
53    {
54    public:
55
56        CommandOptions (CommandInterpreter &interpreter) :
57            Options(interpreter)
58        {
59            // Keep default values of all options in one place: OptionParsingStarting ()
60            OptionParsingStarting ();
61        }
62
63        virtual
64        ~CommandOptions ()
65        {
66        }
67
68        virtual Error
69        SetOptionValue (uint32_t option_idx, const char *option_arg)
70        {
71            Error error;
72            const int short_option = m_getopt_table[option_idx].val;
73
74            switch (short_option)
75            {
76                case 'c':
77                {
78                    bool success;
79                    int32_t input_count =  Args::StringToSInt32 (option_arg, -1, 0, &success);
80                    if (!success)
81                        error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option);
82                    if (input_count < -1)
83                        m_count = UINT32_MAX;
84                    else
85                        m_count = input_count;
86                }
87                break;
88                case 's':
89                {
90                    bool success;
91                    m_start =  Args::StringToUInt32 (option_arg, 0, 0, &success);
92                    if (!success)
93                        error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option);
94                }
95                break;
96                default:
97                    error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
98                    break;
99
100            }
101            return error;
102        }
103
104        void
105        OptionParsingStarting ()
106        {
107            m_count = UINT32_MAX;
108            m_start = 0;
109        }
110
111        const OptionDefinition*
112        GetDefinitions ()
113        {
114            return g_option_table;
115        }
116
117        // Options table: Required for subclasses of Options.
118
119        static OptionDefinition g_option_table[];
120
121        // Instance variables to hold the values for command options.
122        uint32_t m_count;
123        uint32_t m_start;
124    };
125
126    CommandObjectThreadBacktrace (CommandInterpreter &interpreter) :
127        CommandObjectParsed (interpreter,
128                             "thread backtrace",
129                             "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.",
130                             NULL,
131                             eFlagRequiresProcess       |
132                             eFlagRequiresThread        |
133                             eFlagTryTargetAPILock      |
134                             eFlagProcessMustBeLaunched |
135                             eFlagProcessMustBePaused   ),
136        m_options(interpreter)
137    {
138        CommandArgumentEntry arg;
139        CommandArgumentData thread_idx_arg;
140
141        // Define the first (and only) variant of this arg.
142        thread_idx_arg.arg_type = eArgTypeThreadIndex;
143        thread_idx_arg.arg_repetition = eArgRepeatStar;
144
145        // There is only one variant this argument could be; put it into the argument entry.
146        arg.push_back (thread_idx_arg);
147
148        // Push the data for the first argument into the m_arguments vector.
149        m_arguments.push_back (arg);
150    }
151
152    ~CommandObjectThreadBacktrace()
153    {
154    }
155
156    virtual Options *
157    GetOptions ()
158    {
159        return &m_options;
160    }
161
162protected:
163    virtual bool
164    DoExecute (Args& command, CommandReturnObject &result)
165    {
166        result.SetStatus (eReturnStatusSuccessFinishResult);
167        Stream &strm = result.GetOutputStream();
168
169        // Don't show source context when doing backtraces.
170        const uint32_t num_frames_with_source = 0;
171        if (command.GetArgumentCount() == 0)
172        {
173            Thread *thread = m_exe_ctx.GetThreadPtr();
174            // Thread::GetStatus() returns the number of frames shown.
175            if (thread->GetStatus (strm,
176                                   m_options.m_start,
177                                   m_options.m_count,
178                                   num_frames_with_source))
179            {
180                result.SetStatus (eReturnStatusSuccessFinishResult);
181            }
182        }
183        else if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0)
184        {
185            Process *process = m_exe_ctx.GetProcessPtr();
186            Mutex::Locker locker (process->GetThreadList().GetMutex());
187            uint32_t num_threads = process->GetThreadList().GetSize();
188            for (uint32_t i = 0; i < num_threads; i++)
189            {
190                ThreadSP thread_sp = process->GetThreadList().GetThreadAtIndex(i);
191                if (!thread_sp->GetStatus (strm,
192                                           m_options.m_start,
193                                           m_options.m_count,
194                                           num_frames_with_source))
195                {
196                    result.AppendErrorWithFormat ("error displaying backtrace for thread: \"0x%4.4x\"\n", i);
197                    result.SetStatus (eReturnStatusFailed);
198                    return false;
199                }
200
201                if (i < num_threads - 1)
202                    result.AppendMessage("");
203
204            }
205        }
206        else
207        {
208            const size_t num_args = command.GetArgumentCount();
209            Process *process = m_exe_ctx.GetProcessPtr();
210            Mutex::Locker locker (process->GetThreadList().GetMutex());
211            std::vector<ThreadSP> thread_sps;
212
213            for (size_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
258OptionDefinition
259CommandObjectThreadBacktrace::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
266enum StepScope
267{
268    eStepScopeSource,
269    eStepScopeInstruction
270};
271
272class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed
273{
274public:
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            const int short_option = 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            case 't':
324                {
325                    m_step_in_target.clear();
326                    m_step_in_target.assign(option_arg);
327
328                }
329                break;
330            default:
331                error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
332                break;
333
334            }
335            return error;
336        }
337
338        void
339        OptionParsingStarting ()
340        {
341            m_avoid_no_debug = true;
342            m_run_mode = eOnlyDuringStepping;
343            m_avoid_regexp.clear();
344            m_step_in_target.clear();
345        }
346
347        const OptionDefinition*
348        GetDefinitions ()
349        {
350            return g_option_table;
351        }
352
353        // Options table: Required for subclasses of Options.
354
355        static OptionDefinition g_option_table[];
356
357        // Instance variables to hold the values for command options.
358        bool m_avoid_no_debug;
359        RunMode m_run_mode;
360        std::string m_avoid_regexp;
361        std::string m_step_in_target;
362    };
363
364    CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter,
365                                             const char *name,
366                                             const char *help,
367                                             const char *syntax,
368                                             StepType step_type,
369                                             StepScope step_scope) :
370        CommandObjectParsed (interpreter, name, help, syntax,
371                             eFlagRequiresProcess       |
372                             eFlagRequiresThread        |
373                             eFlagTryTargetAPILock      |
374                             eFlagProcessMustBeLaunched |
375                             eFlagProcessMustBePaused   ),
376        m_step_type (step_type),
377        m_step_scope (step_scope),
378        m_options (interpreter)
379    {
380        CommandArgumentEntry arg;
381        CommandArgumentData thread_id_arg;
382
383        // Define the first (and only) variant of this arg.
384        thread_id_arg.arg_type = eArgTypeThreadID;
385        thread_id_arg.arg_repetition = eArgRepeatOptional;
386
387        // There is only one variant this argument could be; put it into the argument entry.
388        arg.push_back (thread_id_arg);
389
390        // Push the data for the first argument into the m_arguments vector.
391        m_arguments.push_back (arg);
392    }
393
394    virtual
395    ~CommandObjectThreadStepWithTypeAndScope ()
396    {
397    }
398
399    virtual
400    Options *
401    GetOptions ()
402    {
403        return &m_options;
404    }
405
406protected:
407    virtual bool
408    DoExecute (Args& command, CommandReturnObject &result)
409    {
410        Process *process = m_exe_ctx.GetProcessPtr();
411        bool synchronous_execution = m_interpreter.GetSynchronous();
412
413        const uint32_t num_threads = process->GetThreadList().GetSize();
414        Thread *thread = NULL;
415
416        if (command.GetArgumentCount() == 0)
417        {
418            thread = process->GetThreadList().GetSelectedThread().get();
419            if (thread == NULL)
420            {
421                result.AppendError ("no selected thread in process");
422                result.SetStatus (eReturnStatusFailed);
423                return false;
424            }
425        }
426        else
427        {
428            const char *thread_idx_cstr = command.GetArgumentAtIndex(0);
429            uint32_t step_thread_idx = Args::StringToUInt32 (thread_idx_cstr, LLDB_INVALID_INDEX32);
430            if (step_thread_idx == LLDB_INVALID_INDEX32)
431            {
432                result.AppendErrorWithFormat ("invalid thread index '%s'.\n", thread_idx_cstr);
433                result.SetStatus (eReturnStatusFailed);
434                return false;
435            }
436            thread = process->GetThreadList().FindThreadByIndexID(step_thread_idx).get();
437            if (thread == NULL)
438            {
439                result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
440                                              step_thread_idx, num_threads);
441                result.SetStatus (eReturnStatusFailed);
442                return false;
443            }
444        }
445
446        const bool abort_other_plans = false;
447        const lldb::RunMode stop_other_threads = m_options.m_run_mode;
448
449        // This is a bit unfortunate, but not all the commands in this command object support
450        // only while stepping, so I use the bool for them.
451        bool bool_stop_other_threads;
452        if (m_options.m_run_mode == eAllThreads)
453            bool_stop_other_threads = false;
454        else if (m_options.m_run_mode == eOnlyDuringStepping)
455        {
456            if (m_step_type == eStepTypeOut)
457                bool_stop_other_threads = false;
458            else
459                bool_stop_other_threads = true;
460        }
461        else
462            bool_stop_other_threads = true;
463
464        ThreadPlanSP new_plan_sp;
465
466        if (m_step_type == eStepTypeInto)
467        {
468            StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
469
470            if (frame->HasDebugInformation ())
471            {
472                new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans,
473                                                                frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
474                                                                frame->GetSymbolContext(eSymbolContextEverything),
475                                                                m_options.m_step_in_target.c_str(),
476                                                                stop_other_threads,
477                                                                m_options.m_avoid_no_debug);
478                if (new_plan_sp && !m_options.m_avoid_regexp.empty())
479                {
480                    ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan_sp.get());
481                    step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str());
482                }
483            }
484            else
485                new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
486
487        }
488        else if (m_step_type == eStepTypeOver)
489        {
490            StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
491
492            if (frame->HasDebugInformation())
493                new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
494                                                                    frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
495                                                                    frame->GetSymbolContext(eSymbolContextEverything),
496                                                                    stop_other_threads);
497            else
498                new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true,
499                                                                            abort_other_plans,
500                                                                            bool_stop_other_threads);
501
502        }
503        else if (m_step_type == eStepTypeTrace)
504        {
505            new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
506        }
507        else if (m_step_type == eStepTypeTraceOver)
508        {
509            new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads);
510        }
511        else if (m_step_type == eStepTypeOut)
512        {
513            new_plan_sp = thread->QueueThreadPlanForStepOut (abort_other_plans,
514                                                          NULL,
515                                                          false,
516                                                          bool_stop_other_threads,
517                                                          eVoteYes,
518                                                          eVoteNoOpinion,
519                                                          thread->GetSelectedFrameIndex());
520        }
521        else
522        {
523            result.AppendError ("step type is not supported");
524            result.SetStatus (eReturnStatusFailed);
525            return false;
526        }
527
528        // If we got a new plan, then set it to be a master plan (User level Plans should be master plans
529        // so that they can be interruptible).  Then resume the process.
530
531        if (new_plan_sp)
532        {
533            new_plan_sp->SetIsMasterPlan (true);
534            new_plan_sp->SetOkayToDiscard (false);
535
536            process->GetThreadList().SetSelectedThreadByID (thread->GetID());
537            process->Resume ();
538
539
540            if (synchronous_execution)
541            {
542                StateType state = process->WaitForProcessToStop (NULL);
543
544                //EventSP event_sp;
545                //StateType state = process->WaitForStateChangedEvents (NULL, event_sp);
546                //while (! StateIsStoppedState (state))
547                //  {
548                //    state = process->WaitForStateChangedEvents (NULL, event_sp);
549                //  }
550                process->GetThreadList().SetSelectedThreadByID (thread->GetID());
551                result.SetDidChangeProcessState (true);
552                result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
553                result.SetStatus (eReturnStatusSuccessFinishNoResult);
554            }
555            else
556            {
557                result.SetStatus (eReturnStatusSuccessContinuingNoResult);
558            }
559        }
560        else
561        {
562            result.AppendError ("Couldn't find thread plan to implement step type.");
563            result.SetStatus (eReturnStatusFailed);
564        }
565        return result.Succeeded();
566    }
567
568protected:
569    StepType m_step_type;
570    StepScope m_step_scope;
571    CommandOptions m_options;
572};
573
574static OptionEnumValueElement
575g_tri_running_mode[] =
576{
577{ eOnlyThisThread,     "this-thread",    "Run only this thread"},
578{ eAllThreads,         "all-threads",    "Run all threads"},
579{ eOnlyDuringStepping, "while-stepping", "Run only this thread while stepping"},
580{ 0, NULL, NULL }
581};
582
583static OptionEnumValueElement
584g_duo_running_mode[] =
585{
586{ eOnlyThisThread,     "this-thread",    "Run only this thread"},
587{ eAllThreads,         "all-threads",    "Run all threads"},
588{ 0, NULL, NULL }
589};
590
591OptionDefinition
592CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] =
593{
594{ 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."},
595{ 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."},
596{ LLDB_OPT_SET_1, false, "step-over-regexp",'r', required_argument, NULL,               0, eArgTypeRegularExpression,   "A regular expression that defines function names to not to stop at when stepping in."},
597{ LLDB_OPT_SET_1, false, "step-in-target",  't', required_argument, NULL,               0, eArgTypeFunctionName,   "The name of the directly called function step in should stop at when stepping into."},
598{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
599};
600
601
602//-------------------------------------------------------------------------
603// CommandObjectThreadContinue
604//-------------------------------------------------------------------------
605
606class CommandObjectThreadContinue : public CommandObjectParsed
607{
608public:
609
610    CommandObjectThreadContinue (CommandInterpreter &interpreter) :
611        CommandObjectParsed (interpreter,
612                             "thread continue",
613                             "Continue execution of one or more threads in an active process.",
614                             NULL,
615                             eFlagRequiresThread        |
616                             eFlagTryTargetAPILock      |
617                             eFlagProcessMustBeLaunched |
618                             eFlagProcessMustBePaused)
619    {
620        CommandArgumentEntry arg;
621        CommandArgumentData thread_idx_arg;
622
623        // Define the first (and only) variant of this arg.
624        thread_idx_arg.arg_type = eArgTypeThreadIndex;
625        thread_idx_arg.arg_repetition = eArgRepeatPlus;
626
627        // There is only one variant this argument could be; put it into the argument entry.
628        arg.push_back (thread_idx_arg);
629
630        // Push the data for the first argument into the m_arguments vector.
631        m_arguments.push_back (arg);
632    }
633
634
635    virtual
636    ~CommandObjectThreadContinue ()
637    {
638    }
639
640    virtual bool
641    DoExecute (Args& command, CommandReturnObject &result)
642    {
643        bool synchronous_execution = m_interpreter.GetSynchronous ();
644
645        if (!m_interpreter.GetDebugger().GetSelectedTarget().get())
646        {
647            result.AppendError ("invalid target, create a debug target using the 'target create' command");
648            result.SetStatus (eReturnStatusFailed);
649            return false;
650        }
651
652        Process *process = m_exe_ctx.GetProcessPtr();
653        if (process == NULL)
654        {
655            result.AppendError ("no process exists. Cannot continue");
656            result.SetStatus (eReturnStatusFailed);
657            return false;
658        }
659
660        StateType state = process->GetState();
661        if ((state == eStateCrashed) || (state == eStateStopped) || (state == eStateSuspended))
662        {
663            Mutex::Locker locker (process->GetThreadList().GetMutex());
664            const uint32_t num_threads = process->GetThreadList().GetSize();
665            const size_t argc = command.GetArgumentCount();
666            if (argc > 0)
667            {
668                std::vector<Thread *> resume_threads;
669                for (uint32_t i=0; i<argc; ++i)
670                {
671                    bool success;
672                    const int base = 0;
673                    uint32_t thread_idx = Args::StringToUInt32 (command.GetArgumentAtIndex(i), LLDB_INVALID_INDEX32, base, &success);
674                    if (success)
675                    {
676                        Thread *thread = process->GetThreadList().FindThreadByIndexID(thread_idx).get();
677
678                        if (thread)
679                        {
680                            resume_threads.push_back(thread);
681                        }
682                        else
683                        {
684                            result.AppendErrorWithFormat("invalid thread index %u.\n", thread_idx);
685                            result.SetStatus (eReturnStatusFailed);
686                            return false;
687                        }
688                    }
689                    else
690                    {
691                        result.AppendErrorWithFormat ("invalid thread index argument: \"%s\".\n", command.GetArgumentAtIndex(i));
692                        result.SetStatus (eReturnStatusFailed);
693                        return false;
694                    }
695                }
696
697                if (resume_threads.empty())
698                {
699                    result.AppendError ("no valid thread indexes were specified");
700                    result.SetStatus (eReturnStatusFailed);
701                    return false;
702                }
703                else
704                {
705                    if (resume_threads.size() == 1)
706                        result.AppendMessageWithFormat ("Resuming thread: ");
707                    else
708                        result.AppendMessageWithFormat ("Resuming threads: ");
709
710                    for (uint32_t idx=0; idx<num_threads; ++idx)
711                    {
712                        Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
713                        std::vector<Thread *>::iterator this_thread_pos = find(resume_threads.begin(), resume_threads.end(), thread);
714
715                        if (this_thread_pos != resume_threads.end())
716                        {
717                            resume_threads.erase(this_thread_pos);
718                            if (resume_threads.size() > 0)
719                                result.AppendMessageWithFormat ("%u, ", thread->GetIndexID());
720                            else
721                                result.AppendMessageWithFormat ("%u ", thread->GetIndexID());
722
723                            thread->SetResumeState (eStateRunning);
724                        }
725                        else
726                        {
727                            thread->SetResumeState (eStateSuspended);
728                        }
729                    }
730                    result.AppendMessageWithFormat ("in process %" PRIu64 "\n", process->GetID());
731                }
732            }
733            else
734            {
735                Thread *current_thread = process->GetThreadList().GetSelectedThread().get();
736                if (current_thread == NULL)
737                {
738                    result.AppendError ("the process doesn't have a current thread");
739                    result.SetStatus (eReturnStatusFailed);
740                    return false;
741                }
742                // Set the actions that the threads should each take when resuming
743                for (uint32_t idx=0; idx<num_threads; ++idx)
744                {
745                    Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
746                    if (thread == current_thread)
747                    {
748                        result.AppendMessageWithFormat ("Resuming thread 0x%4.4" PRIx64 " in process %" PRIu64 "\n", thread->GetID(), process->GetID());
749                        thread->SetResumeState (eStateRunning);
750                    }
751                    else
752                    {
753                        thread->SetResumeState (eStateSuspended);
754                    }
755                }
756            }
757
758            Error error (process->Resume());
759            if (error.Success())
760            {
761                result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
762                if (synchronous_execution)
763                {
764                    state = process->WaitForProcessToStop (NULL);
765
766                    result.SetDidChangeProcessState (true);
767                    result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
768                    result.SetStatus (eReturnStatusSuccessFinishNoResult);
769                }
770                else
771                {
772                    result.SetStatus (eReturnStatusSuccessContinuingNoResult);
773                }
774            }
775            else
776            {
777                result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString());
778                result.SetStatus (eReturnStatusFailed);
779            }
780        }
781        else
782        {
783            result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
784                                          StateAsCString(state));
785            result.SetStatus (eReturnStatusFailed);
786        }
787
788        return result.Succeeded();
789    }
790
791};
792
793//-------------------------------------------------------------------------
794// CommandObjectThreadUntil
795//-------------------------------------------------------------------------
796
797class CommandObjectThreadUntil : public CommandObjectParsed
798{
799public:
800
801    class CommandOptions : public Options
802    {
803    public:
804        uint32_t m_thread_idx;
805        uint32_t m_frame_idx;
806
807        CommandOptions (CommandInterpreter &interpreter) :
808            Options (interpreter),
809            m_thread_idx(LLDB_INVALID_THREAD_ID),
810            m_frame_idx(LLDB_INVALID_FRAME_ID)
811        {
812            // Keep default values of all options in one place: OptionParsingStarting ()
813            OptionParsingStarting ();
814        }
815
816        virtual
817        ~CommandOptions ()
818        {
819        }
820
821        virtual Error
822        SetOptionValue (uint32_t option_idx, const char *option_arg)
823        {
824            Error error;
825            const int short_option = m_getopt_table[option_idx].val;
826
827            switch (short_option)
828            {
829                case 't':
830                {
831                    m_thread_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_INDEX32);
832                    if (m_thread_idx == LLDB_INVALID_INDEX32)
833                    {
834                        error.SetErrorStringWithFormat ("invalid thread index '%s'", option_arg);
835                    }
836                }
837                break;
838                case 'f':
839                {
840                    m_frame_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_FRAME_ID);
841                    if (m_frame_idx == LLDB_INVALID_FRAME_ID)
842                    {
843                        error.SetErrorStringWithFormat ("invalid frame index '%s'", option_arg);
844                    }
845                }
846                break;
847                case 'm':
848                {
849                    OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
850                    lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
851
852                    if (error.Success())
853                    {
854                        if (run_mode == eAllThreads)
855                            m_stop_others = false;
856                        else
857                            m_stop_others = true;
858                    }
859                }
860                break;
861                default:
862                    error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
863                    break;
864
865            }
866            return error;
867        }
868
869        void
870        OptionParsingStarting ()
871        {
872            m_thread_idx = LLDB_INVALID_THREAD_ID;
873            m_frame_idx = 0;
874            m_stop_others = false;
875        }
876
877        const OptionDefinition*
878        GetDefinitions ()
879        {
880            return g_option_table;
881        }
882
883        uint32_t m_step_thread_idx;
884        bool m_stop_others;
885
886        // Options table: Required for subclasses of Options.
887
888        static OptionDefinition g_option_table[];
889
890        // Instance variables to hold the values for command options.
891    };
892
893    CommandObjectThreadUntil (CommandInterpreter &interpreter) :
894        CommandObjectParsed (interpreter,
895                             "thread until",
896                             "Run the current or specified thread until it reaches a given line number or leaves the current function.",
897                             NULL,
898                             eFlagRequiresThread        |
899                             eFlagTryTargetAPILock      |
900                             eFlagProcessMustBeLaunched |
901                             eFlagProcessMustBePaused   ),
902        m_options (interpreter)
903    {
904        CommandArgumentEntry arg;
905        CommandArgumentData line_num_arg;
906
907        // Define the first (and only) variant of this arg.
908        line_num_arg.arg_type = eArgTypeLineNum;
909        line_num_arg.arg_repetition = eArgRepeatPlain;
910
911        // There is only one variant this argument could be; put it into the argument entry.
912        arg.push_back (line_num_arg);
913
914        // Push the data for the first argument into the m_arguments vector.
915        m_arguments.push_back (arg);
916    }
917
918
919    virtual
920    ~CommandObjectThreadUntil ()
921    {
922    }
923
924    virtual
925    Options *
926    GetOptions ()
927    {
928        return &m_options;
929    }
930
931protected:
932    virtual bool
933    DoExecute (Args& command, CommandReturnObject &result)
934    {
935        bool synchronous_execution = m_interpreter.GetSynchronous ();
936
937        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
938        if (target == NULL)
939        {
940            result.AppendError ("invalid target, create a debug target using the 'target create' command");
941            result.SetStatus (eReturnStatusFailed);
942            return false;
943        }
944
945        Process *process = m_exe_ctx.GetProcessPtr();
946        if (process == NULL)
947        {
948            result.AppendError ("need a valid process to step");
949            result.SetStatus (eReturnStatusFailed);
950
951        }
952        else
953        {
954            Thread *thread = NULL;
955            uint32_t line_number;
956
957            if (command.GetArgumentCount() != 1)
958            {
959                result.AppendErrorWithFormat ("No line number provided:\n%s", GetSyntax());
960                result.SetStatus (eReturnStatusFailed);
961                return false;
962            }
963
964            line_number = Args::StringToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX);
965            if (line_number == UINT32_MAX)
966            {
967                result.AppendErrorWithFormat ("invalid line number: '%s'.\n", command.GetArgumentAtIndex(0));
968                result.SetStatus (eReturnStatusFailed);
969                return false;
970            }
971
972            if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID)
973            {
974                thread = process->GetThreadList().GetSelectedThread().get();
975            }
976            else
977            {
978                thread = process->GetThreadList().FindThreadByIndexID(m_options.m_thread_idx).get();
979            }
980
981            if (thread == NULL)
982            {
983                const uint32_t num_threads = process->GetThreadList().GetSize();
984                result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
985                                              m_options.m_thread_idx,
986                                              num_threads);
987                result.SetStatus (eReturnStatusFailed);
988                return false;
989            }
990
991            const bool abort_other_plans = false;
992
993            StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get();
994            if (frame == NULL)
995            {
996
997                result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n",
998                                              m_options.m_frame_idx,
999                                              m_options.m_thread_idx);
1000                result.SetStatus (eReturnStatusFailed);
1001                return false;
1002            }
1003
1004            ThreadPlanSP new_plan_sp;
1005
1006            if (frame->HasDebugInformation ())
1007            {
1008                // Finally we got here...  Translate the given line number to a bunch of addresses:
1009                SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit));
1010                LineTable *line_table = NULL;
1011                if (sc.comp_unit)
1012                    line_table = sc.comp_unit->GetLineTable();
1013
1014                if (line_table == NULL)
1015                {
1016                    result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n",
1017                                                 m_options.m_frame_idx, m_options.m_thread_idx);
1018                    result.SetStatus (eReturnStatusFailed);
1019                    return false;
1020                }
1021
1022                LineEntry function_start;
1023                uint32_t index_ptr = 0, end_ptr;
1024                std::vector<addr_t> address_list;
1025
1026                // Find the beginning & end index of the
1027                AddressRange fun_addr_range = sc.function->GetAddressRange();
1028                Address fun_start_addr = fun_addr_range.GetBaseAddress();
1029                line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr);
1030
1031                Address fun_end_addr(fun_start_addr.GetSection(),
1032                                     fun_start_addr.GetOffset() + fun_addr_range.GetByteSize());
1033                line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr);
1034
1035                bool all_in_function = true;
1036
1037                while (index_ptr <= end_ptr)
1038                {
1039                    LineEntry line_entry;
1040                    const bool exact = false;
1041                    index_ptr = sc.comp_unit->FindLineEntry(index_ptr, line_number, sc.comp_unit, exact, &line_entry);
1042                    if (index_ptr == UINT32_MAX)
1043                        break;
1044
1045                    addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target);
1046                    if (address != LLDB_INVALID_ADDRESS)
1047                    {
1048                        if (fun_addr_range.ContainsLoadAddress (address, target))
1049                            address_list.push_back (address);
1050                        else
1051                            all_in_function = false;
1052                    }
1053                    index_ptr++;
1054                }
1055
1056                if (address_list.size() == 0)
1057                {
1058                    if (all_in_function)
1059                        result.AppendErrorWithFormat ("No line entries matching until target.\n");
1060                    else
1061                        result.AppendErrorWithFormat ("Until target outside of the current function.\n");
1062
1063                    result.SetStatus (eReturnStatusFailed);
1064                    return false;
1065                }
1066
1067                new_plan_sp = thread->QueueThreadPlanForStepUntil (abort_other_plans,
1068                                                                &address_list.front(),
1069                                                                address_list.size(),
1070                                                                m_options.m_stop_others,
1071                                                                m_options.m_frame_idx);
1072                // User level plans should be master plans so they can be interrupted (e.g. by hitting a breakpoint)
1073                // and other plans executed by the user (stepping around the breakpoint) and then a "continue"
1074                // will resume the original plan.
1075                new_plan_sp->SetIsMasterPlan (true);
1076                new_plan_sp->SetOkayToDiscard(false);
1077            }
1078            else
1079            {
1080                result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n",
1081                                              m_options.m_frame_idx,
1082                                              m_options.m_thread_idx);
1083                result.SetStatus (eReturnStatusFailed);
1084                return false;
1085
1086            }
1087
1088            process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx);
1089            Error error (process->Resume ());
1090            if (error.Success())
1091            {
1092                result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
1093                if (synchronous_execution)
1094                {
1095                    StateType state = process->WaitForProcessToStop (NULL);
1096
1097                    result.SetDidChangeProcessState (true);
1098                    result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
1099                    result.SetStatus (eReturnStatusSuccessFinishNoResult);
1100                }
1101                else
1102                {
1103                    result.SetStatus (eReturnStatusSuccessContinuingNoResult);
1104                }
1105            }
1106            else
1107            {
1108                result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
1109                result.SetStatus (eReturnStatusFailed);
1110            }
1111
1112        }
1113        return result.Succeeded();
1114    }
1115
1116    CommandOptions m_options;
1117
1118};
1119
1120OptionDefinition
1121CommandObjectThreadUntil::CommandOptions::g_option_table[] =
1122{
1123{ LLDB_OPT_SET_1, false, "frame",   'f', required_argument, NULL,               0, eArgTypeFrameIndex,   "Frame index for until operation - defaults to 0"},
1124{ LLDB_OPT_SET_1, false, "thread",  't', required_argument, NULL,               0, eArgTypeThreadIndex,  "Thread index for the thread for until operation"},
1125{ 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"},
1126{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1127};
1128
1129
1130//-------------------------------------------------------------------------
1131// CommandObjectThreadSelect
1132//-------------------------------------------------------------------------
1133
1134class CommandObjectThreadSelect : public CommandObjectParsed
1135{
1136public:
1137
1138    CommandObjectThreadSelect (CommandInterpreter &interpreter) :
1139        CommandObjectParsed (interpreter,
1140                             "thread select",
1141                             "Select a thread as the currently active thread.",
1142                             NULL,
1143                             eFlagRequiresProcess       |
1144                             eFlagTryTargetAPILock      |
1145                             eFlagProcessMustBeLaunched |
1146                             eFlagProcessMustBePaused   )
1147    {
1148        CommandArgumentEntry arg;
1149        CommandArgumentData thread_idx_arg;
1150
1151        // Define the first (and only) variant of this arg.
1152        thread_idx_arg.arg_type = eArgTypeThreadIndex;
1153        thread_idx_arg.arg_repetition = eArgRepeatPlain;
1154
1155        // There is only one variant this argument could be; put it into the argument entry.
1156        arg.push_back (thread_idx_arg);
1157
1158        // Push the data for the first argument into the m_arguments vector.
1159        m_arguments.push_back (arg);
1160    }
1161
1162
1163    virtual
1164    ~CommandObjectThreadSelect ()
1165    {
1166    }
1167
1168protected:
1169    virtual bool
1170    DoExecute (Args& command, CommandReturnObject &result)
1171    {
1172        Process *process = m_exe_ctx.GetProcessPtr();
1173        if (process == NULL)
1174        {
1175            result.AppendError ("no process");
1176            result.SetStatus (eReturnStatusFailed);
1177            return false;
1178        }
1179        else if (command.GetArgumentCount() != 1)
1180        {
1181            result.AppendErrorWithFormat("'%s' takes exactly one thread index argument:\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
1182            result.SetStatus (eReturnStatusFailed);
1183            return false;
1184        }
1185
1186        uint32_t index_id = Args::StringToUInt32(command.GetArgumentAtIndex(0), 0, 0);
1187
1188        Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get();
1189        if (new_thread == NULL)
1190        {
1191            result.AppendErrorWithFormat ("invalid thread #%s.\n", command.GetArgumentAtIndex(0));
1192            result.SetStatus (eReturnStatusFailed);
1193            return false;
1194        }
1195
1196        process->GetThreadList().SetSelectedThreadByID(new_thread->GetID(), true);
1197        result.SetStatus (eReturnStatusSuccessFinishNoResult);
1198
1199        return result.Succeeded();
1200    }
1201
1202};
1203
1204
1205//-------------------------------------------------------------------------
1206// CommandObjectThreadList
1207//-------------------------------------------------------------------------
1208
1209class CommandObjectThreadList : public CommandObjectParsed
1210{
1211public:
1212
1213
1214    CommandObjectThreadList (CommandInterpreter &interpreter):
1215        CommandObjectParsed (interpreter,
1216                             "thread list",
1217                             "Show a summary of all current threads in a process.",
1218                             "thread list",
1219                             eFlagRequiresProcess       |
1220                             eFlagTryTargetAPILock      |
1221                             eFlagProcessMustBeLaunched |
1222                             eFlagProcessMustBePaused   )
1223    {
1224    }
1225
1226    ~CommandObjectThreadList()
1227    {
1228    }
1229
1230protected:
1231    bool
1232    DoExecute (Args& command, CommandReturnObject &result)
1233    {
1234        Stream &strm = result.GetOutputStream();
1235        result.SetStatus (eReturnStatusSuccessFinishNoResult);
1236        Process *process = m_exe_ctx.GetProcessPtr();
1237        const bool only_threads_with_stop_reason = false;
1238        const uint32_t start_frame = 0;
1239        const uint32_t num_frames = 0;
1240        const uint32_t num_frames_with_source = 0;
1241        process->GetStatus(strm);
1242        process->GetThreadStatus (strm,
1243                                  only_threads_with_stop_reason,
1244                                  start_frame,
1245                                  num_frames,
1246                                  num_frames_with_source);
1247        return result.Succeeded();
1248    }
1249};
1250
1251//-------------------------------------------------------------------------
1252// CommandObjectThreadReturn
1253//-------------------------------------------------------------------------
1254
1255class CommandObjectThreadReturn : public CommandObjectRaw
1256{
1257public:
1258    class CommandOptions : public Options
1259    {
1260    public:
1261
1262        CommandOptions (CommandInterpreter &interpreter) :
1263            Options (interpreter),
1264            m_from_expression (false)
1265        {
1266            // Keep default values of all options in one place: OptionParsingStarting ()
1267            OptionParsingStarting ();
1268        }
1269
1270        virtual
1271        ~CommandOptions ()
1272        {
1273        }
1274
1275        virtual Error
1276        SetOptionValue (uint32_t option_idx, const char *option_arg)
1277        {
1278            Error error;
1279            const int short_option = m_getopt_table[option_idx].val;
1280
1281            switch (short_option)
1282            {
1283                case 'x':
1284                {
1285                    bool success;
1286                    bool tmp_value = Args::StringToBoolean (option_arg, false, &success);
1287                    if (success)
1288                        m_from_expression = tmp_value;
1289                    else
1290                    {
1291                        error.SetErrorStringWithFormat ("invalid boolean value '%s' for 'x' option", option_arg);
1292                    }
1293                }
1294                break;
1295                default:
1296                    error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
1297                    break;
1298
1299            }
1300            return error;
1301        }
1302
1303        void
1304        OptionParsingStarting ()
1305        {
1306            m_from_expression = false;
1307        }
1308
1309        const OptionDefinition*
1310        GetDefinitions ()
1311        {
1312            return g_option_table;
1313        }
1314
1315        bool m_from_expression;
1316
1317        // Options table: Required for subclasses of Options.
1318
1319        static OptionDefinition g_option_table[];
1320
1321        // Instance variables to hold the values for command options.
1322    };
1323
1324    virtual
1325    Options *
1326    GetOptions ()
1327    {
1328        return &m_options;
1329    }
1330
1331    CommandObjectThreadReturn (CommandInterpreter &interpreter) :
1332        CommandObjectRaw (interpreter,
1333                          "thread return",
1334                          "Return from the currently selected frame, short-circuiting execution of the frames below it, with an optional return value,"
1335                          " or with the -x option from the innermost function evaluation.",
1336                          "thread return",
1337                          eFlagRequiresFrame         |
1338                          eFlagTryTargetAPILock      |
1339                          eFlagProcessMustBeLaunched |
1340                          eFlagProcessMustBePaused   ),
1341        m_options (interpreter)
1342    {
1343        CommandArgumentEntry arg;
1344        CommandArgumentData expression_arg;
1345
1346        // Define the first (and only) variant of this arg.
1347        expression_arg.arg_type = eArgTypeExpression;
1348        expression_arg.arg_repetition = eArgRepeatOptional;
1349
1350        // There is only one variant this argument could be; put it into the argument entry.
1351        arg.push_back (expression_arg);
1352
1353        // Push the data for the first argument into the m_arguments vector.
1354        m_arguments.push_back (arg);
1355
1356
1357    }
1358
1359    ~CommandObjectThreadReturn()
1360    {
1361    }
1362
1363protected:
1364
1365    bool DoExecute
1366    (
1367        const char *command,
1368        CommandReturnObject &result
1369    )
1370    {
1371        // I am going to handle this by hand, because I don't want you to have to say:
1372        // "thread return -- -5".
1373        if (command[0] == '-' && command[1] == 'x')
1374        {
1375            if (command && command[2] != '\0')
1376                result.AppendWarning("Return values ignored when returning from user called expressions");
1377
1378            Thread *thread = m_exe_ctx.GetThreadPtr();
1379            Error error;
1380            error = thread->UnwindInnermostExpression();
1381            if (!error.Success())
1382            {
1383                result.AppendErrorWithFormat ("Unwinding expression failed - %s.", error.AsCString());
1384                result.SetStatus (eReturnStatusFailed);
1385            }
1386            else
1387            {
1388                bool success = thread->SetSelectedFrameByIndexNoisily (0, result.GetOutputStream());
1389                if (success)
1390                {
1391                    m_exe_ctx.SetFrameSP(thread->GetSelectedFrame ());
1392                    result.SetStatus (eReturnStatusSuccessFinishResult);
1393                }
1394                else
1395                {
1396                    result.AppendErrorWithFormat ("Could not select 0th frame after unwinding expression.");
1397                    result.SetStatus (eReturnStatusFailed);
1398                }
1399            }
1400            return result.Succeeded();
1401        }
1402
1403        ValueObjectSP return_valobj_sp;
1404
1405        StackFrameSP frame_sp = m_exe_ctx.GetFrameSP();
1406        uint32_t frame_idx = frame_sp->GetFrameIndex();
1407
1408        if (frame_sp->IsInlined())
1409        {
1410            result.AppendError("Don't know how to return from inlined frames.");
1411            result.SetStatus (eReturnStatusFailed);
1412            return false;
1413        }
1414
1415        if (command && command[0] != '\0')
1416        {
1417            Target *target = m_exe_ctx.GetTargetPtr();
1418            EvaluateExpressionOptions options;
1419
1420            options.SetUnwindOnError(true);
1421            options.SetUseDynamic(eNoDynamicValues);
1422
1423            ExecutionResults exe_results = eExecutionSetupError;
1424            exe_results = target->EvaluateExpression (command,
1425                                                      frame_sp.get(),
1426                                                      return_valobj_sp,
1427                                                      options);
1428            if (exe_results != eExecutionCompleted)
1429            {
1430                if (return_valobj_sp)
1431                    result.AppendErrorWithFormat("Error evaluating result expression: %s", return_valobj_sp->GetError().AsCString());
1432                else
1433                    result.AppendErrorWithFormat("Unknown error evaluating result expression.");
1434                result.SetStatus (eReturnStatusFailed);
1435                return false;
1436
1437            }
1438        }
1439
1440        Error error;
1441        ThreadSP thread_sp = m_exe_ctx.GetThreadSP();
1442        const bool broadcast = true;
1443        error = thread_sp->ReturnFromFrame (frame_sp, return_valobj_sp, broadcast);
1444        if (!error.Success())
1445        {
1446            result.AppendErrorWithFormat("Error returning from frame %d of thread %d: %s.", frame_idx, thread_sp->GetIndexID(), error.AsCString());
1447            result.SetStatus (eReturnStatusFailed);
1448            return false;
1449        }
1450
1451        result.SetStatus (eReturnStatusSuccessFinishResult);
1452        return true;
1453    }
1454
1455    CommandOptions m_options;
1456
1457};
1458OptionDefinition
1459CommandObjectThreadReturn::CommandOptions::g_option_table[] =
1460{
1461{ LLDB_OPT_SET_ALL, false, "from-expression",  'x', no_argument, NULL,               0, eArgTypeNone,     "Return from the innermost expression evaluation."},
1462{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1463};
1464
1465//-------------------------------------------------------------------------
1466// CommandObjectMultiwordThread
1467//-------------------------------------------------------------------------
1468
1469CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) :
1470    CommandObjectMultiword (interpreter,
1471                            "thread",
1472                            "A set of commands for operating on one or more threads within a running process.",
1473                            "thread <subcommand> [<subcommand-options>]")
1474{
1475    LoadSubCommand ("backtrace",  CommandObjectSP (new CommandObjectThreadBacktrace (interpreter)));
1476    LoadSubCommand ("continue",   CommandObjectSP (new CommandObjectThreadContinue (interpreter)));
1477    LoadSubCommand ("list",       CommandObjectSP (new CommandObjectThreadList (interpreter)));
1478    LoadSubCommand ("return",     CommandObjectSP (new CommandObjectThreadReturn (interpreter)));
1479    LoadSubCommand ("select",     CommandObjectSP (new CommandObjectThreadSelect (interpreter)));
1480    LoadSubCommand ("until",      CommandObjectSP (new CommandObjectThreadUntil (interpreter)));
1481    LoadSubCommand ("step-in",    CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1482                                                    interpreter,
1483                                                    "thread step-in",
1484                                                    "Source level single step in specified thread (current thread, if none specified).",
1485                                                    NULL,
1486                                                    eStepTypeInto,
1487                                                    eStepScopeSource)));
1488
1489    LoadSubCommand ("step-out",   CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1490                                                    interpreter,
1491                                                    "thread step-out",
1492                                                    "Finish executing the function of the currently selected frame and return to its call site in specified thread (current thread, if none specified).",
1493                                                    NULL,
1494                                                    eStepTypeOut,
1495                                                    eStepScopeSource)));
1496
1497    LoadSubCommand ("step-over",   CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1498                                                    interpreter,
1499                                                    "thread step-over",
1500                                                    "Source level single step in specified thread (current thread, if none specified), stepping over calls.",
1501                                                    NULL,
1502                                                    eStepTypeOver,
1503                                                    eStepScopeSource)));
1504
1505    LoadSubCommand ("step-inst",   CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1506                                                    interpreter,
1507                                                    "thread step-inst",
1508                                                    "Single step one instruction in specified thread (current thread, if none specified).",
1509                                                    NULL,
1510                                                    eStepTypeTrace,
1511                                                    eStepScopeInstruction)));
1512
1513    LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1514                                                    interpreter,
1515                                                    "thread step-inst-over",
1516                                                    "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.",
1517                                                    NULL,
1518                                                    eStepTypeTraceOver,
1519                                                    eStepScopeInstruction)));
1520}
1521
1522CommandObjectMultiwordThread::~CommandObjectMultiwordThread ()
1523{
1524}
1525
1526
1527