130fdc8d8SChris Lattner //===-- CommandObjectProcess.cpp --------------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
1030fdc8d8SChris Lattner #include "CommandObjectProcess.h"
1130fdc8d8SChris Lattner 
1230fdc8d8SChris Lattner // C Includes
1330fdc8d8SChris Lattner // C++ Includes
1430fdc8d8SChris Lattner // Other libraries and framework includes
1530fdc8d8SChris Lattner // Project includes
1640af72e1SJim Ingham #include "lldb/Interpreter/Args.h"
1740af72e1SJim Ingham #include "lldb/Interpreter/Options.h"
1830fdc8d8SChris Lattner #include "lldb/Core/State.h"
1930fdc8d8SChris Lattner #include "lldb/Interpreter/CommandInterpreter.h"
2030fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h"
214b9bea87SJim Ingham #include "./CommandObjectThread.h"
2230fdc8d8SChris Lattner #include "lldb/Target/Process.h"
2330fdc8d8SChris Lattner #include "lldb/Target/Target.h"
2430fdc8d8SChris Lattner #include "lldb/Target/Thread.h"
2530fdc8d8SChris Lattner 
2630fdc8d8SChris Lattner using namespace lldb;
2730fdc8d8SChris Lattner using namespace lldb_private;
2830fdc8d8SChris Lattner 
2930fdc8d8SChris Lattner //-------------------------------------------------------------------------
3030fdc8d8SChris Lattner // CommandObjectProcessLaunch
3130fdc8d8SChris Lattner //-------------------------------------------------------------------------
3230fdc8d8SChris Lattner 
3330fdc8d8SChris Lattner class CommandObjectProcessLaunch : public CommandObject
3430fdc8d8SChris Lattner {
3530fdc8d8SChris Lattner public:
3630fdc8d8SChris Lattner 
3730fdc8d8SChris Lattner     class CommandOptions : public Options
3830fdc8d8SChris Lattner     {
3930fdc8d8SChris Lattner     public:
4030fdc8d8SChris Lattner 
4130fdc8d8SChris Lattner         CommandOptions () :
4230fdc8d8SChris Lattner             Options()
4330fdc8d8SChris Lattner         {
4430fdc8d8SChris Lattner             // Keep default values of all options in one place: ResetOptionValues ()
4530fdc8d8SChris Lattner             ResetOptionValues ();
4630fdc8d8SChris Lattner         }
4730fdc8d8SChris Lattner 
4830fdc8d8SChris Lattner         ~CommandOptions ()
4930fdc8d8SChris Lattner         {
5030fdc8d8SChris Lattner         }
5130fdc8d8SChris Lattner 
5230fdc8d8SChris Lattner         Error
5330fdc8d8SChris Lattner         SetOptionValue (int option_idx, const char *option_arg)
5430fdc8d8SChris Lattner         {
5530fdc8d8SChris Lattner             Error error;
5630fdc8d8SChris Lattner             char short_option = (char) m_getopt_table[option_idx].val;
5730fdc8d8SChris Lattner 
5830fdc8d8SChris Lattner             switch (short_option)
5930fdc8d8SChris Lattner             {
6030fdc8d8SChris Lattner                 case 's':   stop_at_entry = true;       break;
6130fdc8d8SChris Lattner                 case 'e':   stderr_path = option_arg;   break;
6230fdc8d8SChris Lattner                 case 'i':   stdin_path  = option_arg;   break;
6330fdc8d8SChris Lattner                 case 'o':   stdout_path = option_arg;   break;
6430fdc8d8SChris Lattner                 case 'p':   plugin_name = option_arg;   break;
65*f8da8631SCaroline Tice                 case 'n':   no_stdio = true;            break;
66913c4fa1SGreg Clayton                 case 't':
67913c4fa1SGreg Clayton                     if (option_arg && option_arg[0])
68913c4fa1SGreg Clayton                         tty_name.assign (option_arg);
69913c4fa1SGreg Clayton                     in_new_tty = true;
70913c4fa1SGreg Clayton                     break;
7130fdc8d8SChris Lattner                 default:
7230fdc8d8SChris Lattner                     error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
7330fdc8d8SChris Lattner                     break;
7430fdc8d8SChris Lattner 
7530fdc8d8SChris Lattner             }
7630fdc8d8SChris Lattner             return error;
7730fdc8d8SChris Lattner         }
7830fdc8d8SChris Lattner 
7930fdc8d8SChris Lattner         void
8030fdc8d8SChris Lattner         ResetOptionValues ()
8130fdc8d8SChris Lattner         {
8230fdc8d8SChris Lattner             Options::ResetOptionValues();
8330fdc8d8SChris Lattner             stop_at_entry = false;
8419388cfcSGreg Clayton             in_new_tty = false;
85913c4fa1SGreg Clayton             tty_name.clear();
8630fdc8d8SChris Lattner             stdin_path.clear();
8730fdc8d8SChris Lattner             stdout_path.clear();
8830fdc8d8SChris Lattner             stderr_path.clear();
8930fdc8d8SChris Lattner             plugin_name.clear();
90*f8da8631SCaroline Tice             no_stdio = false;
9130fdc8d8SChris Lattner         }
9230fdc8d8SChris Lattner 
9330fdc8d8SChris Lattner         const lldb::OptionDefinition*
9430fdc8d8SChris Lattner         GetDefinitions ()
9530fdc8d8SChris Lattner         {
9630fdc8d8SChris Lattner             return g_option_table;
9730fdc8d8SChris Lattner         }
9830fdc8d8SChris Lattner 
9930fdc8d8SChris Lattner         // Options table: Required for subclasses of Options.
10030fdc8d8SChris Lattner 
10130fdc8d8SChris Lattner         static lldb::OptionDefinition g_option_table[];
10230fdc8d8SChris Lattner 
10330fdc8d8SChris Lattner         // Instance variables to hold the values for command options.
10430fdc8d8SChris Lattner 
10530fdc8d8SChris Lattner         bool stop_at_entry;
10619388cfcSGreg Clayton         bool in_new_tty;
107*f8da8631SCaroline Tice         bool no_stdio;
108913c4fa1SGreg Clayton         std::string tty_name;
10930fdc8d8SChris Lattner         std::string stderr_path;
11030fdc8d8SChris Lattner         std::string stdin_path;
11130fdc8d8SChris Lattner         std::string stdout_path;
11230fdc8d8SChris Lattner         std::string plugin_name;
11330fdc8d8SChris Lattner 
11430fdc8d8SChris Lattner     };
11530fdc8d8SChris Lattner 
116a7015092SGreg Clayton     CommandObjectProcessLaunch (CommandInterpreter &interpreter) :
117a7015092SGreg Clayton         CommandObject (interpreter,
118a7015092SGreg Clayton                        "process launch",
119e3d26315SCaroline Tice                        "Launch the executable in the debugger.",
120405fe67fSCaroline Tice                        NULL)
12130fdc8d8SChris Lattner     {
122405fe67fSCaroline Tice         CommandArgumentEntry arg;
123405fe67fSCaroline Tice         CommandArgumentData run_args_arg;
124405fe67fSCaroline Tice 
125405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
126405fe67fSCaroline Tice         run_args_arg.arg_type = eArgTypeRunArgs;
127405fe67fSCaroline Tice         run_args_arg.arg_repetition = eArgRepeatOptional;
128405fe67fSCaroline Tice 
129405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
130405fe67fSCaroline Tice         arg.push_back (run_args_arg);
131405fe67fSCaroline Tice 
132405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
133405fe67fSCaroline Tice         m_arguments.push_back (arg);
13430fdc8d8SChris Lattner     }
13530fdc8d8SChris Lattner 
13630fdc8d8SChris Lattner 
13730fdc8d8SChris Lattner     ~CommandObjectProcessLaunch ()
13830fdc8d8SChris Lattner     {
13930fdc8d8SChris Lattner     }
14030fdc8d8SChris Lattner 
14130fdc8d8SChris Lattner     Options *
14230fdc8d8SChris Lattner     GetOptions ()
14330fdc8d8SChris Lattner     {
14430fdc8d8SChris Lattner         return &m_options;
14530fdc8d8SChris Lattner     }
14630fdc8d8SChris Lattner 
14730fdc8d8SChris Lattner     bool
14805faeb71SGreg Clayton     Execute (Args& launch_args, CommandReturnObject &result)
14930fdc8d8SChris Lattner     {
150a7015092SGreg Clayton         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
15130fdc8d8SChris Lattner 
15230fdc8d8SChris Lattner         if (target == NULL)
15330fdc8d8SChris Lattner         {
15430fdc8d8SChris Lattner             result.AppendError ("invalid target, set executable file using 'file' command");
15530fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
15630fdc8d8SChris Lattner             return false;
15730fdc8d8SChris Lattner         }
15830fdc8d8SChris Lattner 
15930fdc8d8SChris Lattner         // If our listener is NULL, users aren't allows to launch
16030fdc8d8SChris Lattner         char filename[PATH_MAX];
16119388cfcSGreg Clayton         const Module *exe_module = target->GetExecutableModule().get();
16230fdc8d8SChris Lattner         exe_module->GetFileSpec().GetPath(filename, sizeof(filename));
16330fdc8d8SChris Lattner 
164a7015092SGreg Clayton         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
165a7015092SGreg Clayton         if (process && process->IsAlive())
16630fdc8d8SChris Lattner         {
16730fdc8d8SChris Lattner             result.AppendErrorWithFormat ("Process %u is currently being debugged, kill the process before running again.\n",
16830fdc8d8SChris Lattner                                           process->GetID());
16930fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
17030fdc8d8SChris Lattner             return false;
17130fdc8d8SChris Lattner         }
17230fdc8d8SChris Lattner 
17330fdc8d8SChris Lattner         const char *plugin_name;
17430fdc8d8SChris Lattner         if (!m_options.plugin_name.empty())
17530fdc8d8SChris Lattner             plugin_name = m_options.plugin_name.c_str();
17630fdc8d8SChris Lattner         else
17730fdc8d8SChris Lattner             plugin_name = NULL;
17830fdc8d8SChris Lattner 
179a7015092SGreg Clayton         process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name).get();
18030fdc8d8SChris Lattner 
181a7015092SGreg Clayton         if (process == NULL)
1823df9a8dfSCaroline Tice         {
18343a8c39bSCaroline Tice             result.AppendErrorWithFormat ("Failed to find a process plugin for executable.\n");
184a7015092SGreg Clayton             result.SetStatus (eReturnStatusFailed);
185a7015092SGreg Clayton             return false;
1863df9a8dfSCaroline Tice         }
1873df9a8dfSCaroline Tice 
188a7015092SGreg Clayton         // If no launch args were given on the command line, then use any that
189a7015092SGreg Clayton         // might have been set using the "run-args" set variable.
19030fdc8d8SChris Lattner         if (launch_args.GetArgumentCount() == 0)
19130fdc8d8SChris Lattner         {
192a7015092SGreg Clayton             if (process->GetRunArguments().GetArgumentCount() > 0)
193a7015092SGreg Clayton                 launch_args = process->GetRunArguments();
19430fdc8d8SChris Lattner         }
19530fdc8d8SChris Lattner 
19619388cfcSGreg Clayton         if (m_options.in_new_tty)
19719388cfcSGreg Clayton         {
19819388cfcSGreg Clayton             char exec_file_path[PATH_MAX];
19919388cfcSGreg Clayton             if (exe_module->GetFileSpec().GetPath(exec_file_path, sizeof(exec_file_path)))
20019388cfcSGreg Clayton             {
20119388cfcSGreg Clayton                 launch_args.InsertArgumentAtIndex(0, exec_file_path);
20219388cfcSGreg Clayton             }
20319388cfcSGreg Clayton             else
20419388cfcSGreg Clayton             {
20519388cfcSGreg Clayton                 result.AppendError("invalid executable");
20619388cfcSGreg Clayton                 result.SetStatus (eReturnStatusFailed);
20719388cfcSGreg Clayton                 return false;
20819388cfcSGreg Clayton             }
20919388cfcSGreg Clayton         }
21019388cfcSGreg Clayton 
211a7015092SGreg Clayton         Args environment;
21230fdc8d8SChris Lattner 
213a7015092SGreg Clayton         process->GetEnvironmentAsArgs (environment);
214a7015092SGreg Clayton 
215a7015092SGreg Clayton         uint32_t launch_flags = eLaunchFlagNone;
216a7015092SGreg Clayton 
217a7015092SGreg Clayton         if (process->GetDisableASLR())
218a7015092SGreg Clayton             launch_flags |= eLaunchFlagDisableASLR;
219a7015092SGreg Clayton 
220*f8da8631SCaroline Tice         if (m_options.no_stdio)
221*f8da8631SCaroline Tice             launch_flags |= eLaunchFlagDisableSTDIO;
222*f8da8631SCaroline Tice         else if (!m_options.in_new_tty
223*f8da8631SCaroline Tice                  && m_options.stdin_path.empty()
224*f8da8631SCaroline Tice                  && m_options.stdout_path.empty()
225*f8da8631SCaroline Tice                  && m_options.stderr_path.empty())
226*f8da8631SCaroline Tice         {
227*f8da8631SCaroline Tice             // Only use the settings value if the user hasn't specified any options that would override it.
228*f8da8631SCaroline Tice             if (process->GetDisableSTDIO())
229*f8da8631SCaroline Tice                 launch_flags |= eLaunchFlagDisableSTDIO;
230*f8da8631SCaroline Tice         }
231*f8da8631SCaroline Tice 
23219388cfcSGreg Clayton         const char **inferior_argv = launch_args.GetArgumentCount() ? launch_args.GetConstArgumentVector() : NULL;
23319388cfcSGreg Clayton         const char **inferior_envp = environment.GetArgumentCount() ? environment.GetConstArgumentVector() : NULL;
23430fdc8d8SChris Lattner 
23519388cfcSGreg Clayton         Error error;
23619388cfcSGreg Clayton 
23719388cfcSGreg Clayton         if (m_options.in_new_tty)
23819388cfcSGreg Clayton         {
23919388cfcSGreg Clayton 
240913c4fa1SGreg Clayton             lldb::pid_t pid = Host::LaunchInNewTerminal (m_options.tty_name.c_str(),
241913c4fa1SGreg Clayton                                                          inferior_argv,
24219388cfcSGreg Clayton                                                          inferior_envp,
24319388cfcSGreg Clayton                                                          &exe_module->GetArchitecture(),
24419388cfcSGreg Clayton                                                          true,
24519388cfcSGreg Clayton                                                          process->GetDisableASLR());
24619388cfcSGreg Clayton 
2473fcbed6bSGreg Clayton             if (pid != LLDB_INVALID_PROCESS_ID)
2483fcbed6bSGreg Clayton                 error = process->Attach (pid);
24919388cfcSGreg Clayton         }
25019388cfcSGreg Clayton         else
25119388cfcSGreg Clayton         {
25230fdc8d8SChris Lattner             const char * stdin_path = NULL;
25330fdc8d8SChris Lattner             const char * stdout_path = NULL;
25430fdc8d8SChris Lattner             const char * stderr_path = NULL;
25530fdc8d8SChris Lattner 
256a7015092SGreg Clayton             // Were any standard input/output/error paths given on the command line?
257a7015092SGreg Clayton             if (m_options.stdin_path.empty() &&
25830fdc8d8SChris Lattner                 m_options.stdout_path.empty() &&
259a7015092SGreg Clayton                 m_options.stderr_path.empty())
26030fdc8d8SChris Lattner             {
261a7015092SGreg Clayton                 // No standard file handles were given on the command line, check
262a7015092SGreg Clayton                 // with the process object in case they were give using "set settings"
263a7015092SGreg Clayton                 stdin_path = process->GetStandardInputPath();
264a7015092SGreg Clayton                 stdout_path = process->GetStandardOutputPath();
265a7015092SGreg Clayton                 stderr_path = process->GetStandardErrorPath();
266a7015092SGreg Clayton             }
267a7015092SGreg Clayton             else
268a7015092SGreg Clayton             {
269a7015092SGreg Clayton                 stdin_path = m_options.stdin_path.empty()  ? NULL : m_options.stdin_path.c_str();
270a7015092SGreg Clayton                 stdout_path = m_options.stdout_path.empty() ? NULL : m_options.stdout_path.c_str();
271a7015092SGreg Clayton                 stderr_path = m_options.stderr_path.empty() ? NULL : m_options.stderr_path.c_str();
27230fdc8d8SChris Lattner             }
27330fdc8d8SChris Lattner 
274a7015092SGreg Clayton             if (stdin_path == NULL)
275a7015092SGreg Clayton                 stdin_path = "/dev/null";
276a7015092SGreg Clayton             if (stdout_path == NULL)
277a7015092SGreg Clayton                 stdout_path = "/dev/null";
278a7015092SGreg Clayton             if (stderr_path == NULL)
279a7015092SGreg Clayton                 stderr_path = "/dev/null";
280a7015092SGreg Clayton 
28119388cfcSGreg Clayton             error = process->Launch (inferior_argv,
28219388cfcSGreg Clayton                                      inferior_envp,
283f681b94fSGreg Clayton                                      launch_flags,
28430fdc8d8SChris Lattner                                      stdin_path,
28530fdc8d8SChris Lattner                                      stdout_path,
28619388cfcSGreg Clayton                                      stderr_path);
28719388cfcSGreg Clayton         }
28830fdc8d8SChris Lattner 
28930fdc8d8SChris Lattner         if (error.Success())
29030fdc8d8SChris Lattner         {
29119388cfcSGreg Clayton             const char *archname = exe_module->GetArchitecture().AsCString();
29219388cfcSGreg Clayton 
29319388cfcSGreg Clayton             result.AppendMessageWithFormat ("Process %i launched: '%s' (%s)\n", process->GetID(), filename, archname);
29405faeb71SGreg Clayton             result.SetDidChangeProcessState (true);
29530fdc8d8SChris Lattner             if (m_options.stop_at_entry == false)
29630fdc8d8SChris Lattner             {
29705faeb71SGreg Clayton                 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
29830fdc8d8SChris Lattner                 StateType state = process->WaitForProcessToStop (NULL);
29930fdc8d8SChris Lattner 
30030fdc8d8SChris Lattner                 if (state == eStateStopped)
30130fdc8d8SChris Lattner                 {
30205faeb71SGreg Clayton                     error = process->Resume();
30305faeb71SGreg Clayton                     if (error.Success())
30405faeb71SGreg Clayton                     {
30505faeb71SGreg Clayton                         bool synchronous_execution = m_interpreter.GetSynchronous ();
30630fdc8d8SChris Lattner                         if (synchronous_execution)
30730fdc8d8SChris Lattner                         {
30805faeb71SGreg Clayton                             state = process->WaitForProcessToStop (NULL);
30930fdc8d8SChris Lattner                             result.SetDidChangeProcessState (true);
31005faeb71SGreg Clayton                             result.SetStatus (eReturnStatusSuccessFinishResult);
31105faeb71SGreg Clayton                         }
31205faeb71SGreg Clayton                         else
31305faeb71SGreg Clayton                         {
31405faeb71SGreg Clayton                             result.SetStatus (eReturnStatusSuccessContinuingNoResult);
31505faeb71SGreg Clayton                         }
31605faeb71SGreg Clayton                     }
31730fdc8d8SChris Lattner                 }
31830fdc8d8SChris Lattner             }
31930fdc8d8SChris Lattner         }
32030fdc8d8SChris Lattner 
32130fdc8d8SChris Lattner         return result.Succeeded();
32230fdc8d8SChris Lattner     }
32330fdc8d8SChris Lattner 
324ebc09c36SJim Ingham     virtual const char *GetRepeatCommand (Args &current_command_args, uint32_t index)
325ebc09c36SJim Ingham     {
326ebc09c36SJim Ingham         // No repeat for "process launch"...
327ebc09c36SJim Ingham         return "";
328ebc09c36SJim Ingham     }
329ebc09c36SJim Ingham 
33030fdc8d8SChris Lattner protected:
33130fdc8d8SChris Lattner 
33230fdc8d8SChris Lattner     CommandOptions m_options;
33330fdc8d8SChris Lattner };
33430fdc8d8SChris Lattner 
33530fdc8d8SChris Lattner 
33619388cfcSGreg Clayton #define SET1 LLDB_OPT_SET_1
33719388cfcSGreg Clayton #define SET2 LLDB_OPT_SET_2
338*f8da8631SCaroline Tice #define SET3 LLDB_OPT_SET_3
33919388cfcSGreg Clayton 
34030fdc8d8SChris Lattner lldb::OptionDefinition
34130fdc8d8SChris Lattner CommandObjectProcessLaunch::CommandOptions::g_option_table[] =
34230fdc8d8SChris Lattner {
343*f8da8631SCaroline Tice { SET1 | SET2 | SET3, false, "stop-at-entry", 's', no_argument,       NULL, 0, eArgTypeNone,    "Stop at the entry point of the program when launching a process."},
34419388cfcSGreg Clayton { SET1              , false, "stdin",         'i', required_argument, NULL, 0, eArgTypePath,    "Redirect stdin for the process to <path>."},
34519388cfcSGreg Clayton { SET1              , false, "stdout",        'o', required_argument, NULL, 0, eArgTypePath,    "Redirect stdout for the process to <path>."},
34619388cfcSGreg Clayton { SET1              , false, "stderr",        'e', required_argument, NULL, 0, eArgTypePath,    "Redirect stderr for the process to <path>."},
347*f8da8631SCaroline Tice { SET1 | SET2 | SET3, false, "plugin",        'p', required_argument, NULL, 0, eArgTypePlugin,  "Name of the process plugin you want to use."},
348913c4fa1SGreg Clayton {        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."},
349*f8da8631SCaroline Tice {               SET3, false, "no-stdio",      'n', no_argument,       NULL, 0, eArgTypeNone,    "Do not set up for terminal I/O to go to running process."},
350deaab222SCaroline Tice { 0,                  false, NULL,             0,  0,                 NULL, 0, eArgTypeNone,    NULL }
35130fdc8d8SChris Lattner };
35230fdc8d8SChris Lattner 
35319388cfcSGreg Clayton #undef SET1
35419388cfcSGreg Clayton #undef SET2
355*f8da8631SCaroline Tice #undef SET3
35630fdc8d8SChris Lattner 
35730fdc8d8SChris Lattner //-------------------------------------------------------------------------
35830fdc8d8SChris Lattner // CommandObjectProcessAttach
35930fdc8d8SChris Lattner //-------------------------------------------------------------------------
36030fdc8d8SChris Lattner 
36130fdc8d8SChris Lattner class CommandObjectProcessAttach : public CommandObject
36230fdc8d8SChris Lattner {
36330fdc8d8SChris Lattner public:
36430fdc8d8SChris Lattner 
36530fdc8d8SChris Lattner     class CommandOptions : public Options
36630fdc8d8SChris Lattner     {
36730fdc8d8SChris Lattner     public:
36830fdc8d8SChris Lattner 
36930fdc8d8SChris Lattner         CommandOptions () :
37030fdc8d8SChris Lattner             Options()
37130fdc8d8SChris Lattner         {
37230fdc8d8SChris Lattner             // Keep default values of all options in one place: ResetOptionValues ()
37330fdc8d8SChris Lattner             ResetOptionValues ();
37430fdc8d8SChris Lattner         }
37530fdc8d8SChris Lattner 
37630fdc8d8SChris Lattner         ~CommandOptions ()
37730fdc8d8SChris Lattner         {
37830fdc8d8SChris Lattner         }
37930fdc8d8SChris Lattner 
38030fdc8d8SChris Lattner         Error
38130fdc8d8SChris Lattner         SetOptionValue (int option_idx, const char *option_arg)
38230fdc8d8SChris Lattner         {
38330fdc8d8SChris Lattner             Error error;
38430fdc8d8SChris Lattner             char short_option = (char) m_getopt_table[option_idx].val;
38530fdc8d8SChris Lattner             bool success = false;
38630fdc8d8SChris Lattner             switch (short_option)
38730fdc8d8SChris Lattner             {
38830fdc8d8SChris Lattner                 case 'p':
38930fdc8d8SChris Lattner                     pid = Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success);
39030fdc8d8SChris Lattner                     if (!success || pid == LLDB_INVALID_PROCESS_ID)
39130fdc8d8SChris Lattner                     {
39230fdc8d8SChris Lattner                         error.SetErrorStringWithFormat("Invalid process ID '%s'.\n", option_arg);
39330fdc8d8SChris Lattner                     }
39430fdc8d8SChris Lattner                     break;
39530fdc8d8SChris Lattner 
39630fdc8d8SChris Lattner                 case 'P':
39730fdc8d8SChris Lattner                     plugin_name = option_arg;
39830fdc8d8SChris Lattner                     break;
39930fdc8d8SChris Lattner 
40030fdc8d8SChris Lattner                 case 'n':
40130fdc8d8SChris Lattner                     name.assign(option_arg);
40230fdc8d8SChris Lattner                     break;
40330fdc8d8SChris Lattner 
40430fdc8d8SChris Lattner                 case 'w':
40530fdc8d8SChris Lattner                     waitfor = true;
40630fdc8d8SChris Lattner                     break;
40730fdc8d8SChris Lattner 
40830fdc8d8SChris Lattner                 default:
40930fdc8d8SChris Lattner                     error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
41030fdc8d8SChris Lattner                     break;
41130fdc8d8SChris Lattner             }
41230fdc8d8SChris Lattner             return error;
41330fdc8d8SChris Lattner         }
41430fdc8d8SChris Lattner 
41530fdc8d8SChris Lattner         void
41630fdc8d8SChris Lattner         ResetOptionValues ()
41730fdc8d8SChris Lattner         {
41830fdc8d8SChris Lattner             Options::ResetOptionValues();
41930fdc8d8SChris Lattner             pid = LLDB_INVALID_PROCESS_ID;
42030fdc8d8SChris Lattner             name.clear();
42130fdc8d8SChris Lattner             waitfor = false;
42230fdc8d8SChris Lattner         }
42330fdc8d8SChris Lattner 
42430fdc8d8SChris Lattner         const lldb::OptionDefinition*
42530fdc8d8SChris Lattner         GetDefinitions ()
42630fdc8d8SChris Lattner         {
42730fdc8d8SChris Lattner             return g_option_table;
42830fdc8d8SChris Lattner         }
42930fdc8d8SChris Lattner 
4305aee162fSJim Ingham         virtual bool
431a7015092SGreg Clayton         HandleOptionArgumentCompletion (CommandInterpreter &interpeter,
4325aee162fSJim Ingham                                         Args &input,
4335aee162fSJim Ingham                                         int cursor_index,
4345aee162fSJim Ingham                                         int char_pos,
4355aee162fSJim Ingham                                         OptionElementVector &opt_element_vector,
4365aee162fSJim Ingham                                         int opt_element_index,
4375aee162fSJim Ingham                                         int match_start_point,
4385aee162fSJim Ingham                                         int max_return_elements,
4395aee162fSJim Ingham                                         bool &word_complete,
4405aee162fSJim Ingham                                         StringList &matches)
4415aee162fSJim Ingham         {
4425aee162fSJim Ingham             int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
4435aee162fSJim Ingham             int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
4445aee162fSJim Ingham 
4455aee162fSJim Ingham             // We are only completing the name option for now...
4465aee162fSJim Ingham 
4475aee162fSJim Ingham             const lldb::OptionDefinition *opt_defs = GetDefinitions();
4485aee162fSJim Ingham             if (opt_defs[opt_defs_index].short_option == 'n')
4495aee162fSJim Ingham             {
4505aee162fSJim Ingham                 // Are we in the name?
4515aee162fSJim Ingham 
4525aee162fSJim Ingham                 // Look to see if there is a -P argument provided, and if so use that plugin, otherwise
4535aee162fSJim Ingham                 // use the default plugin.
454a7015092SGreg Clayton                 Process *process = interpeter.GetDebugger().GetExecutionContext().process;
4555aee162fSJim Ingham                 bool need_to_delete_process = false;
4565aee162fSJim Ingham 
4575aee162fSJim Ingham                 const char *partial_name = NULL;
4585aee162fSJim Ingham                 partial_name = input.GetArgumentAtIndex(opt_arg_pos);
4595aee162fSJim Ingham 
4605aee162fSJim Ingham                 if (process && process->IsAlive())
4615aee162fSJim Ingham                     return true;
4625aee162fSJim Ingham 
463a7015092SGreg Clayton                 Target *target = interpeter.GetDebugger().GetSelectedTarget().get();
4645aee162fSJim Ingham                 if (target == NULL)
4655aee162fSJim Ingham                 {
4665aee162fSJim Ingham                     // No target has been set yet, for now do host completion.  Otherwise I don't know how we would
4675aee162fSJim Ingham                     // figure out what the right target to use is...
4685aee162fSJim Ingham                     std::vector<lldb::pid_t> pids;
4695aee162fSJim Ingham                     Host::ListProcessesMatchingName (partial_name, matches, pids);
4705aee162fSJim Ingham                     return true;
4715aee162fSJim Ingham                 }
4725aee162fSJim Ingham                 if (!process)
4735aee162fSJim Ingham                 {
474a7015092SGreg Clayton                     process = target->CreateProcess (interpeter.GetDebugger().GetListener(), partial_name).get();
4755aee162fSJim Ingham                     need_to_delete_process = true;
4765aee162fSJim Ingham                 }
4775aee162fSJim Ingham 
4785aee162fSJim Ingham                 if (process)
4795aee162fSJim Ingham                 {
4805aee162fSJim Ingham                     matches.Clear();
4815aee162fSJim Ingham                     std::vector<lldb::pid_t> pids;
4825aee162fSJim Ingham                     process->ListProcessesMatchingName (NULL, matches, pids);
4835aee162fSJim Ingham                     if (need_to_delete_process)
4845aee162fSJim Ingham                         target->DeleteCurrentProcess();
4855aee162fSJim Ingham                     return true;
4865aee162fSJim Ingham                 }
4875aee162fSJim Ingham             }
4885aee162fSJim Ingham 
4895aee162fSJim Ingham             return false;
4905aee162fSJim Ingham         }
4915aee162fSJim Ingham 
49230fdc8d8SChris Lattner         // Options table: Required for subclasses of Options.
49330fdc8d8SChris Lattner 
49430fdc8d8SChris Lattner         static lldb::OptionDefinition g_option_table[];
49530fdc8d8SChris Lattner 
49630fdc8d8SChris Lattner         // Instance variables to hold the values for command options.
49730fdc8d8SChris Lattner 
49830fdc8d8SChris Lattner         lldb::pid_t pid;
49930fdc8d8SChris Lattner         std::string plugin_name;
50030fdc8d8SChris Lattner         std::string name;
50130fdc8d8SChris Lattner         bool waitfor;
50230fdc8d8SChris Lattner     };
50330fdc8d8SChris Lattner 
504a7015092SGreg Clayton     CommandObjectProcessAttach (CommandInterpreter &interpreter) :
505a7015092SGreg Clayton         CommandObject (interpreter,
506a7015092SGreg Clayton                        "process attach",
507e3d26315SCaroline Tice                        "Attach to a process.",
5085aee162fSJim Ingham                        "process attach <cmd-options>")
5095aee162fSJim Ingham     {
5105aee162fSJim Ingham     }
5115aee162fSJim Ingham 
5125aee162fSJim Ingham     ~CommandObjectProcessAttach ()
5135aee162fSJim Ingham     {
5145aee162fSJim Ingham     }
5155aee162fSJim Ingham 
5165aee162fSJim Ingham     bool
517a7015092SGreg Clayton     Execute (Args& command,
5185aee162fSJim Ingham              CommandReturnObject &result)
5195aee162fSJim Ingham     {
520a7015092SGreg Clayton         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
5215aee162fSJim Ingham 
522a7015092SGreg Clayton         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
5235aee162fSJim Ingham         if (process)
5245aee162fSJim Ingham         {
5255aee162fSJim Ingham             if (process->IsAlive())
5265aee162fSJim Ingham             {
5275aee162fSJim Ingham                 result.AppendErrorWithFormat ("Process %u is currently being debugged, kill the process before attaching.\n",
5285aee162fSJim Ingham                                               process->GetID());
5295aee162fSJim Ingham                 result.SetStatus (eReturnStatusFailed);
5305aee162fSJim Ingham                 return false;
5315aee162fSJim Ingham             }
5325aee162fSJim Ingham         }
5335aee162fSJim Ingham 
5345aee162fSJim Ingham         if (target == NULL)
5355aee162fSJim Ingham         {
5365aee162fSJim Ingham             // If there isn't a current target create one.
5375aee162fSJim Ingham             TargetSP new_target_sp;
5385aee162fSJim Ingham             FileSpec emptyFileSpec;
5395aee162fSJim Ingham             ArchSpec emptyArchSpec;
5405aee162fSJim Ingham             Error error;
5415aee162fSJim Ingham 
542a7015092SGreg Clayton             error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(),
5435aee162fSJim Ingham                                                                               emptyFileSpec,
5445aee162fSJim Ingham                                                                               emptyArchSpec,
5455aee162fSJim Ingham                                                                               NULL,
5465aee162fSJim Ingham                                                                               false,
5475aee162fSJim Ingham                                                                               new_target_sp);
5485aee162fSJim Ingham             target = new_target_sp.get();
5495aee162fSJim Ingham             if (target == NULL || error.Fail())
5505aee162fSJim Ingham             {
5515aee162fSJim Ingham                 result.AppendError(error.AsCString("Error creating empty target"));
5525aee162fSJim Ingham                 return false;
5535aee162fSJim Ingham             }
554a7015092SGreg Clayton             m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target);
5555aee162fSJim Ingham         }
5565aee162fSJim Ingham 
5575aee162fSJim Ingham         // Record the old executable module, we want to issue a warning if the process of attaching changed the
5585aee162fSJim Ingham         // current executable (like somebody said "file foo" then attached to a PID whose executable was bar.)
5595aee162fSJim Ingham 
5605aee162fSJim Ingham         ModuleSP old_exec_module_sp = target->GetExecutableModule();
5615aee162fSJim Ingham         ArchSpec old_arch_spec = target->GetArchitecture();
5625aee162fSJim Ingham 
5635aee162fSJim Ingham         if (command.GetArgumentCount())
5645aee162fSJim Ingham         {
5655aee162fSJim Ingham             result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: \n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
5665aee162fSJim Ingham             result.SetStatus (eReturnStatusFailed);
5675aee162fSJim Ingham         }
5685aee162fSJim Ingham         else
5695aee162fSJim Ingham         {
5705aee162fSJim Ingham             const char *plugin_name = NULL;
5715aee162fSJim Ingham 
5725aee162fSJim Ingham             if (!m_options.plugin_name.empty())
5735aee162fSJim Ingham                 plugin_name = m_options.plugin_name.c_str();
5745aee162fSJim Ingham 
575a7015092SGreg Clayton             process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name).get();
5765aee162fSJim Ingham 
5775aee162fSJim Ingham             if (process)
5785aee162fSJim Ingham             {
5795aee162fSJim Ingham                 Error error;
5805aee162fSJim Ingham                 int attach_pid = m_options.pid;
5815aee162fSJim Ingham 
5823a0b9cdfSJim Ingham                 const char *wait_name = NULL;
5833a0b9cdfSJim Ingham 
5845aee162fSJim Ingham                 if (m_options.name.empty())
5855aee162fSJim Ingham                 {
5863a0b9cdfSJim Ingham                     if (old_exec_module_sp)
5873a0b9cdfSJim Ingham                     {
5883a0b9cdfSJim Ingham                         wait_name = old_exec_module_sp->GetFileSpec().GetFilename().AsCString();
5893a0b9cdfSJim Ingham                     }
5905aee162fSJim Ingham                 }
5915aee162fSJim Ingham                 else
5925aee162fSJim Ingham                 {
5933a0b9cdfSJim Ingham                     wait_name = m_options.name.c_str();
5943a0b9cdfSJim Ingham                 }
5953a0b9cdfSJim Ingham 
5963a0b9cdfSJim Ingham                 // If we are waiting for a process with this name to show up, do that first.
5973a0b9cdfSJim Ingham                 if (m_options.waitfor)
5983a0b9cdfSJim Ingham                 {
5993a0b9cdfSJim Ingham 
6003a0b9cdfSJim Ingham                     if (wait_name == NULL)
6013a0b9cdfSJim Ingham                     {
6023a0b9cdfSJim Ingham                         result.AppendError("Invalid arguments: must have a file loaded or supply a process name with the waitfor option.\n");
6033a0b9cdfSJim Ingham                         result.SetStatus (eReturnStatusFailed);
6043a0b9cdfSJim Ingham                         return false;
6053a0b9cdfSJim Ingham                     }
6063a0b9cdfSJim Ingham 
607a7015092SGreg Clayton                     m_interpreter.GetDebugger().GetOutputStream().Printf("Waiting to attach to a process named \"%s\".\n", wait_name);
6083a0b9cdfSJim Ingham                     error = process->Attach (wait_name, m_options.waitfor);
6095aee162fSJim Ingham                     if (error.Success())
6105aee162fSJim Ingham                     {
6115aee162fSJim Ingham                         result.SetStatus (eReturnStatusSuccessContinuingNoResult);
6125aee162fSJim Ingham                     }
6135aee162fSJim Ingham                     else
6145aee162fSJim Ingham                     {
6155aee162fSJim Ingham                         result.AppendErrorWithFormat ("Waiting for a process to launch named '%s': %s\n",
6163a0b9cdfSJim Ingham                                                          wait_name,
6175aee162fSJim Ingham                                                          error.AsCString());
6185aee162fSJim Ingham                         result.SetStatus (eReturnStatusFailed);
6195aee162fSJim Ingham                         return false;
6205aee162fSJim Ingham                     }
6215aee162fSJim Ingham                 }
6225aee162fSJim Ingham                 else
6235aee162fSJim Ingham                 {
6245aee162fSJim Ingham                     // If the process was specified by name look it up, so we can warn if there are multiple
6255aee162fSJim Ingham                     // processes with this pid.
6265aee162fSJim Ingham 
6273a0b9cdfSJim Ingham                     if (attach_pid == LLDB_INVALID_PROCESS_ID && wait_name != NULL)
6285aee162fSJim Ingham                     {
6295aee162fSJim Ingham                         std::vector<lldb::pid_t> pids;
6305aee162fSJim Ingham                         StringList matches;
6315aee162fSJim Ingham 
6323a0b9cdfSJim Ingham                         process->ListProcessesMatchingName(wait_name, matches, pids);
6335aee162fSJim Ingham                         if (matches.GetSize() > 1)
6345aee162fSJim Ingham                         {
6353a0b9cdfSJim Ingham                             result.AppendErrorWithFormat("More than one process named %s\n", wait_name);
6365aee162fSJim Ingham                             result.SetStatus (eReturnStatusFailed);
6375aee162fSJim Ingham                             return false;
6385aee162fSJim Ingham                         }
6395aee162fSJim Ingham                         else if (matches.GetSize() == 0)
6405aee162fSJim Ingham                         {
6413a0b9cdfSJim Ingham                             result.AppendErrorWithFormat("Could not find a process named %s\n", wait_name);
6425aee162fSJim Ingham                             result.SetStatus (eReturnStatusFailed);
6435aee162fSJim Ingham                             return false;
6445aee162fSJim Ingham                         }
6455aee162fSJim Ingham                         else
6465aee162fSJim Ingham                         {
6475aee162fSJim Ingham                             attach_pid = pids[0];
6485aee162fSJim Ingham                         }
6495aee162fSJim Ingham 
6505aee162fSJim Ingham                     }
6515aee162fSJim Ingham 
6525aee162fSJim Ingham                     if (attach_pid != LLDB_INVALID_PROCESS_ID)
6535aee162fSJim Ingham                     {
6545aee162fSJim Ingham                         error = process->Attach (attach_pid);
6555aee162fSJim Ingham                         if (error.Success())
6565aee162fSJim Ingham                         {
6575aee162fSJim Ingham                             result.SetStatus (eReturnStatusSuccessContinuingNoResult);
6585aee162fSJim Ingham                         }
6595aee162fSJim Ingham                         else
6605aee162fSJim Ingham                         {
6615aee162fSJim Ingham                             result.AppendErrorWithFormat ("Attaching to process %i failed: %s.\n",
6625aee162fSJim Ingham                                                          attach_pid,
6635aee162fSJim Ingham                                                          error.AsCString());
6645aee162fSJim Ingham                             result.SetStatus (eReturnStatusFailed);
6655aee162fSJim Ingham                         }
6665aee162fSJim Ingham                     }
6675aee162fSJim Ingham                     else
6685aee162fSJim Ingham                     {
6695aee162fSJim Ingham                         result.AppendErrorWithFormat ("No PID specified for attach\n",
6705aee162fSJim Ingham                                                          attach_pid,
6715aee162fSJim Ingham                                                          error.AsCString());
6725aee162fSJim Ingham                         result.SetStatus (eReturnStatusFailed);
6735aee162fSJim Ingham 
6745aee162fSJim Ingham                     }
6755aee162fSJim Ingham                 }
6765aee162fSJim Ingham             }
6775aee162fSJim Ingham         }
6785aee162fSJim Ingham 
6795aee162fSJim Ingham         if (result.Succeeded())
6805aee162fSJim Ingham         {
6815aee162fSJim Ingham             // Okay, we're done.  Last step is to warn if the executable module has changed:
6825aee162fSJim Ingham             if (!old_exec_module_sp)
6835aee162fSJim Ingham             {
6845aee162fSJim Ingham                 char new_path[PATH_MAX + 1];
6855aee162fSJim Ingham                 target->GetExecutableModule()->GetFileSpec().GetPath(new_path, PATH_MAX);
6865aee162fSJim Ingham 
6875aee162fSJim Ingham                 result.AppendMessageWithFormat("Executable module set to \"%s\".\n",
6885aee162fSJim Ingham                     new_path);
6895aee162fSJim Ingham             }
6905aee162fSJim Ingham             else if (old_exec_module_sp->GetFileSpec() != target->GetExecutableModule()->GetFileSpec())
6915aee162fSJim Ingham             {
6925aee162fSJim Ingham                 char old_path[PATH_MAX + 1];
6935aee162fSJim Ingham                 char new_path[PATH_MAX + 1];
6945aee162fSJim Ingham 
6955aee162fSJim Ingham                 old_exec_module_sp->GetFileSpec().GetPath(old_path, PATH_MAX);
6965aee162fSJim Ingham                 target->GetExecutableModule()->GetFileSpec().GetPath (new_path, PATH_MAX);
6975aee162fSJim Ingham 
6985aee162fSJim Ingham                 result.AppendWarningWithFormat("Executable module changed from \"%s\" to \"%s\".\n",
6995aee162fSJim Ingham                                                     old_path, new_path);
7005aee162fSJim Ingham             }
7015aee162fSJim Ingham 
7025aee162fSJim Ingham             if (!old_arch_spec.IsValid())
7035aee162fSJim Ingham             {
7045aee162fSJim Ingham                 result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().AsCString());
7055aee162fSJim Ingham             }
7065aee162fSJim Ingham             else if (old_arch_spec != target->GetArchitecture())
7075aee162fSJim Ingham             {
7085aee162fSJim Ingham                 result.AppendWarningWithFormat("Architecture changed from %s to %s.\n",
7095aee162fSJim Ingham                                                 old_arch_spec.AsCString(), target->GetArchitecture().AsCString());
7105aee162fSJim Ingham             }
7115aee162fSJim Ingham         }
7125aee162fSJim Ingham         return result.Succeeded();
7135aee162fSJim Ingham     }
7145aee162fSJim Ingham 
7155aee162fSJim Ingham     Options *
7165aee162fSJim Ingham     GetOptions ()
7175aee162fSJim Ingham     {
7185aee162fSJim Ingham         return &m_options;
7195aee162fSJim Ingham     }
7205aee162fSJim Ingham 
72130fdc8d8SChris Lattner protected:
72230fdc8d8SChris Lattner 
72330fdc8d8SChris Lattner     CommandOptions m_options;
72430fdc8d8SChris Lattner };
72530fdc8d8SChris Lattner 
72630fdc8d8SChris Lattner 
72730fdc8d8SChris Lattner lldb::OptionDefinition
72830fdc8d8SChris Lattner CommandObjectProcessAttach::CommandOptions::g_option_table[] =
72930fdc8d8SChris Lattner {
730deaab222SCaroline Tice { LLDB_OPT_SET_ALL, false, "plugin", 'P', required_argument, NULL, 0, eArgTypePlugin,        "Name of the process plugin you want to use."},
731deaab222SCaroline Tice { LLDB_OPT_SET_1,   false, "pid",    'p', required_argument, NULL, 0, eArgTypePid,           "The process ID of an existing process to attach to."},
732deaab222SCaroline Tice { LLDB_OPT_SET_2,   false, "name",   'n', required_argument, NULL, 0, eArgTypeProcessName,  "The name of the process to attach to."},
733deaab222SCaroline Tice { LLDB_OPT_SET_2,   false, "waitfor",'w', no_argument,       NULL, 0, eArgTypeNone,              "Wait for the the process with <process-name> to launch."},
734deaab222SCaroline Tice { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
73530fdc8d8SChris Lattner };
73630fdc8d8SChris Lattner 
73730fdc8d8SChris Lattner //-------------------------------------------------------------------------
73830fdc8d8SChris Lattner // CommandObjectProcessContinue
73930fdc8d8SChris Lattner //-------------------------------------------------------------------------
74030fdc8d8SChris Lattner 
74130fdc8d8SChris Lattner class CommandObjectProcessContinue : public CommandObject
74230fdc8d8SChris Lattner {
74330fdc8d8SChris Lattner public:
74430fdc8d8SChris Lattner 
745a7015092SGreg Clayton     CommandObjectProcessContinue (CommandInterpreter &interpreter) :
746a7015092SGreg Clayton         CommandObject (interpreter,
747a7015092SGreg Clayton                        "process continue",
748e3d26315SCaroline Tice                        "Continue execution of all threads in the current process.",
74930fdc8d8SChris Lattner                        "process continue",
75030fdc8d8SChris Lattner                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
75130fdc8d8SChris Lattner     {
75230fdc8d8SChris Lattner     }
75330fdc8d8SChris Lattner 
75430fdc8d8SChris Lattner 
75530fdc8d8SChris Lattner     ~CommandObjectProcessContinue ()
75630fdc8d8SChris Lattner     {
75730fdc8d8SChris Lattner     }
75830fdc8d8SChris Lattner 
75930fdc8d8SChris Lattner     bool
760a7015092SGreg Clayton     Execute (Args& command,
76130fdc8d8SChris Lattner              CommandReturnObject &result)
76230fdc8d8SChris Lattner     {
763a7015092SGreg Clayton         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
764a7015092SGreg Clayton         bool synchronous_execution = m_interpreter.GetSynchronous ();
76530fdc8d8SChris Lattner 
76630fdc8d8SChris Lattner         if (process == NULL)
76730fdc8d8SChris Lattner         {
76830fdc8d8SChris Lattner             result.AppendError ("no process to continue");
76930fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
77030fdc8d8SChris Lattner             return false;
77130fdc8d8SChris Lattner          }
77230fdc8d8SChris Lattner 
77330fdc8d8SChris Lattner         StateType state = process->GetState();
77430fdc8d8SChris Lattner         if (state == eStateStopped)
77530fdc8d8SChris Lattner         {
77630fdc8d8SChris Lattner             if (command.GetArgumentCount() != 0)
77730fdc8d8SChris Lattner             {
77830fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("The '%s' command does not take any arguments.\n", m_cmd_name.c_str());
77930fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
78030fdc8d8SChris Lattner                 return false;
78130fdc8d8SChris Lattner             }
78230fdc8d8SChris Lattner 
78330fdc8d8SChris Lattner             const uint32_t num_threads = process->GetThreadList().GetSize();
78430fdc8d8SChris Lattner 
78530fdc8d8SChris Lattner             // Set the actions that the threads should each take when resuming
78630fdc8d8SChris Lattner             for (uint32_t idx=0; idx<num_threads; ++idx)
78730fdc8d8SChris Lattner             {
78830fdc8d8SChris Lattner                 process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState (eStateRunning);
78930fdc8d8SChris Lattner             }
79030fdc8d8SChris Lattner 
79130fdc8d8SChris Lattner             Error error(process->Resume());
79230fdc8d8SChris Lattner             if (error.Success())
79330fdc8d8SChris Lattner             {
79419388cfcSGreg Clayton                 result.AppendMessageWithFormat ("Process %i resuming\n", process->GetID());
79530fdc8d8SChris Lattner                 if (synchronous_execution)
79630fdc8d8SChris Lattner                 {
797b132097bSGreg Clayton                     state = process->WaitForProcessToStop (NULL);
79830fdc8d8SChris Lattner 
79930fdc8d8SChris Lattner                     result.SetDidChangeProcessState (true);
80030fdc8d8SChris Lattner                     result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state));
80130fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
80230fdc8d8SChris Lattner                 }
80330fdc8d8SChris Lattner                 else
80430fdc8d8SChris Lattner                 {
80530fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusSuccessContinuingNoResult);
80630fdc8d8SChris Lattner                 }
80730fdc8d8SChris Lattner             }
80830fdc8d8SChris Lattner             else
80930fdc8d8SChris Lattner             {
81030fdc8d8SChris Lattner                 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
81130fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
81230fdc8d8SChris Lattner             }
81330fdc8d8SChris Lattner         }
81430fdc8d8SChris Lattner         else
81530fdc8d8SChris Lattner         {
81630fdc8d8SChris Lattner             result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
81730fdc8d8SChris Lattner                                          StateAsCString(state));
81830fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
81930fdc8d8SChris Lattner         }
82030fdc8d8SChris Lattner         return result.Succeeded();
82130fdc8d8SChris Lattner     }
82230fdc8d8SChris Lattner };
82330fdc8d8SChris Lattner 
82430fdc8d8SChris Lattner //-------------------------------------------------------------------------
82530fdc8d8SChris Lattner // CommandObjectProcessDetach
82630fdc8d8SChris Lattner //-------------------------------------------------------------------------
82730fdc8d8SChris Lattner 
82830fdc8d8SChris Lattner class CommandObjectProcessDetach : public CommandObject
82930fdc8d8SChris Lattner {
83030fdc8d8SChris Lattner public:
83130fdc8d8SChris Lattner 
832a7015092SGreg Clayton     CommandObjectProcessDetach (CommandInterpreter &interpreter) :
833a7015092SGreg Clayton         CommandObject (interpreter,
834a7015092SGreg Clayton                        "process detach",
835e3d26315SCaroline Tice                        "Detach from the current process being debugged.",
83630fdc8d8SChris Lattner                        "process detach",
83730fdc8d8SChris Lattner                        eFlagProcessMustBeLaunched)
83830fdc8d8SChris Lattner     {
83930fdc8d8SChris Lattner     }
84030fdc8d8SChris Lattner 
84130fdc8d8SChris Lattner     ~CommandObjectProcessDetach ()
84230fdc8d8SChris Lattner     {
84330fdc8d8SChris Lattner     }
84430fdc8d8SChris Lattner 
84530fdc8d8SChris Lattner     bool
846a7015092SGreg Clayton     Execute (Args& command,
84730fdc8d8SChris Lattner              CommandReturnObject &result)
84830fdc8d8SChris Lattner     {
849a7015092SGreg Clayton         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
85030fdc8d8SChris Lattner         if (process == NULL)
85130fdc8d8SChris Lattner         {
85230fdc8d8SChris Lattner             result.AppendError ("must have a valid process in order to detach");
85330fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
85430fdc8d8SChris Lattner             return false;
85530fdc8d8SChris Lattner         }
85630fdc8d8SChris Lattner 
8575d7be2e6SCaroline Tice         result.AppendMessageWithFormat ("Detaching from process %i\n", process->GetID());
85830fdc8d8SChris Lattner         Error error (process->Detach());
85930fdc8d8SChris Lattner         if (error.Success())
86030fdc8d8SChris Lattner         {
86130fdc8d8SChris Lattner             result.SetStatus (eReturnStatusSuccessFinishResult);
86230fdc8d8SChris Lattner         }
86330fdc8d8SChris Lattner         else
86430fdc8d8SChris Lattner         {
86530fdc8d8SChris Lattner             result.AppendErrorWithFormat ("Detach failed: %s\n", error.AsCString());
86630fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
86730fdc8d8SChris Lattner             return false;
86830fdc8d8SChris Lattner         }
86930fdc8d8SChris Lattner         return result.Succeeded();
87030fdc8d8SChris Lattner     }
87130fdc8d8SChris Lattner };
87230fdc8d8SChris Lattner 
87330fdc8d8SChris Lattner //-------------------------------------------------------------------------
8748f343b09SGreg Clayton // CommandObjectProcessLoad
8758f343b09SGreg Clayton //-------------------------------------------------------------------------
8768f343b09SGreg Clayton 
8778f343b09SGreg Clayton class CommandObjectProcessLoad : public CommandObject
8788f343b09SGreg Clayton {
8798f343b09SGreg Clayton public:
8808f343b09SGreg Clayton 
8818f343b09SGreg Clayton     CommandObjectProcessLoad (CommandInterpreter &interpreter) :
8828f343b09SGreg Clayton         CommandObject (interpreter,
8838f343b09SGreg Clayton                        "process load",
8848f343b09SGreg Clayton                        "Load a shared library into the current process.",
8858f343b09SGreg Clayton                        "process load <filename> [<filename> ...]",
8868f343b09SGreg Clayton                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
8878f343b09SGreg Clayton     {
8888f343b09SGreg Clayton     }
8898f343b09SGreg Clayton 
8908f343b09SGreg Clayton     ~CommandObjectProcessLoad ()
8918f343b09SGreg Clayton     {
8928f343b09SGreg Clayton     }
8938f343b09SGreg Clayton 
8948f343b09SGreg Clayton     bool
8958f343b09SGreg Clayton     Execute (Args& command,
8968f343b09SGreg Clayton              CommandReturnObject &result)
8978f343b09SGreg Clayton     {
8988f343b09SGreg Clayton         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
8998f343b09SGreg Clayton         if (process == NULL)
9008f343b09SGreg Clayton         {
9018f343b09SGreg Clayton             result.AppendError ("must have a valid process in order to load a shared library");
9028f343b09SGreg Clayton             result.SetStatus (eReturnStatusFailed);
9038f343b09SGreg Clayton             return false;
9048f343b09SGreg Clayton         }
9058f343b09SGreg Clayton 
9068f343b09SGreg Clayton         const uint32_t argc = command.GetArgumentCount();
9078f343b09SGreg Clayton 
9088f343b09SGreg Clayton         for (uint32_t i=0; i<argc; ++i)
9098f343b09SGreg Clayton         {
9108f343b09SGreg Clayton             Error error;
9118f343b09SGreg Clayton             const char *image_path = command.GetArgumentAtIndex(i);
9128f343b09SGreg Clayton             FileSpec image_spec (image_path, false);
9138f343b09SGreg Clayton             uint32_t image_token = process->LoadImage(image_spec, error);
9148f343b09SGreg Clayton             if (image_token != LLDB_INVALID_IMAGE_TOKEN)
9158f343b09SGreg Clayton             {
9168f343b09SGreg Clayton                 result.AppendMessageWithFormat ("Loading \"%s\"...ok\nImage %u loaded.\n", image_path, image_token);
9178f343b09SGreg Clayton                 result.SetStatus (eReturnStatusSuccessFinishResult);
9188f343b09SGreg Clayton             }
9198f343b09SGreg Clayton             else
9208f343b09SGreg Clayton             {
9218f343b09SGreg Clayton                 result.AppendErrorWithFormat ("failed to load '%s': %s", image_path, error.AsCString());
9228f343b09SGreg Clayton                 result.SetStatus (eReturnStatusFailed);
9238f343b09SGreg Clayton             }
9248f343b09SGreg Clayton         }
9258f343b09SGreg Clayton         return result.Succeeded();
9268f343b09SGreg Clayton     }
9278f343b09SGreg Clayton };
9288f343b09SGreg Clayton 
9298f343b09SGreg Clayton 
9308f343b09SGreg Clayton //-------------------------------------------------------------------------
9318f343b09SGreg Clayton // CommandObjectProcessUnload
9328f343b09SGreg Clayton //-------------------------------------------------------------------------
9338f343b09SGreg Clayton 
9348f343b09SGreg Clayton class CommandObjectProcessUnload : public CommandObject
9358f343b09SGreg Clayton {
9368f343b09SGreg Clayton public:
9378f343b09SGreg Clayton 
9388f343b09SGreg Clayton     CommandObjectProcessUnload (CommandInterpreter &interpreter) :
9398f343b09SGreg Clayton         CommandObject (interpreter,
9408f343b09SGreg Clayton                        "process unload",
9418f343b09SGreg Clayton                        "Unload a shared library from the current process using the index returned by a previous call to \"process load\".",
9428f343b09SGreg Clayton                        "process unload <index>",
9438f343b09SGreg Clayton                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
9448f343b09SGreg Clayton     {
9458f343b09SGreg Clayton     }
9468f343b09SGreg Clayton 
9478f343b09SGreg Clayton     ~CommandObjectProcessUnload ()
9488f343b09SGreg Clayton     {
9498f343b09SGreg Clayton     }
9508f343b09SGreg Clayton 
9518f343b09SGreg Clayton     bool
9528f343b09SGreg Clayton     Execute (Args& command,
9538f343b09SGreg Clayton              CommandReturnObject &result)
9548f343b09SGreg Clayton     {
9558f343b09SGreg Clayton         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
9568f343b09SGreg Clayton         if (process == NULL)
9578f343b09SGreg Clayton         {
9588f343b09SGreg Clayton             result.AppendError ("must have a valid process in order to load a shared library");
9598f343b09SGreg Clayton             result.SetStatus (eReturnStatusFailed);
9608f343b09SGreg Clayton             return false;
9618f343b09SGreg Clayton         }
9628f343b09SGreg Clayton 
9638f343b09SGreg Clayton         const uint32_t argc = command.GetArgumentCount();
9648f343b09SGreg Clayton 
9658f343b09SGreg Clayton         for (uint32_t i=0; i<argc; ++i)
9668f343b09SGreg Clayton         {
9678f343b09SGreg Clayton             const char *image_token_cstr = command.GetArgumentAtIndex(i);
9688f343b09SGreg Clayton             uint32_t image_token = Args::StringToUInt32(image_token_cstr, LLDB_INVALID_IMAGE_TOKEN, 0);
9698f343b09SGreg Clayton             if (image_token == LLDB_INVALID_IMAGE_TOKEN)
9708f343b09SGreg Clayton             {
9718f343b09SGreg Clayton                 result.AppendErrorWithFormat ("invalid image index argument '%s'", image_token_cstr);
9728f343b09SGreg Clayton                 result.SetStatus (eReturnStatusFailed);
9738f343b09SGreg Clayton                 break;
9748f343b09SGreg Clayton             }
9758f343b09SGreg Clayton             else
9768f343b09SGreg Clayton             {
9778f343b09SGreg Clayton                 Error error (process->UnloadImage(image_token));
9788f343b09SGreg Clayton                 if (error.Success())
9798f343b09SGreg Clayton                 {
9808f343b09SGreg Clayton                     result.AppendMessageWithFormat ("Unloading shared library with index %u...ok\n", image_token);
9818f343b09SGreg Clayton                     result.SetStatus (eReturnStatusSuccessFinishResult);
9828f343b09SGreg Clayton                 }
9838f343b09SGreg Clayton                 else
9848f343b09SGreg Clayton                 {
9858f343b09SGreg Clayton                     result.AppendErrorWithFormat ("failed to unload image: %s", error.AsCString());
9868f343b09SGreg Clayton                     result.SetStatus (eReturnStatusFailed);
9878f343b09SGreg Clayton                     break;
9888f343b09SGreg Clayton                 }
9898f343b09SGreg Clayton             }
9908f343b09SGreg Clayton         }
9918f343b09SGreg Clayton         return result.Succeeded();
9928f343b09SGreg Clayton     }
9938f343b09SGreg Clayton };
9948f343b09SGreg Clayton 
9958f343b09SGreg Clayton //-------------------------------------------------------------------------
99630fdc8d8SChris Lattner // CommandObjectProcessSignal
99730fdc8d8SChris Lattner //-------------------------------------------------------------------------
99830fdc8d8SChris Lattner 
99930fdc8d8SChris Lattner class CommandObjectProcessSignal : public CommandObject
100030fdc8d8SChris Lattner {
100130fdc8d8SChris Lattner public:
100230fdc8d8SChris Lattner 
1003a7015092SGreg Clayton     CommandObjectProcessSignal (CommandInterpreter &interpreter) :
1004a7015092SGreg Clayton         CommandObject (interpreter,
1005a7015092SGreg Clayton                        "process signal",
1006e3d26315SCaroline Tice                        "Send a UNIX signal to the current process being debugged.",
1007405fe67fSCaroline Tice                        NULL)
100830fdc8d8SChris Lattner     {
1009405fe67fSCaroline Tice         CommandArgumentEntry arg;
1010405fe67fSCaroline Tice         CommandArgumentData signal_arg;
1011405fe67fSCaroline Tice 
1012405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
1013c0dbdfb6SCaroline Tice         signal_arg.arg_type = eArgTypeUnixSignal;
1014405fe67fSCaroline Tice         signal_arg.arg_repetition = eArgRepeatPlain;
1015405fe67fSCaroline Tice 
1016405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
1017405fe67fSCaroline Tice         arg.push_back (signal_arg);
1018405fe67fSCaroline Tice 
1019405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
1020405fe67fSCaroline Tice         m_arguments.push_back (arg);
102130fdc8d8SChris Lattner     }
102230fdc8d8SChris Lattner 
102330fdc8d8SChris Lattner     ~CommandObjectProcessSignal ()
102430fdc8d8SChris Lattner     {
102530fdc8d8SChris Lattner     }
102630fdc8d8SChris Lattner 
102730fdc8d8SChris Lattner     bool
1028a7015092SGreg Clayton     Execute (Args& command,
102930fdc8d8SChris Lattner              CommandReturnObject &result)
103030fdc8d8SChris Lattner     {
1031a7015092SGreg Clayton         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
103230fdc8d8SChris Lattner         if (process == NULL)
103330fdc8d8SChris Lattner         {
103430fdc8d8SChris Lattner             result.AppendError ("no process to signal");
103530fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
103630fdc8d8SChris Lattner             return false;
103730fdc8d8SChris Lattner         }
103830fdc8d8SChris Lattner 
103930fdc8d8SChris Lattner         if (command.GetArgumentCount() == 1)
104030fdc8d8SChris Lattner         {
1041237cd906SGreg Clayton             int signo = LLDB_INVALID_SIGNAL_NUMBER;
1042237cd906SGreg Clayton 
1043237cd906SGreg Clayton             const char *signal_name = command.GetArgumentAtIndex(0);
1044237cd906SGreg Clayton             if (::isxdigit (signal_name[0]))
1045237cd906SGreg Clayton                 signo = Args::StringToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0);
1046237cd906SGreg Clayton             else
1047237cd906SGreg Clayton                 signo = process->GetUnixSignals().GetSignalNumberFromName (signal_name);
1048237cd906SGreg Clayton 
1049237cd906SGreg Clayton             if (signo == LLDB_INVALID_SIGNAL_NUMBER)
105030fdc8d8SChris Lattner             {
105130fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("Invalid signal argument '%s'.\n", command.GetArgumentAtIndex(0));
105230fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
105330fdc8d8SChris Lattner             }
105430fdc8d8SChris Lattner             else
105530fdc8d8SChris Lattner             {
105630fdc8d8SChris Lattner                 Error error (process->Signal (signo));
105730fdc8d8SChris Lattner                 if (error.Success())
105830fdc8d8SChris Lattner                 {
105930fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusSuccessFinishResult);
106030fdc8d8SChris Lattner                 }
106130fdc8d8SChris Lattner                 else
106230fdc8d8SChris Lattner                 {
106330fdc8d8SChris Lattner                     result.AppendErrorWithFormat ("Failed to send signal %i: %s\n", signo, error.AsCString());
106430fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
106530fdc8d8SChris Lattner                 }
106630fdc8d8SChris Lattner             }
106730fdc8d8SChris Lattner         }
106830fdc8d8SChris Lattner         else
106930fdc8d8SChris Lattner         {
107030fdc8d8SChris Lattner             result.AppendErrorWithFormat("'%s' takes exactly one signal number argument:\nUsage: \n", m_cmd_name.c_str(),
107130fdc8d8SChris Lattner                                         m_cmd_syntax.c_str());
107230fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
107330fdc8d8SChris Lattner         }
107430fdc8d8SChris Lattner         return result.Succeeded();
107530fdc8d8SChris Lattner     }
107630fdc8d8SChris Lattner };
107730fdc8d8SChris Lattner 
107830fdc8d8SChris Lattner 
107930fdc8d8SChris Lattner //-------------------------------------------------------------------------
108030fdc8d8SChris Lattner // CommandObjectProcessInterrupt
108130fdc8d8SChris Lattner //-------------------------------------------------------------------------
108230fdc8d8SChris Lattner 
108330fdc8d8SChris Lattner class CommandObjectProcessInterrupt : public CommandObject
108430fdc8d8SChris Lattner {
108530fdc8d8SChris Lattner public:
108630fdc8d8SChris Lattner 
108730fdc8d8SChris Lattner 
1088a7015092SGreg Clayton     CommandObjectProcessInterrupt (CommandInterpreter &interpreter) :
1089a7015092SGreg Clayton     CommandObject (interpreter,
1090a7015092SGreg Clayton                    "process interrupt",
1091e3d26315SCaroline Tice                    "Interrupt the current process being debugged.",
109230fdc8d8SChris Lattner                    "process interrupt",
109330fdc8d8SChris Lattner                    eFlagProcessMustBeLaunched)
109430fdc8d8SChris Lattner     {
109530fdc8d8SChris Lattner     }
109630fdc8d8SChris Lattner 
109730fdc8d8SChris Lattner     ~CommandObjectProcessInterrupt ()
109830fdc8d8SChris Lattner     {
109930fdc8d8SChris Lattner     }
110030fdc8d8SChris Lattner 
110130fdc8d8SChris Lattner     bool
1102a7015092SGreg Clayton     Execute (Args& command,
110330fdc8d8SChris Lattner              CommandReturnObject &result)
110430fdc8d8SChris Lattner     {
1105a7015092SGreg Clayton         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
110630fdc8d8SChris Lattner         if (process == NULL)
110730fdc8d8SChris Lattner         {
110830fdc8d8SChris Lattner             result.AppendError ("no process to halt");
110930fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
111030fdc8d8SChris Lattner             return false;
111130fdc8d8SChris Lattner         }
111230fdc8d8SChris Lattner 
111330fdc8d8SChris Lattner         if (command.GetArgumentCount() == 0)
111430fdc8d8SChris Lattner         {
111530fdc8d8SChris Lattner             Error error(process->Halt ());
111630fdc8d8SChris Lattner             if (error.Success())
111730fdc8d8SChris Lattner             {
111830fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusSuccessFinishResult);
111930fdc8d8SChris Lattner 
112030fdc8d8SChris Lattner                 // Maybe we should add a "SuspendThreadPlans so we
112130fdc8d8SChris Lattner                 // can halt, and keep in place all the current thread plans.
112230fdc8d8SChris Lattner                 process->GetThreadList().DiscardThreadPlans();
112330fdc8d8SChris Lattner             }
112430fdc8d8SChris Lattner             else
112530fdc8d8SChris Lattner             {
112630fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("Failed to halt process: %s\n", error.AsCString());
112730fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
112830fdc8d8SChris Lattner             }
112930fdc8d8SChris Lattner         }
113030fdc8d8SChris Lattner         else
113130fdc8d8SChris Lattner         {
113230fdc8d8SChris Lattner             result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: \n",
113330fdc8d8SChris Lattner                                         m_cmd_name.c_str(),
113430fdc8d8SChris Lattner                                         m_cmd_syntax.c_str());
113530fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
113630fdc8d8SChris Lattner         }
113730fdc8d8SChris Lattner         return result.Succeeded();
113830fdc8d8SChris Lattner     }
113930fdc8d8SChris Lattner };
114030fdc8d8SChris Lattner 
114130fdc8d8SChris Lattner //-------------------------------------------------------------------------
114230fdc8d8SChris Lattner // CommandObjectProcessKill
114330fdc8d8SChris Lattner //-------------------------------------------------------------------------
114430fdc8d8SChris Lattner 
114530fdc8d8SChris Lattner class CommandObjectProcessKill : public CommandObject
114630fdc8d8SChris Lattner {
114730fdc8d8SChris Lattner public:
114830fdc8d8SChris Lattner 
1149a7015092SGreg Clayton     CommandObjectProcessKill (CommandInterpreter &interpreter) :
1150a7015092SGreg Clayton     CommandObject (interpreter,
1151a7015092SGreg Clayton                    "process kill",
1152e3d26315SCaroline Tice                    "Terminate the current process being debugged.",
115330fdc8d8SChris Lattner                    "process kill",
115430fdc8d8SChris Lattner                    eFlagProcessMustBeLaunched)
115530fdc8d8SChris Lattner     {
115630fdc8d8SChris Lattner     }
115730fdc8d8SChris Lattner 
115830fdc8d8SChris Lattner     ~CommandObjectProcessKill ()
115930fdc8d8SChris Lattner     {
116030fdc8d8SChris Lattner     }
116130fdc8d8SChris Lattner 
116230fdc8d8SChris Lattner     bool
1163a7015092SGreg Clayton     Execute (Args& command,
116430fdc8d8SChris Lattner              CommandReturnObject &result)
116530fdc8d8SChris Lattner     {
1166a7015092SGreg Clayton         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
116730fdc8d8SChris Lattner         if (process == NULL)
116830fdc8d8SChris Lattner         {
116930fdc8d8SChris Lattner             result.AppendError ("no process to kill");
117030fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
117130fdc8d8SChris Lattner             return false;
117230fdc8d8SChris Lattner         }
117330fdc8d8SChris Lattner 
117430fdc8d8SChris Lattner         if (command.GetArgumentCount() == 0)
117530fdc8d8SChris Lattner         {
117630fdc8d8SChris Lattner             Error error (process->Destroy());
117730fdc8d8SChris Lattner             if (error.Success())
117830fdc8d8SChris Lattner             {
117930fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusSuccessFinishResult);
118030fdc8d8SChris Lattner             }
118130fdc8d8SChris Lattner             else
118230fdc8d8SChris Lattner             {
118330fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString());
118430fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
118530fdc8d8SChris Lattner             }
118630fdc8d8SChris Lattner         }
118730fdc8d8SChris Lattner         else
118830fdc8d8SChris Lattner         {
118930fdc8d8SChris Lattner             result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: \n",
119030fdc8d8SChris Lattner                                         m_cmd_name.c_str(),
119130fdc8d8SChris Lattner                                         m_cmd_syntax.c_str());
119230fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
119330fdc8d8SChris Lattner         }
119430fdc8d8SChris Lattner         return result.Succeeded();
119530fdc8d8SChris Lattner     }
119630fdc8d8SChris Lattner };
119730fdc8d8SChris Lattner 
119830fdc8d8SChris Lattner //-------------------------------------------------------------------------
11994b9bea87SJim Ingham // CommandObjectProcessStatus
12004b9bea87SJim Ingham //-------------------------------------------------------------------------
12014b9bea87SJim Ingham class CommandObjectProcessStatus : public CommandObject
12024b9bea87SJim Ingham {
12034b9bea87SJim Ingham public:
1204a7015092SGreg Clayton     CommandObjectProcessStatus (CommandInterpreter &interpreter) :
1205a7015092SGreg Clayton     CommandObject (interpreter,
1206a7015092SGreg Clayton                    "process status",
1207e3d26315SCaroline Tice                    "Show the current status and location of executing process.",
1208e3d26315SCaroline Tice                    "process status",
12094b9bea87SJim Ingham                    0)
12104b9bea87SJim Ingham     {
12114b9bea87SJim Ingham     }
12124b9bea87SJim Ingham 
12134b9bea87SJim Ingham     ~CommandObjectProcessStatus()
12144b9bea87SJim Ingham     {
12154b9bea87SJim Ingham     }
12164b9bea87SJim Ingham 
12174b9bea87SJim Ingham 
12184b9bea87SJim Ingham     bool
12194b9bea87SJim Ingham     Execute
12204b9bea87SJim Ingham     (
12214b9bea87SJim Ingham         Args& command,
12224b9bea87SJim Ingham         CommandReturnObject &result
12234b9bea87SJim Ingham     )
12244b9bea87SJim Ingham     {
12254b9bea87SJim Ingham         StreamString &output_stream = result.GetOutputStream();
12264b9bea87SJim Ingham         result.SetStatus (eReturnStatusSuccessFinishNoResult);
1227a7015092SGreg Clayton         ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext());
12284b9bea87SJim Ingham         if (exe_ctx.process)
12294b9bea87SJim Ingham         {
12304b9bea87SJim Ingham             const StateType state = exe_ctx.process->GetState();
12314b9bea87SJim Ingham             if (StateIsStoppedState(state))
12324b9bea87SJim Ingham             {
12334b9bea87SJim Ingham                 if (state == eStateExited)
12344b9bea87SJim Ingham                 {
12354b9bea87SJim Ingham                     int exit_status = exe_ctx.process->GetExitStatus();
12364b9bea87SJim Ingham                     const char *exit_description = exe_ctx.process->GetExitDescription();
12374b9bea87SJim Ingham                     output_stream.Printf ("Process %d exited with status = %i (0x%8.8x) %s\n",
12384b9bea87SJim Ingham                                           exe_ctx.process->GetID(),
12394b9bea87SJim Ingham                                           exit_status,
12404b9bea87SJim Ingham                                           exit_status,
12414b9bea87SJim Ingham                                           exit_description ? exit_description : "");
12424b9bea87SJim Ingham                 }
12434b9bea87SJim Ingham                 else
12444b9bea87SJim Ingham                 {
12454b9bea87SJim Ingham                     output_stream.Printf ("Process %d %s\n", exe_ctx.process->GetID(), StateAsCString (state));
12464b9bea87SJim Ingham                     if (exe_ctx.thread == NULL)
12474b9bea87SJim Ingham                         exe_ctx.thread = exe_ctx.process->GetThreadList().GetThreadAtIndex(0).get();
12484b9bea87SJim Ingham                     if (exe_ctx.thread != NULL)
12494b9bea87SJim Ingham                     {
1250a7015092SGreg Clayton                         DisplayThreadsInfo (m_interpreter, &exe_ctx, result, true, true);
12514b9bea87SJim Ingham                     }
12524b9bea87SJim Ingham                     else
12534b9bea87SJim Ingham                     {
12544b9bea87SJim Ingham                         result.AppendError ("No valid thread found in current process.");
12554b9bea87SJim Ingham                         result.SetStatus (eReturnStatusFailed);
12564b9bea87SJim Ingham                     }
12574b9bea87SJim Ingham                 }
12584b9bea87SJim Ingham             }
12594b9bea87SJim Ingham             else
12604b9bea87SJim Ingham             {
12614b9bea87SJim Ingham                 output_stream.Printf ("Process %d is running.\n",
12624b9bea87SJim Ingham                                           exe_ctx.process->GetID());
12634b9bea87SJim Ingham             }
12644b9bea87SJim Ingham         }
12654b9bea87SJim Ingham         else
12664b9bea87SJim Ingham         {
12674b9bea87SJim Ingham             result.AppendError ("No current location or status available.");
12684b9bea87SJim Ingham             result.SetStatus (eReturnStatusFailed);
12694b9bea87SJim Ingham         }
12704b9bea87SJim Ingham         return result.Succeeded();
12714b9bea87SJim Ingham     }
12724b9bea87SJim Ingham };
12734b9bea87SJim Ingham 
12744b9bea87SJim Ingham //-------------------------------------------------------------------------
127535731357SCaroline Tice // CommandObjectProcessHandle
127635731357SCaroline Tice //-------------------------------------------------------------------------
127735731357SCaroline Tice 
127835731357SCaroline Tice class CommandObjectProcessHandle : public CommandObject
127935731357SCaroline Tice {
128035731357SCaroline Tice public:
128135731357SCaroline Tice 
128235731357SCaroline Tice     class CommandOptions : public Options
128335731357SCaroline Tice     {
128435731357SCaroline Tice     public:
128535731357SCaroline Tice 
128635731357SCaroline Tice         CommandOptions () :
128735731357SCaroline Tice             Options ()
128835731357SCaroline Tice         {
128935731357SCaroline Tice             ResetOptionValues ();
129035731357SCaroline Tice         }
129135731357SCaroline Tice 
129235731357SCaroline Tice         ~CommandOptions ()
129335731357SCaroline Tice         {
129435731357SCaroline Tice         }
129535731357SCaroline Tice 
129635731357SCaroline Tice         Error
129735731357SCaroline Tice         SetOptionValue (int option_idx, const char *option_arg)
129835731357SCaroline Tice         {
129935731357SCaroline Tice             Error error;
130035731357SCaroline Tice             char short_option = (char) m_getopt_table[option_idx].val;
130135731357SCaroline Tice 
130235731357SCaroline Tice             switch (short_option)
130335731357SCaroline Tice             {
130435731357SCaroline Tice                 case 's':
130535731357SCaroline Tice                     stop = option_arg;
130635731357SCaroline Tice                     break;
130735731357SCaroline Tice                 case 'n':
130835731357SCaroline Tice                     notify = option_arg;
130935731357SCaroline Tice                     break;
131035731357SCaroline Tice                 case 'p':
131135731357SCaroline Tice                     pass = option_arg;
131235731357SCaroline Tice                     break;
131335731357SCaroline Tice                 default:
131435731357SCaroline Tice                     error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
131535731357SCaroline Tice                     break;
131635731357SCaroline Tice             }
131735731357SCaroline Tice             return error;
131835731357SCaroline Tice         }
131935731357SCaroline Tice 
132035731357SCaroline Tice         void
132135731357SCaroline Tice         ResetOptionValues ()
132235731357SCaroline Tice         {
132335731357SCaroline Tice             Options::ResetOptionValues();
132435731357SCaroline Tice             stop.clear();
132535731357SCaroline Tice             notify.clear();
132635731357SCaroline Tice             pass.clear();
132735731357SCaroline Tice         }
132835731357SCaroline Tice 
132935731357SCaroline Tice         const lldb::OptionDefinition*
133035731357SCaroline Tice         GetDefinitions ()
133135731357SCaroline Tice         {
133235731357SCaroline Tice             return g_option_table;
133335731357SCaroline Tice         }
133435731357SCaroline Tice 
133535731357SCaroline Tice         // Options table: Required for subclasses of Options.
133635731357SCaroline Tice 
133735731357SCaroline Tice         static lldb::OptionDefinition g_option_table[];
133835731357SCaroline Tice 
133935731357SCaroline Tice         // Instance variables to hold the values for command options.
134035731357SCaroline Tice 
134135731357SCaroline Tice         std::string stop;
134235731357SCaroline Tice         std::string notify;
134335731357SCaroline Tice         std::string pass;
134435731357SCaroline Tice     };
134535731357SCaroline Tice 
134635731357SCaroline Tice 
134735731357SCaroline Tice     CommandObjectProcessHandle (CommandInterpreter &interpreter) :
134835731357SCaroline Tice         CommandObject (interpreter,
134935731357SCaroline Tice                        "process handle",
135010ad7993SCaroline Tice                        "Show or update what the process and debugger should do with various signals received from the OS.",
135135731357SCaroline Tice                        NULL)
135235731357SCaroline Tice     {
135310ad7993SCaroline Tice         SetHelpLong ("If no signals are specified, update them all.  If no update option is specified, list the current values.\n");
135435731357SCaroline Tice         CommandArgumentEntry arg;
1355c0dbdfb6SCaroline Tice         CommandArgumentData signal_arg;
135635731357SCaroline Tice 
1357c0dbdfb6SCaroline Tice         signal_arg.arg_type = eArgTypeUnixSignal;
1358c0dbdfb6SCaroline Tice         signal_arg.arg_repetition = eArgRepeatStar;
135935731357SCaroline Tice 
1360c0dbdfb6SCaroline Tice         arg.push_back (signal_arg);
136135731357SCaroline Tice 
136235731357SCaroline Tice         m_arguments.push_back (arg);
136335731357SCaroline Tice     }
136435731357SCaroline Tice 
136535731357SCaroline Tice     ~CommandObjectProcessHandle ()
136635731357SCaroline Tice     {
136735731357SCaroline Tice     }
136835731357SCaroline Tice 
136935731357SCaroline Tice     Options *
137035731357SCaroline Tice     GetOptions ()
137135731357SCaroline Tice     {
137235731357SCaroline Tice         return &m_options;
137335731357SCaroline Tice     }
137435731357SCaroline Tice 
137535731357SCaroline Tice     bool
137610ad7993SCaroline Tice     VerifyCommandOptionValue (const std::string &option, int &real_value)
137735731357SCaroline Tice     {
137835731357SCaroline Tice         bool okay = true;
137935731357SCaroline Tice 
138010ad7993SCaroline Tice         bool success = false;
138110ad7993SCaroline Tice         bool tmp_value = Args::StringToBoolean (option.c_str(), false, &success);
138210ad7993SCaroline Tice 
138310ad7993SCaroline Tice         if (success && tmp_value)
138410ad7993SCaroline Tice             real_value = 1;
138510ad7993SCaroline Tice         else if (success && !tmp_value)
138610ad7993SCaroline Tice             real_value = 0;
138735731357SCaroline Tice         else
138835731357SCaroline Tice         {
138935731357SCaroline Tice             // If the value isn't 'true' or 'false', it had better be 0 or 1.
139010ad7993SCaroline Tice             real_value = Args::StringToUInt32 (option.c_str(), 3);
139110ad7993SCaroline Tice             if (real_value != 0 && real_value != 1)
139235731357SCaroline Tice                 okay = false;
139335731357SCaroline Tice         }
139435731357SCaroline Tice 
139535731357SCaroline Tice         return okay;
139635731357SCaroline Tice     }
139735731357SCaroline Tice 
139810ad7993SCaroline Tice     void
139910ad7993SCaroline Tice     PrintSignalHeader (Stream &str)
140010ad7993SCaroline Tice     {
140110ad7993SCaroline Tice         str.Printf ("NAME        PASS   STOP   NOTIFY\n");
140210ad7993SCaroline Tice         str.Printf ("==========  =====  =====  ======\n");
140310ad7993SCaroline Tice     }
140410ad7993SCaroline Tice 
140510ad7993SCaroline Tice     void
140610ad7993SCaroline Tice     PrintSignal (Stream &str, int32_t signo, const char *sig_name, UnixSignals &signals)
140710ad7993SCaroline Tice     {
140810ad7993SCaroline Tice         bool stop;
140910ad7993SCaroline Tice         bool suppress;
141010ad7993SCaroline Tice         bool notify;
141110ad7993SCaroline Tice 
141210ad7993SCaroline Tice         str.Printf ("%-10s  ", sig_name);
141310ad7993SCaroline Tice         if (signals.GetSignalInfo (signo, suppress, stop, notify))
141410ad7993SCaroline Tice         {
141510ad7993SCaroline Tice             bool pass = !suppress;
141610ad7993SCaroline Tice             str.Printf ("%s  %s  %s",
141710ad7993SCaroline Tice                         (pass ? "true " : "false"),
141810ad7993SCaroline Tice                         (stop ? "true " : "false"),
141910ad7993SCaroline Tice                         (notify ? "true " : "false"));
142010ad7993SCaroline Tice         }
142110ad7993SCaroline Tice         str.Printf ("\n");
142210ad7993SCaroline Tice     }
142310ad7993SCaroline Tice 
142410ad7993SCaroline Tice     void
142510ad7993SCaroline Tice     PrintSignalInformation (Stream &str, Args &signal_args, int num_valid_signals, UnixSignals &signals)
142610ad7993SCaroline Tice     {
142710ad7993SCaroline Tice         PrintSignalHeader (str);
142810ad7993SCaroline Tice 
142910ad7993SCaroline Tice         if (num_valid_signals > 0)
143010ad7993SCaroline Tice         {
143110ad7993SCaroline Tice             size_t num_args = signal_args.GetArgumentCount();
143210ad7993SCaroline Tice             for (size_t i = 0; i < num_args; ++i)
143310ad7993SCaroline Tice             {
143410ad7993SCaroline Tice                 int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i));
143510ad7993SCaroline Tice                 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
143610ad7993SCaroline Tice                     PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals);
143710ad7993SCaroline Tice             }
143810ad7993SCaroline Tice         }
143910ad7993SCaroline Tice         else // Print info for ALL signals
144010ad7993SCaroline Tice         {
144110ad7993SCaroline Tice             int32_t signo = signals.GetFirstSignalNumber();
144210ad7993SCaroline Tice             while (signo != LLDB_INVALID_SIGNAL_NUMBER)
144310ad7993SCaroline Tice             {
144410ad7993SCaroline Tice                 PrintSignal (str, signo, signals.GetSignalAsCString (signo), signals);
144510ad7993SCaroline Tice                 signo = signals.GetNextSignalNumber (signo);
144610ad7993SCaroline Tice             }
144710ad7993SCaroline Tice         }
144810ad7993SCaroline Tice     }
144910ad7993SCaroline Tice 
145035731357SCaroline Tice     bool
145135731357SCaroline Tice     Execute (Args &signal_args, CommandReturnObject &result)
145235731357SCaroline Tice     {
145335731357SCaroline Tice         TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
145435731357SCaroline Tice 
145535731357SCaroline Tice         if (!target_sp)
145635731357SCaroline Tice         {
145735731357SCaroline Tice             result.AppendError ("No current target;"
145835731357SCaroline Tice                                 " cannot handle signals until you have a valid target and process.\n");
145935731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
146035731357SCaroline Tice             return false;
146135731357SCaroline Tice         }
146235731357SCaroline Tice 
146335731357SCaroline Tice         ProcessSP process_sp = target_sp->GetProcessSP();
146435731357SCaroline Tice 
146535731357SCaroline Tice         if (!process_sp)
146635731357SCaroline Tice         {
146735731357SCaroline Tice             result.AppendError ("No current process; cannot handle signals until you have a valid process.\n");
146835731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
146935731357SCaroline Tice             return false;
147035731357SCaroline Tice         }
147135731357SCaroline Tice 
147235731357SCaroline Tice         int stop_action = -1;   // -1 means leave the current setting alone
147335731357SCaroline Tice         int pass_action = -1;   // -1 means leave the current setting alone
147435731357SCaroline Tice         int notify_action = -1; // -1 means leave the current setting alone
147535731357SCaroline Tice 
147635731357SCaroline Tice         if (! m_options.stop.empty()
147710ad7993SCaroline Tice             && ! VerifyCommandOptionValue (m_options.stop, stop_action))
147835731357SCaroline Tice         {
147935731357SCaroline Tice             result.AppendError ("Invalid argument for command option --stop; must be true or false.\n");
148035731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
148135731357SCaroline Tice             return false;
148235731357SCaroline Tice         }
148335731357SCaroline Tice 
148435731357SCaroline Tice         if (! m_options.notify.empty()
148510ad7993SCaroline Tice             && ! VerifyCommandOptionValue (m_options.notify, notify_action))
148635731357SCaroline Tice         {
148735731357SCaroline Tice             result.AppendError ("Invalid argument for command option --notify; must be true or false.\n");
148835731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
148935731357SCaroline Tice             return false;
149035731357SCaroline Tice         }
149135731357SCaroline Tice 
149235731357SCaroline Tice         if (! m_options.pass.empty()
149310ad7993SCaroline Tice             && ! VerifyCommandOptionValue (m_options.pass, pass_action))
149435731357SCaroline Tice         {
149535731357SCaroline Tice             result.AppendError ("Invalid argument for command option --pass; must be true or false.\n");
149635731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
149735731357SCaroline Tice             return false;
149835731357SCaroline Tice         }
149935731357SCaroline Tice 
150035731357SCaroline Tice         size_t num_args = signal_args.GetArgumentCount();
150135731357SCaroline Tice         UnixSignals &signals = process_sp->GetUnixSignals();
150235731357SCaroline Tice         int num_signals_set = 0;
150335731357SCaroline Tice 
150410ad7993SCaroline Tice         if (num_args > 0)
150510ad7993SCaroline Tice         {
150635731357SCaroline Tice             for (size_t i = 0; i < num_args; ++i)
150735731357SCaroline Tice             {
150835731357SCaroline Tice                 int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i));
150935731357SCaroline Tice                 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
151035731357SCaroline Tice                 {
151110ad7993SCaroline Tice                     // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees
151235731357SCaroline Tice                     // the value is either 0 or 1.
151335731357SCaroline Tice                     if (stop_action != -1)
151435731357SCaroline Tice                         signals.SetShouldStop (signo, (bool) stop_action);
151535731357SCaroline Tice                     if (pass_action != -1)
151635731357SCaroline Tice                     {
151710ad7993SCaroline Tice                         bool suppress = ! ((bool) pass_action);
151810ad7993SCaroline Tice                         signals.SetShouldSuppress (signo, suppress);
151935731357SCaroline Tice                     }
152035731357SCaroline Tice                     if (notify_action != -1)
152135731357SCaroline Tice                         signals.SetShouldNotify (signo, (bool) notify_action);
152235731357SCaroline Tice                     ++num_signals_set;
152335731357SCaroline Tice                 }
152435731357SCaroline Tice                 else
152535731357SCaroline Tice                 {
152635731357SCaroline Tice                     result.AppendErrorWithFormat ("Invalid signal name '%s'\n", signal_args.GetArgumentAtIndex (i));
152735731357SCaroline Tice                 }
152835731357SCaroline Tice             }
152910ad7993SCaroline Tice         }
153010ad7993SCaroline Tice         else
153110ad7993SCaroline Tice         {
153210ad7993SCaroline Tice             // No signal specified, if any command options were specified, update ALL signals.
153310ad7993SCaroline Tice             if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1))
153410ad7993SCaroline Tice             {
153510ad7993SCaroline Tice                 if (m_interpreter.Confirm ("Do you really want to update all the signals?", false))
153610ad7993SCaroline Tice                 {
153710ad7993SCaroline Tice                     int32_t signo = signals.GetFirstSignalNumber();
153810ad7993SCaroline Tice                     while (signo != LLDB_INVALID_SIGNAL_NUMBER)
153910ad7993SCaroline Tice                     {
154010ad7993SCaroline Tice                         if (notify_action != -1)
154110ad7993SCaroline Tice                             signals.SetShouldNotify (signo, (bool) notify_action);
154210ad7993SCaroline Tice                         if (stop_action != -1)
154310ad7993SCaroline Tice                             signals.SetShouldStop (signo, (bool) stop_action);
154410ad7993SCaroline Tice                         if (pass_action != -1)
154510ad7993SCaroline Tice                         {
154610ad7993SCaroline Tice                             bool suppress = ! ((bool) pass_action);
154710ad7993SCaroline Tice                             signals.SetShouldSuppress (signo, suppress);
154810ad7993SCaroline Tice                         }
154910ad7993SCaroline Tice                         signo = signals.GetNextSignalNumber (signo);
155010ad7993SCaroline Tice                     }
155110ad7993SCaroline Tice                 }
155210ad7993SCaroline Tice             }
155310ad7993SCaroline Tice         }
155410ad7993SCaroline Tice 
155510ad7993SCaroline Tice         PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals);
155635731357SCaroline Tice 
155735731357SCaroline Tice         if (num_signals_set > 0)
155835731357SCaroline Tice             result.SetStatus (eReturnStatusSuccessFinishNoResult);
155935731357SCaroline Tice         else
156035731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
156135731357SCaroline Tice 
156235731357SCaroline Tice         return result.Succeeded();
156335731357SCaroline Tice     }
156435731357SCaroline Tice 
156535731357SCaroline Tice protected:
156635731357SCaroline Tice 
156735731357SCaroline Tice     CommandOptions m_options;
156835731357SCaroline Tice };
156935731357SCaroline Tice 
157035731357SCaroline Tice lldb::OptionDefinition
157135731357SCaroline Tice CommandObjectProcessHandle::CommandOptions::g_option_table[] =
157235731357SCaroline Tice {
157335731357SCaroline Tice { 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." },
157435731357SCaroline Tice { 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." },
157535731357SCaroline Tice { LLDB_OPT_SET_1, false, "pass",  'p', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." },
157635731357SCaroline Tice { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
157735731357SCaroline Tice };
157835731357SCaroline Tice 
157935731357SCaroline Tice //-------------------------------------------------------------------------
158030fdc8d8SChris Lattner // CommandObjectMultiwordProcess
158130fdc8d8SChris Lattner //-------------------------------------------------------------------------
158230fdc8d8SChris Lattner 
15836611103cSGreg Clayton CommandObjectMultiwordProcess::CommandObjectMultiwordProcess (CommandInterpreter &interpreter) :
1584a7015092SGreg Clayton     CommandObjectMultiword (interpreter,
1585a7015092SGreg Clayton                             "process",
158630fdc8d8SChris Lattner                             "A set of commands for operating on a process.",
158730fdc8d8SChris Lattner                             "process <subcommand> [<subcommand-options>]")
158830fdc8d8SChris Lattner {
1589a7015092SGreg Clayton     LoadSubCommand ("attach",      CommandObjectSP (new CommandObjectProcessAttach (interpreter)));
1590a7015092SGreg Clayton     LoadSubCommand ("launch",      CommandObjectSP (new CommandObjectProcessLaunch (interpreter)));
1591a7015092SGreg Clayton     LoadSubCommand ("continue",    CommandObjectSP (new CommandObjectProcessContinue (interpreter)));
1592a7015092SGreg Clayton     LoadSubCommand ("detach",      CommandObjectSP (new CommandObjectProcessDetach (interpreter)));
15938f343b09SGreg Clayton     LoadSubCommand ("load",        CommandObjectSP (new CommandObjectProcessLoad (interpreter)));
15948f343b09SGreg Clayton     LoadSubCommand ("unload",      CommandObjectSP (new CommandObjectProcessUnload (interpreter)));
1595a7015092SGreg Clayton     LoadSubCommand ("signal",      CommandObjectSP (new CommandObjectProcessSignal (interpreter)));
159635731357SCaroline Tice     LoadSubCommand ("handle",      CommandObjectSP (new CommandObjectProcessHandle (interpreter)));
1597a7015092SGreg Clayton     LoadSubCommand ("status",      CommandObjectSP (new CommandObjectProcessStatus (interpreter)));
1598a7015092SGreg Clayton     LoadSubCommand ("interrupt",   CommandObjectSP (new CommandObjectProcessInterrupt (interpreter)));
1599a7015092SGreg Clayton     LoadSubCommand ("kill",        CommandObjectSP (new CommandObjectProcessKill (interpreter)));
160030fdc8d8SChris Lattner }
160130fdc8d8SChris Lattner 
160230fdc8d8SChris Lattner CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess ()
160330fdc8d8SChris Lattner {
160430fdc8d8SChris Lattner }
160530fdc8d8SChris Lattner 
1606