CommandObjectProcess.cpp revision 0baa394cd55c6dfb7a6259d215d0dea2b708067b
1//===-- CommandObjectProcess.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 "CommandObjectProcess.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
16#include "lldb/Interpreter/Args.h"
17#include "lldb/Interpreter/Options.h"
18#include "lldb/Core/State.h"
19#include "lldb/Interpreter/CommandInterpreter.h"
20#include "lldb/Interpreter/CommandReturnObject.h"
21#include "./CommandObjectThread.h"
22#include "lldb/Target/Process.h"
23#include "lldb/Target/Target.h"
24#include "lldb/Target/Thread.h"
25
26using namespace lldb;
27using namespace lldb_private;
28
29//-------------------------------------------------------------------------
30// CommandObjectProcessLaunch
31//-------------------------------------------------------------------------
32
33class CommandObjectProcessLaunch : public CommandObject
34{
35public:
36
37    class CommandOptions : public Options
38    {
39    public:
40
41        CommandOptions () :
42            Options()
43        {
44            // Keep default values of all options in one place: ResetOptionValues ()
45            ResetOptionValues ();
46        }
47
48        ~CommandOptions ()
49        {
50        }
51
52        Error
53        SetOptionValue (int option_idx, const char *option_arg)
54        {
55            Error error;
56            char short_option = (char) m_getopt_table[option_idx].val;
57
58            switch (short_option)
59            {
60                case 's':   stop_at_entry = true;       break;
61                case 'e':   stderr_path = option_arg;   break;
62                case 'i':   stdin_path  = option_arg;   break;
63                case 'o':   stdout_path = option_arg;   break;
64                case 'p':   plugin_name = option_arg;   break;
65                case 't':
66                    if (option_arg && option_arg[0])
67                        tty_name.assign (option_arg);
68                    in_new_tty = true;
69                    break;
70                default:
71                    error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
72                    break;
73
74            }
75            return error;
76        }
77
78        void
79        ResetOptionValues ()
80        {
81            Options::ResetOptionValues();
82            stop_at_entry = false;
83            in_new_tty = false;
84            tty_name.clear();
85            stdin_path.clear();
86            stdout_path.clear();
87            stderr_path.clear();
88            plugin_name.clear();
89        }
90
91        const lldb::OptionDefinition*
92        GetDefinitions ()
93        {
94            return g_option_table;
95        }
96
97        // Options table: Required for subclasses of Options.
98
99        static lldb::OptionDefinition g_option_table[];
100
101        // Instance variables to hold the values for command options.
102
103        bool stop_at_entry;
104        bool in_new_tty;
105        std::string tty_name;
106        std::string stderr_path;
107        std::string stdin_path;
108        std::string stdout_path;
109        std::string plugin_name;
110
111    };
112
113    CommandObjectProcessLaunch (CommandInterpreter &interpreter) :
114        CommandObject (interpreter,
115                       "process launch",
116                       "Launch the executable in the debugger.",
117                       NULL)
118    {
119        CommandArgumentEntry arg;
120        CommandArgumentData run_args_arg;
121
122        // Define the first (and only) variant of this arg.
123        run_args_arg.arg_type = eArgTypeRunArgs;
124        run_args_arg.arg_repetition = eArgRepeatOptional;
125
126        // There is only one variant this argument could be; put it into the argument entry.
127        arg.push_back (run_args_arg);
128
129        // Push the data for the first argument into the m_arguments vector.
130        m_arguments.push_back (arg);
131    }
132
133
134    ~CommandObjectProcessLaunch ()
135    {
136    }
137
138    Options *
139    GetOptions ()
140    {
141        return &m_options;
142    }
143
144    bool
145    Execute (Args& launch_args, CommandReturnObject &result)
146    {
147        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
148
149        if (target == NULL)
150        {
151            result.AppendError ("invalid target, set executable file using 'file' command");
152            result.SetStatus (eReturnStatusFailed);
153            return false;
154        }
155
156        // If our listener is NULL, users aren't allows to launch
157        char filename[PATH_MAX];
158        const Module *exe_module = target->GetExecutableModule().get();
159        exe_module->GetFileSpec().GetPath(filename, sizeof(filename));
160
161        Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
162        if (process && process->IsAlive())
163        {
164            result.AppendErrorWithFormat ("Process %u is currently being debugged, kill the process before running again.\n",
165                                          process->GetID());
166            result.SetStatus (eReturnStatusFailed);
167            return false;
168        }
169
170        const char *plugin_name;
171        if (!m_options.plugin_name.empty())
172            plugin_name = m_options.plugin_name.c_str();
173        else
174            plugin_name = NULL;
175
176        process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name).get();
177
178        if (process == NULL)
179        {
180            result.AppendErrorWithFormat ("Failed to find a process plugin for executable.\n");
181            result.SetStatus (eReturnStatusFailed);
182            return false;
183        }
184
185        // If no launch args were given on the command line, then use any that
186        // might have been set using the "run-args" set variable.
187        if (launch_args.GetArgumentCount() == 0)
188        {
189            if (process->GetRunArguments().GetArgumentCount() > 0)
190                launch_args = process->GetRunArguments();
191        }
192
193        if (m_options.in_new_tty)
194        {
195            char exec_file_path[PATH_MAX];
196            if (exe_module->GetFileSpec().GetPath(exec_file_path, sizeof(exec_file_path)))
197            {
198                launch_args.InsertArgumentAtIndex(0, exec_file_path);
199            }
200            else
201            {
202                result.AppendError("invalid executable");
203                result.SetStatus (eReturnStatusFailed);
204                return false;
205            }
206        }
207
208        Args environment;
209
210        process->GetEnvironmentAsArgs (environment);
211
212        uint32_t launch_flags = eLaunchFlagNone;
213
214        if (process->GetDisableASLR())
215            launch_flags |= eLaunchFlagDisableASLR;
216
217        const char **inferior_argv = launch_args.GetArgumentCount() ? launch_args.GetConstArgumentVector() : NULL;
218        const char **inferior_envp = environment.GetArgumentCount() ? environment.GetConstArgumentVector() : NULL;
219
220        Error error;
221
222        if (m_options.in_new_tty)
223        {
224
225            lldb::pid_t pid = Host::LaunchInNewTerminal (m_options.tty_name.c_str(),
226                                                         inferior_argv,
227                                                         inferior_envp,
228                                                         &exe_module->GetArchitecture(),
229                                                         true,
230                                                         process->GetDisableASLR());
231
232            if (pid != LLDB_INVALID_PROCESS_ID)
233                error = process->Attach (pid);
234        }
235        else
236        {
237            const char * stdin_path = NULL;
238            const char * stdout_path = NULL;
239            const char * stderr_path = NULL;
240
241            // Were any standard input/output/error paths given on the command line?
242            if (m_options.stdin_path.empty() &&
243                m_options.stdout_path.empty() &&
244                m_options.stderr_path.empty())
245            {
246                // No standard file handles were given on the command line, check
247                // with the process object in case they were give using "set settings"
248                stdin_path = process->GetStandardInputPath();
249                stdout_path = process->GetStandardOutputPath();
250                stderr_path = process->GetStandardErrorPath();
251            }
252            else
253            {
254                stdin_path = m_options.stdin_path.empty()  ? NULL : m_options.stdin_path.c_str();
255                stdout_path = m_options.stdout_path.empty() ? NULL : m_options.stdout_path.c_str();
256                stderr_path = m_options.stderr_path.empty() ? NULL : m_options.stderr_path.c_str();
257            }
258
259            if (stdin_path == NULL)
260                stdin_path = "/dev/null";
261            if (stdout_path == NULL)
262                stdout_path = "/dev/null";
263            if (stderr_path == NULL)
264                stderr_path = "/dev/null";
265
266            error = process->Launch (inferior_argv,
267                                     inferior_envp,
268                                     launch_flags,
269                                     stdin_path,
270                                     stdout_path,
271                                     stderr_path);
272        }
273
274        if (error.Success())
275        {
276            const char *archname = exe_module->GetArchitecture().AsCString();
277
278            result.AppendMessageWithFormat ("Process %i launched: '%s' (%s)\n", process->GetID(), filename, archname);
279            result.SetDidChangeProcessState (true);
280            if (m_options.stop_at_entry == false)
281            {
282                result.SetStatus (eReturnStatusSuccessContinuingNoResult);
283                StateType state = process->WaitForProcessToStop (NULL);
284
285                if (state == eStateStopped)
286                {
287                    error = process->Resume();
288                    if (error.Success())
289                    {
290                        bool synchronous_execution = m_interpreter.GetSynchronous ();
291                        if (synchronous_execution)
292                        {
293                            state = process->WaitForProcessToStop (NULL);
294                            result.SetDidChangeProcessState (true);
295                            result.SetStatus (eReturnStatusSuccessFinishResult);
296                        }
297                        else
298                        {
299                            result.SetStatus (eReturnStatusSuccessContinuingNoResult);
300                        }
301                    }
302                }
303            }
304        }
305
306        return result.Succeeded();
307    }
308
309    virtual const char *GetRepeatCommand (Args &current_command_args, uint32_t index)
310    {
311        // No repeat for "process launch"...
312        return "";
313    }
314
315protected:
316
317    CommandOptions m_options;
318};
319
320
321#define SET1 LLDB_OPT_SET_1
322#define SET2 LLDB_OPT_SET_2
323
324lldb::OptionDefinition
325CommandObjectProcessLaunch::CommandOptions::g_option_table[] =
326{
327{ SET1 | SET2, false, "stop-at-entry", 's', no_argument,       NULL, 0, eArgTypeNone,    "Stop at the entry point of the program when launching a process."},
328{ SET1       , false, "stdin",         'i', required_argument, NULL, 0, eArgTypePath,    "Redirect stdin for the process to <path>."},
329{ SET1       , false, "stdout",        'o', required_argument, NULL, 0, eArgTypePath,    "Redirect stdout for the process to <path>."},
330{ SET1       , false, "stderr",        'e', required_argument, NULL, 0, eArgTypePath,    "Redirect stderr for the process to <path>."},
331{ SET1 | SET2, false, "plugin",        'p', required_argument, NULL, 0, eArgTypePlugin,  "Name of the process plugin you want to use."},
332{        SET2, false, "tty",           't', optional_argument, NULL, 0, eArgTypePath,    "Start the process in a terminal. If <path> is specified, look for a terminal whose name contains <path>, else start the process in a new terminal."},
333{ 0,           false, NULL,             0,  0,                 NULL, 0, eArgTypeNone,    NULL }
334};
335
336#undef SET1
337#undef SET2
338
339//-------------------------------------------------------------------------
340// CommandObjectProcessAttach
341//-------------------------------------------------------------------------
342
343class CommandObjectProcessAttach : public CommandObject
344{
345public:
346
347    class CommandOptions : public Options
348    {
349    public:
350
351        CommandOptions () :
352            Options()
353        {
354            // Keep default values of all options in one place: ResetOptionValues ()
355            ResetOptionValues ();
356        }
357
358        ~CommandOptions ()
359        {
360        }
361
362        Error
363        SetOptionValue (int option_idx, const char *option_arg)
364        {
365            Error error;
366            char short_option = (char) m_getopt_table[option_idx].val;
367            bool success = false;
368            switch (short_option)
369            {
370                case 'p':
371                    pid = Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success);
372                    if (!success || pid == LLDB_INVALID_PROCESS_ID)
373                    {
374                        error.SetErrorStringWithFormat("Invalid process ID '%s'.\n", option_arg);
375                    }
376                    break;
377
378                case 'P':
379                    plugin_name = option_arg;
380                    break;
381
382                case 'n':
383                    name.assign(option_arg);
384                    break;
385
386                case 'w':
387                    waitfor = true;
388                    break;
389
390                default:
391                    error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
392                    break;
393            }
394            return error;
395        }
396
397        void
398        ResetOptionValues ()
399        {
400            Options::ResetOptionValues();
401            pid = LLDB_INVALID_PROCESS_ID;
402            name.clear();
403            waitfor = false;
404        }
405
406        const lldb::OptionDefinition*
407        GetDefinitions ()
408        {
409            return g_option_table;
410        }
411
412        virtual bool
413        HandleOptionArgumentCompletion (CommandInterpreter &interpeter,
414                                        Args &input,
415                                        int cursor_index,
416                                        int char_pos,
417                                        OptionElementVector &opt_element_vector,
418                                        int opt_element_index,
419                                        int match_start_point,
420                                        int max_return_elements,
421                                        bool &word_complete,
422                                        StringList &matches)
423        {
424            int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
425            int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
426
427            // We are only completing the name option for now...
428
429            const lldb::OptionDefinition *opt_defs = GetDefinitions();
430            if (opt_defs[opt_defs_index].short_option == 'n')
431            {
432                // Are we in the name?
433
434                // Look to see if there is a -P argument provided, and if so use that plugin, otherwise
435                // use the default plugin.
436                Process *process = interpeter.GetDebugger().GetExecutionContext().process;
437                bool need_to_delete_process = false;
438
439                const char *partial_name = NULL;
440                partial_name = input.GetArgumentAtIndex(opt_arg_pos);
441
442                if (process && process->IsAlive())
443                    return true;
444
445                Target *target = interpeter.GetDebugger().GetSelectedTarget().get();
446                if (target == NULL)
447                {
448                    // No target has been set yet, for now do host completion.  Otherwise I don't know how we would
449                    // figure out what the right target to use is...
450                    std::vector<lldb::pid_t> pids;
451                    Host::ListProcessesMatchingName (partial_name, matches, pids);
452                    return true;
453                }
454                if (!process)
455                {
456                    process = target->CreateProcess (interpeter.GetDebugger().GetListener(), partial_name).get();
457                    need_to_delete_process = true;
458                }
459
460                if (process)
461                {
462                    matches.Clear();
463                    std::vector<lldb::pid_t> pids;
464                    process->ListProcessesMatchingName (NULL, matches, pids);
465                    if (need_to_delete_process)
466                        target->DeleteCurrentProcess();
467                    return true;
468                }
469            }
470
471            return false;
472        }
473
474        // Options table: Required for subclasses of Options.
475
476        static lldb::OptionDefinition g_option_table[];
477
478        // Instance variables to hold the values for command options.
479
480        lldb::pid_t pid;
481        std::string plugin_name;
482        std::string name;
483        bool waitfor;
484    };
485
486    CommandObjectProcessAttach (CommandInterpreter &interpreter) :
487        CommandObject (interpreter,
488                       "process attach",
489                       "Attach to a process.",
490                       "process attach <cmd-options>")
491    {
492    }
493
494    ~CommandObjectProcessAttach ()
495    {
496    }
497
498    bool
499    Execute (Args& command,
500             CommandReturnObject &result)
501    {
502        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
503
504        Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
505        if (process)
506        {
507            if (process->IsAlive())
508            {
509                result.AppendErrorWithFormat ("Process %u is currently being debugged, kill the process before attaching.\n",
510                                              process->GetID());
511                result.SetStatus (eReturnStatusFailed);
512                return false;
513            }
514        }
515
516        if (target == NULL)
517        {
518            // If there isn't a current target create one.
519            TargetSP new_target_sp;
520            FileSpec emptyFileSpec;
521            ArchSpec emptyArchSpec;
522            Error error;
523
524            error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(),
525                                                                              emptyFileSpec,
526                                                                              emptyArchSpec,
527                                                                              NULL,
528                                                                              false,
529                                                                              new_target_sp);
530            target = new_target_sp.get();
531            if (target == NULL || error.Fail())
532            {
533                result.AppendError(error.AsCString("Error creating empty target"));
534                return false;
535            }
536            m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target);
537        }
538
539        // Record the old executable module, we want to issue a warning if the process of attaching changed the
540        // current executable (like somebody said "file foo" then attached to a PID whose executable was bar.)
541
542        ModuleSP old_exec_module_sp = target->GetExecutableModule();
543        ArchSpec old_arch_spec = target->GetArchitecture();
544
545        if (command.GetArgumentCount())
546        {
547            result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: \n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
548            result.SetStatus (eReturnStatusFailed);
549        }
550        else
551        {
552            const char *plugin_name = NULL;
553
554            if (!m_options.plugin_name.empty())
555                plugin_name = m_options.plugin_name.c_str();
556
557            process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name).get();
558
559            if (process)
560            {
561                Error error;
562                int attach_pid = m_options.pid;
563
564                const char *wait_name = NULL;
565
566                if (m_options.name.empty())
567                {
568                    if (old_exec_module_sp)
569                    {
570                        wait_name = old_exec_module_sp->GetFileSpec().GetFilename().AsCString();
571                    }
572                }
573                else
574                {
575                    wait_name = m_options.name.c_str();
576                }
577
578                // If we are waiting for a process with this name to show up, do that first.
579                if (m_options.waitfor)
580                {
581
582                    if (wait_name == NULL)
583                    {
584                        result.AppendError("Invalid arguments: must have a file loaded or supply a process name with the waitfor option.\n");
585                        result.SetStatus (eReturnStatusFailed);
586                        return false;
587                    }
588
589                    m_interpreter.GetDebugger().GetOutputStream().Printf("Waiting to attach to a process named \"%s\".\n", wait_name);
590                    error = process->Attach (wait_name, m_options.waitfor);
591                    if (error.Success())
592                    {
593                        result.SetStatus (eReturnStatusSuccessContinuingNoResult);
594                    }
595                    else
596                    {
597                        result.AppendErrorWithFormat ("Waiting for a process to launch named '%s': %s\n",
598                                                         wait_name,
599                                                         error.AsCString());
600                        result.SetStatus (eReturnStatusFailed);
601                        return false;
602                    }
603                }
604                else
605                {
606                    // If the process was specified by name look it up, so we can warn if there are multiple
607                    // processes with this pid.
608
609                    if (attach_pid == LLDB_INVALID_PROCESS_ID && wait_name != NULL)
610                    {
611                        std::vector<lldb::pid_t> pids;
612                        StringList matches;
613
614                        process->ListProcessesMatchingName(wait_name, matches, pids);
615                        if (matches.GetSize() > 1)
616                        {
617                            result.AppendErrorWithFormat("More than one process named %s\n", wait_name);
618                            result.SetStatus (eReturnStatusFailed);
619                            return false;
620                        }
621                        else if (matches.GetSize() == 0)
622                        {
623                            result.AppendErrorWithFormat("Could not find a process named %s\n", wait_name);
624                            result.SetStatus (eReturnStatusFailed);
625                            return false;
626                        }
627                        else
628                        {
629                            attach_pid = pids[0];
630                        }
631
632                    }
633
634                    if (attach_pid != LLDB_INVALID_PROCESS_ID)
635                    {
636                        error = process->Attach (attach_pid);
637                        if (error.Success())
638                        {
639                            result.SetStatus (eReturnStatusSuccessContinuingNoResult);
640                        }
641                        else
642                        {
643                            result.AppendErrorWithFormat ("Attaching to process %i failed: %s.\n",
644                                                         attach_pid,
645                                                         error.AsCString());
646                            result.SetStatus (eReturnStatusFailed);
647                        }
648                    }
649                    else
650                    {
651                        result.AppendErrorWithFormat ("No PID specified for attach\n",
652                                                         attach_pid,
653                                                         error.AsCString());
654                        result.SetStatus (eReturnStatusFailed);
655
656                    }
657                }
658            }
659        }
660
661        if (result.Succeeded())
662        {
663            // Okay, we're done.  Last step is to warn if the executable module has changed:
664            if (!old_exec_module_sp)
665            {
666                char new_path[PATH_MAX + 1];
667                target->GetExecutableModule()->GetFileSpec().GetPath(new_path, PATH_MAX);
668
669                result.AppendMessageWithFormat("Executable module set to \"%s\".\n",
670                    new_path);
671            }
672            else if (old_exec_module_sp->GetFileSpec() != target->GetExecutableModule()->GetFileSpec())
673            {
674                char old_path[PATH_MAX + 1];
675                char new_path[PATH_MAX + 1];
676
677                old_exec_module_sp->GetFileSpec().GetPath(old_path, PATH_MAX);
678                target->GetExecutableModule()->GetFileSpec().GetPath (new_path, PATH_MAX);
679
680                result.AppendWarningWithFormat("Executable module changed from \"%s\" to \"%s\".\n",
681                                                    old_path, new_path);
682            }
683
684            if (!old_arch_spec.IsValid())
685            {
686                result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().AsCString());
687            }
688            else if (old_arch_spec != target->GetArchitecture())
689            {
690                result.AppendWarningWithFormat("Architecture changed from %s to %s.\n",
691                                                old_arch_spec.AsCString(), target->GetArchitecture().AsCString());
692            }
693        }
694        return result.Succeeded();
695    }
696
697    Options *
698    GetOptions ()
699    {
700        return &m_options;
701    }
702
703protected:
704
705    CommandOptions m_options;
706};
707
708
709lldb::OptionDefinition
710CommandObjectProcessAttach::CommandOptions::g_option_table[] =
711{
712{ LLDB_OPT_SET_ALL, false, "plugin", 'P', required_argument, NULL, 0, eArgTypePlugin,        "Name of the process plugin you want to use."},
713{ LLDB_OPT_SET_1,   false, "pid",    'p', required_argument, NULL, 0, eArgTypePid,           "The process ID of an existing process to attach to."},
714{ LLDB_OPT_SET_2,   false, "name",   'n', required_argument, NULL, 0, eArgTypeProcessName,  "The name of the process to attach to."},
715{ LLDB_OPT_SET_2,   false, "waitfor",'w', no_argument,       NULL, 0, eArgTypeNone,              "Wait for the the process with <process-name> to launch."},
716{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
717};
718
719//-------------------------------------------------------------------------
720// CommandObjectProcessContinue
721//-------------------------------------------------------------------------
722
723class CommandObjectProcessContinue : public CommandObject
724{
725public:
726
727    CommandObjectProcessContinue (CommandInterpreter &interpreter) :
728        CommandObject (interpreter,
729                       "process continue",
730                       "Continue execution of all threads in the current process.",
731                       "process continue",
732                       eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
733    {
734    }
735
736
737    ~CommandObjectProcessContinue ()
738    {
739    }
740
741    bool
742    Execute (Args& command,
743             CommandReturnObject &result)
744    {
745        Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
746        bool synchronous_execution = m_interpreter.GetSynchronous ();
747
748        if (process == NULL)
749        {
750            result.AppendError ("no process to continue");
751            result.SetStatus (eReturnStatusFailed);
752            return false;
753         }
754
755        StateType state = process->GetState();
756        if (state == eStateStopped)
757        {
758            if (command.GetArgumentCount() != 0)
759            {
760                result.AppendErrorWithFormat ("The '%s' command does not take any arguments.\n", m_cmd_name.c_str());
761                result.SetStatus (eReturnStatusFailed);
762                return false;
763            }
764
765            const uint32_t num_threads = process->GetThreadList().GetSize();
766
767            // Set the actions that the threads should each take when resuming
768            for (uint32_t idx=0; idx<num_threads; ++idx)
769            {
770                process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState (eStateRunning);
771            }
772
773            Error error(process->Resume());
774            if (error.Success())
775            {
776                result.AppendMessageWithFormat ("Process %i resuming\n", process->GetID());
777                if (synchronous_execution)
778                {
779                    state = process->WaitForProcessToStop (NULL);
780
781                    result.SetDidChangeProcessState (true);
782                    result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state));
783                    result.SetStatus (eReturnStatusSuccessFinishNoResult);
784                }
785                else
786                {
787                    result.SetStatus (eReturnStatusSuccessContinuingNoResult);
788                }
789            }
790            else
791            {
792                result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
793                result.SetStatus (eReturnStatusFailed);
794            }
795        }
796        else
797        {
798            result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
799                                         StateAsCString(state));
800            result.SetStatus (eReturnStatusFailed);
801        }
802        return result.Succeeded();
803    }
804};
805
806//-------------------------------------------------------------------------
807// CommandObjectProcessDetach
808//-------------------------------------------------------------------------
809
810class CommandObjectProcessDetach : public CommandObject
811{
812public:
813
814    CommandObjectProcessDetach (CommandInterpreter &interpreter) :
815        CommandObject (interpreter,
816                       "process detach",
817                       "Detach from the current process being debugged.",
818                       "process detach",
819                       eFlagProcessMustBeLaunched)
820    {
821    }
822
823    ~CommandObjectProcessDetach ()
824    {
825    }
826
827    bool
828    Execute (Args& command,
829             CommandReturnObject &result)
830    {
831        Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
832        if (process == NULL)
833        {
834            result.AppendError ("must have a valid process in order to detach");
835            result.SetStatus (eReturnStatusFailed);
836            return false;
837        }
838
839        result.AppendMessageWithFormat ("Detaching from process %i\n", process->GetID());
840        Error error (process->Detach());
841        if (error.Success())
842        {
843            result.SetStatus (eReturnStatusSuccessFinishResult);
844        }
845        else
846        {
847            result.AppendErrorWithFormat ("Detach failed: %s\n", error.AsCString());
848            result.SetStatus (eReturnStatusFailed);
849            return false;
850        }
851        return result.Succeeded();
852    }
853};
854
855//-------------------------------------------------------------------------
856// CommandObjectProcessLoad
857//-------------------------------------------------------------------------
858
859class CommandObjectProcessLoad : public CommandObject
860{
861public:
862
863    CommandObjectProcessLoad (CommandInterpreter &interpreter) :
864        CommandObject (interpreter,
865                       "process load",
866                       "Load a shared library into the current process.",
867                       "process load <filename> [<filename> ...]",
868                       eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
869    {
870    }
871
872    ~CommandObjectProcessLoad ()
873    {
874    }
875
876    bool
877    Execute (Args& command,
878             CommandReturnObject &result)
879    {
880        Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
881        if (process == NULL)
882        {
883            result.AppendError ("must have a valid process in order to load a shared library");
884            result.SetStatus (eReturnStatusFailed);
885            return false;
886        }
887
888        const uint32_t argc = command.GetArgumentCount();
889
890        for (uint32_t i=0; i<argc; ++i)
891        {
892            Error error;
893            const char *image_path = command.GetArgumentAtIndex(i);
894            FileSpec image_spec (image_path, false);
895            uint32_t image_token = process->LoadImage(image_spec, error);
896            if (image_token != LLDB_INVALID_IMAGE_TOKEN)
897            {
898                result.AppendMessageWithFormat ("Loading \"%s\"...ok\nImage %u loaded.\n", image_path, image_token);
899                result.SetStatus (eReturnStatusSuccessFinishResult);
900            }
901            else
902            {
903                result.AppendErrorWithFormat ("failed to load '%s': %s", image_path, error.AsCString());
904                result.SetStatus (eReturnStatusFailed);
905            }
906        }
907        return result.Succeeded();
908    }
909};
910
911
912//-------------------------------------------------------------------------
913// CommandObjectProcessUnload
914//-------------------------------------------------------------------------
915
916class CommandObjectProcessUnload : public CommandObject
917{
918public:
919
920    CommandObjectProcessUnload (CommandInterpreter &interpreter) :
921        CommandObject (interpreter,
922                       "process unload",
923                       "Unload a shared library from the current process using the index returned by a previous call to \"process load\".",
924                       "process unload <index>",
925                       eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
926    {
927    }
928
929    ~CommandObjectProcessUnload ()
930    {
931    }
932
933    bool
934    Execute (Args& command,
935             CommandReturnObject &result)
936    {
937        Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
938        if (process == NULL)
939        {
940            result.AppendError ("must have a valid process in order to load a shared library");
941            result.SetStatus (eReturnStatusFailed);
942            return false;
943        }
944
945        const uint32_t argc = command.GetArgumentCount();
946
947        for (uint32_t i=0; i<argc; ++i)
948        {
949            const char *image_token_cstr = command.GetArgumentAtIndex(i);
950            uint32_t image_token = Args::StringToUInt32(image_token_cstr, LLDB_INVALID_IMAGE_TOKEN, 0);
951            if (image_token == LLDB_INVALID_IMAGE_TOKEN)
952            {
953                result.AppendErrorWithFormat ("invalid image index argument '%s'", image_token_cstr);
954                result.SetStatus (eReturnStatusFailed);
955                break;
956            }
957            else
958            {
959                Error error (process->UnloadImage(image_token));
960                if (error.Success())
961                {
962                    result.AppendMessageWithFormat ("Unloading shared library with index %u...ok\n", image_token);
963                    result.SetStatus (eReturnStatusSuccessFinishResult);
964                }
965                else
966                {
967                    result.AppendErrorWithFormat ("failed to unload image: %s", error.AsCString());
968                    result.SetStatus (eReturnStatusFailed);
969                    break;
970                }
971            }
972        }
973        return result.Succeeded();
974    }
975};
976
977//-------------------------------------------------------------------------
978// CommandObjectProcessSignal
979//-------------------------------------------------------------------------
980
981class CommandObjectProcessSignal : public CommandObject
982{
983public:
984
985    CommandObjectProcessSignal (CommandInterpreter &interpreter) :
986        CommandObject (interpreter,
987                       "process signal",
988                       "Send a UNIX signal to the current process being debugged.",
989                       NULL)
990    {
991        CommandArgumentEntry arg;
992        CommandArgumentData signal_arg;
993
994        // Define the first (and only) variant of this arg.
995        signal_arg.arg_type = eArgTypeUnixSignal;
996        signal_arg.arg_repetition = eArgRepeatPlain;
997
998        // There is only one variant this argument could be; put it into the argument entry.
999        arg.push_back (signal_arg);
1000
1001        // Push the data for the first argument into the m_arguments vector.
1002        m_arguments.push_back (arg);
1003    }
1004
1005    ~CommandObjectProcessSignal ()
1006    {
1007    }
1008
1009    bool
1010    Execute (Args& command,
1011             CommandReturnObject &result)
1012    {
1013        Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
1014        if (process == NULL)
1015        {
1016            result.AppendError ("no process to signal");
1017            result.SetStatus (eReturnStatusFailed);
1018            return false;
1019        }
1020
1021        if (command.GetArgumentCount() == 1)
1022        {
1023            int signo = LLDB_INVALID_SIGNAL_NUMBER;
1024
1025            const char *signal_name = command.GetArgumentAtIndex(0);
1026            if (::isxdigit (signal_name[0]))
1027                signo = Args::StringToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0);
1028            else
1029                signo = process->GetUnixSignals().GetSignalNumberFromName (signal_name);
1030
1031            if (signo == LLDB_INVALID_SIGNAL_NUMBER)
1032            {
1033                result.AppendErrorWithFormat ("Invalid signal argument '%s'.\n", command.GetArgumentAtIndex(0));
1034                result.SetStatus (eReturnStatusFailed);
1035            }
1036            else
1037            {
1038                Error error (process->Signal (signo));
1039                if (error.Success())
1040                {
1041                    result.SetStatus (eReturnStatusSuccessFinishResult);
1042                }
1043                else
1044                {
1045                    result.AppendErrorWithFormat ("Failed to send signal %i: %s\n", signo, error.AsCString());
1046                    result.SetStatus (eReturnStatusFailed);
1047                }
1048            }
1049        }
1050        else
1051        {
1052            result.AppendErrorWithFormat("'%s' takes exactly one signal number argument:\nUsage: \n", m_cmd_name.c_str(),
1053                                        m_cmd_syntax.c_str());
1054            result.SetStatus (eReturnStatusFailed);
1055        }
1056        return result.Succeeded();
1057    }
1058};
1059
1060
1061//-------------------------------------------------------------------------
1062// CommandObjectProcessInterrupt
1063//-------------------------------------------------------------------------
1064
1065class CommandObjectProcessInterrupt : public CommandObject
1066{
1067public:
1068
1069
1070    CommandObjectProcessInterrupt (CommandInterpreter &interpreter) :
1071    CommandObject (interpreter,
1072                   "process interrupt",
1073                   "Interrupt the current process being debugged.",
1074                   "process interrupt",
1075                   eFlagProcessMustBeLaunched)
1076    {
1077    }
1078
1079    ~CommandObjectProcessInterrupt ()
1080    {
1081    }
1082
1083    bool
1084    Execute (Args& command,
1085             CommandReturnObject &result)
1086    {
1087        Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
1088        if (process == NULL)
1089        {
1090            result.AppendError ("no process to halt");
1091            result.SetStatus (eReturnStatusFailed);
1092            return false;
1093        }
1094
1095        if (command.GetArgumentCount() == 0)
1096        {
1097            Error error(process->Halt ());
1098            if (error.Success())
1099            {
1100                result.SetStatus (eReturnStatusSuccessFinishResult);
1101
1102                // Maybe we should add a "SuspendThreadPlans so we
1103                // can halt, and keep in place all the current thread plans.
1104                process->GetThreadList().DiscardThreadPlans();
1105            }
1106            else
1107            {
1108                result.AppendErrorWithFormat ("Failed to halt process: %s\n", error.AsCString());
1109                result.SetStatus (eReturnStatusFailed);
1110            }
1111        }
1112        else
1113        {
1114            result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: \n",
1115                                        m_cmd_name.c_str(),
1116                                        m_cmd_syntax.c_str());
1117            result.SetStatus (eReturnStatusFailed);
1118        }
1119        return result.Succeeded();
1120    }
1121};
1122
1123//-------------------------------------------------------------------------
1124// CommandObjectProcessKill
1125//-------------------------------------------------------------------------
1126
1127class CommandObjectProcessKill : public CommandObject
1128{
1129public:
1130
1131    CommandObjectProcessKill (CommandInterpreter &interpreter) :
1132    CommandObject (interpreter,
1133                   "process kill",
1134                   "Terminate the current process being debugged.",
1135                   "process kill",
1136                   eFlagProcessMustBeLaunched)
1137    {
1138    }
1139
1140    ~CommandObjectProcessKill ()
1141    {
1142    }
1143
1144    bool
1145    Execute (Args& command,
1146             CommandReturnObject &result)
1147    {
1148        Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
1149        if (process == NULL)
1150        {
1151            result.AppendError ("no process to kill");
1152            result.SetStatus (eReturnStatusFailed);
1153            return false;
1154        }
1155
1156        if (command.GetArgumentCount() == 0)
1157        {
1158            Error error (process->Destroy());
1159            if (error.Success())
1160            {
1161                result.SetStatus (eReturnStatusSuccessFinishResult);
1162            }
1163            else
1164            {
1165                result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString());
1166                result.SetStatus (eReturnStatusFailed);
1167            }
1168        }
1169        else
1170        {
1171            result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: \n",
1172                                        m_cmd_name.c_str(),
1173                                        m_cmd_syntax.c_str());
1174            result.SetStatus (eReturnStatusFailed);
1175        }
1176        return result.Succeeded();
1177    }
1178};
1179
1180//-------------------------------------------------------------------------
1181// CommandObjectProcessStatus
1182//-------------------------------------------------------------------------
1183class CommandObjectProcessStatus : public CommandObject
1184{
1185public:
1186    CommandObjectProcessStatus (CommandInterpreter &interpreter) :
1187    CommandObject (interpreter,
1188                   "process status",
1189                   "Show the current status and location of executing process.",
1190                   "process status",
1191                   0)
1192    {
1193    }
1194
1195    ~CommandObjectProcessStatus()
1196    {
1197    }
1198
1199
1200    bool
1201    Execute
1202    (
1203        Args& command,
1204        CommandReturnObject &result
1205    )
1206    {
1207        StreamString &output_stream = result.GetOutputStream();
1208        result.SetStatus (eReturnStatusSuccessFinishNoResult);
1209        ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext());
1210        if (exe_ctx.process)
1211        {
1212            const StateType state = exe_ctx.process->GetState();
1213            if (StateIsStoppedState(state))
1214            {
1215                if (state == eStateExited)
1216                {
1217                    int exit_status = exe_ctx.process->GetExitStatus();
1218                    const char *exit_description = exe_ctx.process->GetExitDescription();
1219                    output_stream.Printf ("Process %d exited with status = %i (0x%8.8x) %s\n",
1220                                          exe_ctx.process->GetID(),
1221                                          exit_status,
1222                                          exit_status,
1223                                          exit_description ? exit_description : "");
1224                }
1225                else
1226                {
1227                    output_stream.Printf ("Process %d %s\n", exe_ctx.process->GetID(), StateAsCString (state));
1228                    if (exe_ctx.thread == NULL)
1229                        exe_ctx.thread = exe_ctx.process->GetThreadList().GetThreadAtIndex(0).get();
1230                    if (exe_ctx.thread != NULL)
1231                    {
1232                        DisplayThreadsInfo (m_interpreter, &exe_ctx, result, true, true);
1233                    }
1234                    else
1235                    {
1236                        result.AppendError ("No valid thread found in current process.");
1237                        result.SetStatus (eReturnStatusFailed);
1238                    }
1239                }
1240            }
1241            else
1242            {
1243                output_stream.Printf ("Process %d is running.\n",
1244                                          exe_ctx.process->GetID());
1245            }
1246        }
1247        else
1248        {
1249            result.AppendError ("No current location or status available.");
1250            result.SetStatus (eReturnStatusFailed);
1251        }
1252        return result.Succeeded();
1253    }
1254};
1255
1256//-------------------------------------------------------------------------
1257// CommandObjectProcessHandle
1258//-------------------------------------------------------------------------
1259
1260class CommandObjectProcessHandle : public CommandObject
1261{
1262public:
1263
1264    class CommandOptions : public Options
1265    {
1266    public:
1267
1268        CommandOptions () :
1269            Options ()
1270        {
1271            ResetOptionValues ();
1272        }
1273
1274        ~CommandOptions ()
1275        {
1276        }
1277
1278        Error
1279        SetOptionValue (int option_idx, const char *option_arg)
1280        {
1281            Error error;
1282            char short_option = (char) m_getopt_table[option_idx].val;
1283
1284            switch (short_option)
1285            {
1286                case 's':
1287                    stop = option_arg;
1288                    break;
1289                case 'n':
1290                    notify = option_arg;
1291                    break;
1292                case 'p':
1293                    pass = option_arg;
1294                    break;
1295                default:
1296                    error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
1297                    break;
1298            }
1299            return error;
1300        }
1301
1302        void
1303        ResetOptionValues ()
1304        {
1305            Options::ResetOptionValues();
1306            stop.clear();
1307            notify.clear();
1308            pass.clear();
1309        }
1310
1311        const lldb::OptionDefinition*
1312        GetDefinitions ()
1313        {
1314            return g_option_table;
1315        }
1316
1317        // Options table: Required for subclasses of Options.
1318
1319        static lldb::OptionDefinition g_option_table[];
1320
1321        // Instance variables to hold the values for command options.
1322
1323        std::string stop;
1324        std::string notify;
1325        std::string pass;
1326    };
1327
1328
1329    CommandObjectProcessHandle (CommandInterpreter &interpreter) :
1330        CommandObject (interpreter,
1331                       "process handle",
1332                       "Show or update what the process and debugger should do with various signals received from the OS.",
1333                       NULL)
1334    {
1335        SetHelpLong ("If no signals are specified, update them all.  If no update option is specified, list the current values.\n");
1336        CommandArgumentEntry arg;
1337        CommandArgumentData signal_arg;
1338
1339        signal_arg.arg_type = eArgTypeUnixSignal;
1340        signal_arg.arg_repetition = eArgRepeatStar;
1341
1342        arg.push_back (signal_arg);
1343
1344        m_arguments.push_back (arg);
1345    }
1346
1347    ~CommandObjectProcessHandle ()
1348    {
1349    }
1350
1351    Options *
1352    GetOptions ()
1353    {
1354        return &m_options;
1355    }
1356
1357    bool
1358    VerifyCommandOptionValue (const std::string &option, int &real_value)
1359    {
1360        bool okay = true;
1361
1362        bool success = false;
1363        bool tmp_value = Args::StringToBoolean (option.c_str(), false, &success);
1364
1365        if (success && tmp_value)
1366            real_value = 1;
1367        else if (success && !tmp_value)
1368            real_value = 0;
1369        else
1370        {
1371            // If the value isn't 'true' or 'false', it had better be 0 or 1.
1372            real_value = Args::StringToUInt32 (option.c_str(), 3);
1373            if (real_value != 0 && real_value != 1)
1374                okay = false;
1375        }
1376
1377        return okay;
1378    }
1379
1380    void
1381    PrintSignalHeader (Stream &str)
1382    {
1383        str.Printf ("NAME        PASS   STOP   NOTIFY\n");
1384        str.Printf ("==========  =====  =====  ======\n");
1385    }
1386
1387    void
1388    PrintSignal (Stream &str, int32_t signo, const char *sig_name, UnixSignals &signals)
1389    {
1390        bool stop;
1391        bool suppress;
1392        bool notify;
1393
1394        str.Printf ("%-10s  ", sig_name);
1395        if (signals.GetSignalInfo (signo, suppress, stop, notify))
1396        {
1397            bool pass = !suppress;
1398            str.Printf ("%s  %s  %s",
1399                        (pass ? "true " : "false"),
1400                        (stop ? "true " : "false"),
1401                        (notify ? "true " : "false"));
1402        }
1403        str.Printf ("\n");
1404    }
1405
1406    void
1407    PrintSignalInformation (Stream &str, Args &signal_args, int num_valid_signals, UnixSignals &signals)
1408    {
1409        PrintSignalHeader (str);
1410
1411        if (num_valid_signals > 0)
1412        {
1413            size_t num_args = signal_args.GetArgumentCount();
1414            for (size_t i = 0; i < num_args; ++i)
1415            {
1416                int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i));
1417                if (signo != LLDB_INVALID_SIGNAL_NUMBER)
1418                    PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals);
1419            }
1420        }
1421        else // Print info for ALL signals
1422        {
1423            int32_t signo = signals.GetFirstSignalNumber();
1424            while (signo != LLDB_INVALID_SIGNAL_NUMBER)
1425            {
1426                PrintSignal (str, signo, signals.GetSignalAsCString (signo), signals);
1427                signo = signals.GetNextSignalNumber (signo);
1428            }
1429        }
1430    }
1431
1432    bool
1433    Execute (Args &signal_args, CommandReturnObject &result)
1434    {
1435        TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
1436
1437        if (!target_sp)
1438        {
1439            result.AppendError ("No current target;"
1440                                " cannot handle signals until you have a valid target and process.\n");
1441            result.SetStatus (eReturnStatusFailed);
1442            return false;
1443        }
1444
1445        ProcessSP process_sp = target_sp->GetProcessSP();
1446
1447        if (!process_sp)
1448        {
1449            result.AppendError ("No current process; cannot handle signals until you have a valid process.\n");
1450            result.SetStatus (eReturnStatusFailed);
1451            return false;
1452        }
1453
1454        int stop_action = -1;   // -1 means leave the current setting alone
1455        int pass_action = -1;   // -1 means leave the current setting alone
1456        int notify_action = -1; // -1 means leave the current setting alone
1457
1458        if (! m_options.stop.empty()
1459            && ! VerifyCommandOptionValue (m_options.stop, stop_action))
1460        {
1461            result.AppendError ("Invalid argument for command option --stop; must be true or false.\n");
1462            result.SetStatus (eReturnStatusFailed);
1463            return false;
1464        }
1465
1466        if (! m_options.notify.empty()
1467            && ! VerifyCommandOptionValue (m_options.notify, notify_action))
1468        {
1469            result.AppendError ("Invalid argument for command option --notify; must be true or false.\n");
1470            result.SetStatus (eReturnStatusFailed);
1471            return false;
1472        }
1473
1474        if (! m_options.pass.empty()
1475            && ! VerifyCommandOptionValue (m_options.pass, pass_action))
1476        {
1477            result.AppendError ("Invalid argument for command option --pass; must be true or false.\n");
1478            result.SetStatus (eReturnStatusFailed);
1479            return false;
1480        }
1481
1482        size_t num_args = signal_args.GetArgumentCount();
1483        UnixSignals &signals = process_sp->GetUnixSignals();
1484        int num_signals_set = 0;
1485
1486        if (num_args > 0)
1487        {
1488            for (size_t i = 0; i < num_args; ++i)
1489            {
1490                int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i));
1491                if (signo != LLDB_INVALID_SIGNAL_NUMBER)
1492                {
1493                    // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees
1494                    // the value is either 0 or 1.
1495                    if (stop_action != -1)
1496                        signals.SetShouldStop (signo, (bool) stop_action);
1497                    if (pass_action != -1)
1498                    {
1499                        bool suppress = ! ((bool) pass_action);
1500                        signals.SetShouldSuppress (signo, suppress);
1501                    }
1502                    if (notify_action != -1)
1503                        signals.SetShouldNotify (signo, (bool) notify_action);
1504                    ++num_signals_set;
1505                }
1506                else
1507                {
1508                    result.AppendErrorWithFormat ("Invalid signal name '%s'\n", signal_args.GetArgumentAtIndex (i));
1509                }
1510            }
1511        }
1512        else
1513        {
1514            // No signal specified, if any command options were specified, update ALL signals.
1515            if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1))
1516            {
1517                if (m_interpreter.Confirm ("Do you really want to update all the signals?", false))
1518                {
1519                    int32_t signo = signals.GetFirstSignalNumber();
1520                    while (signo != LLDB_INVALID_SIGNAL_NUMBER)
1521                    {
1522                        if (notify_action != -1)
1523                            signals.SetShouldNotify (signo, (bool) notify_action);
1524                        if (stop_action != -1)
1525                            signals.SetShouldStop (signo, (bool) stop_action);
1526                        if (pass_action != -1)
1527                        {
1528                            bool suppress = ! ((bool) pass_action);
1529                            signals.SetShouldSuppress (signo, suppress);
1530                        }
1531                        signo = signals.GetNextSignalNumber (signo);
1532                    }
1533                }
1534            }
1535        }
1536
1537        PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals);
1538
1539        if (num_signals_set > 0)
1540            result.SetStatus (eReturnStatusSuccessFinishNoResult);
1541        else
1542            result.SetStatus (eReturnStatusFailed);
1543
1544        return result.Succeeded();
1545    }
1546
1547protected:
1548
1549    CommandOptions m_options;
1550};
1551
1552lldb::OptionDefinition
1553CommandObjectProcessHandle::CommandOptions::g_option_table[] =
1554{
1555{ LLDB_OPT_SET_1, false, "stop",   's', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the process should be stopped if the signal is received." },
1556{ LLDB_OPT_SET_1, false, "notify", 'n', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the debugger should notify the user if the signal is received." },
1557{ LLDB_OPT_SET_1, false, "pass",  'p', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." },
1558{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1559};
1560
1561//-------------------------------------------------------------------------
1562// CommandObjectMultiwordProcess
1563//-------------------------------------------------------------------------
1564
1565CommandObjectMultiwordProcess::CommandObjectMultiwordProcess (CommandInterpreter &interpreter) :
1566    CommandObjectMultiword (interpreter,
1567                            "process",
1568                            "A set of commands for operating on a process.",
1569                            "process <subcommand> [<subcommand-options>]")
1570{
1571    LoadSubCommand ("attach",      CommandObjectSP (new CommandObjectProcessAttach (interpreter)));
1572    LoadSubCommand ("launch",      CommandObjectSP (new CommandObjectProcessLaunch (interpreter)));
1573    LoadSubCommand ("continue",    CommandObjectSP (new CommandObjectProcessContinue (interpreter)));
1574    LoadSubCommand ("detach",      CommandObjectSP (new CommandObjectProcessDetach (interpreter)));
1575    LoadSubCommand ("load",        CommandObjectSP (new CommandObjectProcessLoad (interpreter)));
1576    LoadSubCommand ("unload",      CommandObjectSP (new CommandObjectProcessUnload (interpreter)));
1577    LoadSubCommand ("signal",      CommandObjectSP (new CommandObjectProcessSignal (interpreter)));
1578    LoadSubCommand ("handle",      CommandObjectSP (new CommandObjectProcessHandle (interpreter)));
1579    LoadSubCommand ("status",      CommandObjectSP (new CommandObjectProcessStatus (interpreter)));
1580    LoadSubCommand ("interrupt",   CommandObjectSP (new CommandObjectProcessInterrupt (interpreter)));
1581    LoadSubCommand ("kill",        CommandObjectSP (new CommandObjectProcessKill (interpreter)));
1582}
1583
1584CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess ()
1585{
1586}
1587
1588