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;
65913c4fa1SGreg Clayton                 case 't':
66913c4fa1SGreg Clayton                     if (option_arg && option_arg[0])
67913c4fa1SGreg Clayton                         tty_name.assign (option_arg);
68913c4fa1SGreg Clayton                     in_new_tty = true;
69913c4fa1SGreg Clayton                     break;
7030fdc8d8SChris Lattner                 default:
7130fdc8d8SChris Lattner                     error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
7230fdc8d8SChris Lattner                     break;
7330fdc8d8SChris Lattner 
7430fdc8d8SChris Lattner             }
7530fdc8d8SChris Lattner             return error;
7630fdc8d8SChris Lattner         }
7730fdc8d8SChris Lattner 
7830fdc8d8SChris Lattner         void
7930fdc8d8SChris Lattner         ResetOptionValues ()
8030fdc8d8SChris Lattner         {
8130fdc8d8SChris Lattner             Options::ResetOptionValues();
8230fdc8d8SChris Lattner             stop_at_entry = false;
8319388cfcSGreg Clayton             in_new_tty = false;
84913c4fa1SGreg Clayton             tty_name.clear();
8530fdc8d8SChris Lattner             stdin_path.clear();
8630fdc8d8SChris Lattner             stdout_path.clear();
8730fdc8d8SChris Lattner             stderr_path.clear();
8830fdc8d8SChris Lattner             plugin_name.clear();
8930fdc8d8SChris Lattner         }
9030fdc8d8SChris Lattner 
9130fdc8d8SChris Lattner         const lldb::OptionDefinition*
9230fdc8d8SChris Lattner         GetDefinitions ()
9330fdc8d8SChris Lattner         {
9430fdc8d8SChris Lattner             return g_option_table;
9530fdc8d8SChris Lattner         }
9630fdc8d8SChris Lattner 
9730fdc8d8SChris Lattner         // Options table: Required for subclasses of Options.
9830fdc8d8SChris Lattner 
9930fdc8d8SChris Lattner         static lldb::OptionDefinition g_option_table[];
10030fdc8d8SChris Lattner 
10130fdc8d8SChris Lattner         // Instance variables to hold the values for command options.
10230fdc8d8SChris Lattner 
10330fdc8d8SChris Lattner         bool stop_at_entry;
10419388cfcSGreg Clayton         bool in_new_tty;
105913c4fa1SGreg Clayton         std::string tty_name;
10630fdc8d8SChris Lattner         std::string stderr_path;
10730fdc8d8SChris Lattner         std::string stdin_path;
10830fdc8d8SChris Lattner         std::string stdout_path;
10930fdc8d8SChris Lattner         std::string plugin_name;
11030fdc8d8SChris Lattner 
11130fdc8d8SChris Lattner     };
11230fdc8d8SChris Lattner 
113a7015092SGreg Clayton     CommandObjectProcessLaunch (CommandInterpreter &interpreter) :
114a7015092SGreg Clayton         CommandObject (interpreter,
115a7015092SGreg Clayton                        "process launch",
116e3d26315SCaroline Tice                        "Launch the executable in the debugger.",
117405fe67fSCaroline Tice                        NULL)
11830fdc8d8SChris Lattner     {
119405fe67fSCaroline Tice         CommandArgumentEntry arg;
120405fe67fSCaroline Tice         CommandArgumentData run_args_arg;
121405fe67fSCaroline Tice 
122405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
123405fe67fSCaroline Tice         run_args_arg.arg_type = eArgTypeRunArgs;
124405fe67fSCaroline Tice         run_args_arg.arg_repetition = eArgRepeatOptional;
125405fe67fSCaroline Tice 
126405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
127405fe67fSCaroline Tice         arg.push_back (run_args_arg);
128405fe67fSCaroline Tice 
129405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
130405fe67fSCaroline Tice         m_arguments.push_back (arg);
13130fdc8d8SChris Lattner     }
13230fdc8d8SChris Lattner 
13330fdc8d8SChris Lattner 
13430fdc8d8SChris Lattner     ~CommandObjectProcessLaunch ()
13530fdc8d8SChris Lattner     {
13630fdc8d8SChris Lattner     }
13730fdc8d8SChris Lattner 
13830fdc8d8SChris Lattner     Options *
13930fdc8d8SChris Lattner     GetOptions ()
14030fdc8d8SChris Lattner     {
14130fdc8d8SChris Lattner         return &m_options;
14230fdc8d8SChris Lattner     }
14330fdc8d8SChris Lattner 
14430fdc8d8SChris Lattner     bool
14505faeb71SGreg Clayton     Execute (Args& launch_args, CommandReturnObject &result)
14630fdc8d8SChris Lattner     {
147a7015092SGreg Clayton         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
14830fdc8d8SChris Lattner 
14930fdc8d8SChris Lattner         if (target == NULL)
15030fdc8d8SChris Lattner         {
15130fdc8d8SChris Lattner             result.AppendError ("invalid target, set executable file using 'file' command");
15230fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
15330fdc8d8SChris Lattner             return false;
15430fdc8d8SChris Lattner         }
15530fdc8d8SChris Lattner 
15630fdc8d8SChris Lattner         // If our listener is NULL, users aren't allows to launch
15730fdc8d8SChris Lattner         char filename[PATH_MAX];
15819388cfcSGreg Clayton         const Module *exe_module = target->GetExecutableModule().get();
15930fdc8d8SChris Lattner         exe_module->GetFileSpec().GetPath(filename, sizeof(filename));
16030fdc8d8SChris Lattner 
161a7015092SGreg Clayton         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
162a7015092SGreg Clayton         if (process && process->IsAlive())
16330fdc8d8SChris Lattner         {
16430fdc8d8SChris Lattner             result.AppendErrorWithFormat ("Process %u is currently being debugged, kill the process before running again.\n",
16530fdc8d8SChris Lattner                                           process->GetID());
16630fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
16730fdc8d8SChris Lattner             return false;
16830fdc8d8SChris Lattner         }
16930fdc8d8SChris Lattner 
17030fdc8d8SChris Lattner         const char *plugin_name;
17130fdc8d8SChris Lattner         if (!m_options.plugin_name.empty())
17230fdc8d8SChris Lattner             plugin_name = m_options.plugin_name.c_str();
17330fdc8d8SChris Lattner         else
17430fdc8d8SChris Lattner             plugin_name = NULL;
17530fdc8d8SChris Lattner 
176a7015092SGreg Clayton         process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name).get();
17730fdc8d8SChris Lattner 
178a7015092SGreg Clayton         if (process == NULL)
1793df9a8dfSCaroline Tice         {
18043a8c39bSCaroline Tice             result.AppendErrorWithFormat ("Failed to find a process plugin for executable.\n");
181a7015092SGreg Clayton             result.SetStatus (eReturnStatusFailed);
182a7015092SGreg Clayton             return false;
1833df9a8dfSCaroline Tice         }
1843df9a8dfSCaroline Tice 
185a7015092SGreg Clayton         // If no launch args were given on the command line, then use any that
186a7015092SGreg Clayton         // might have been set using the "run-args" set variable.
18730fdc8d8SChris Lattner         if (launch_args.GetArgumentCount() == 0)
18830fdc8d8SChris Lattner         {
189a7015092SGreg Clayton             if (process->GetRunArguments().GetArgumentCount() > 0)
190a7015092SGreg Clayton                 launch_args = process->GetRunArguments();
19130fdc8d8SChris Lattner         }
19230fdc8d8SChris Lattner 
19319388cfcSGreg Clayton         if (m_options.in_new_tty)
19419388cfcSGreg Clayton         {
19519388cfcSGreg Clayton             char exec_file_path[PATH_MAX];
19619388cfcSGreg Clayton             if (exe_module->GetFileSpec().GetPath(exec_file_path, sizeof(exec_file_path)))
19719388cfcSGreg Clayton             {
19819388cfcSGreg Clayton                 launch_args.InsertArgumentAtIndex(0, exec_file_path);
19919388cfcSGreg Clayton             }
20019388cfcSGreg Clayton             else
20119388cfcSGreg Clayton             {
20219388cfcSGreg Clayton                 result.AppendError("invalid executable");
20319388cfcSGreg Clayton                 result.SetStatus (eReturnStatusFailed);
20419388cfcSGreg Clayton                 return false;
20519388cfcSGreg Clayton             }
20619388cfcSGreg Clayton         }
20719388cfcSGreg Clayton 
208a7015092SGreg Clayton         Args environment;
20930fdc8d8SChris Lattner 
210a7015092SGreg Clayton         process->GetEnvironmentAsArgs (environment);
211a7015092SGreg Clayton 
212a7015092SGreg Clayton         uint32_t launch_flags = eLaunchFlagNone;
213a7015092SGreg Clayton 
214a7015092SGreg Clayton         if (process->GetDisableASLR())
215a7015092SGreg Clayton             launch_flags |= eLaunchFlagDisableASLR;
216a7015092SGreg Clayton 
21719388cfcSGreg Clayton         const char **inferior_argv = launch_args.GetArgumentCount() ? launch_args.GetConstArgumentVector() : NULL;
21819388cfcSGreg Clayton         const char **inferior_envp = environment.GetArgumentCount() ? environment.GetConstArgumentVector() : NULL;
21930fdc8d8SChris Lattner 
22019388cfcSGreg Clayton         Error error;
22119388cfcSGreg Clayton 
22219388cfcSGreg Clayton         if (m_options.in_new_tty)
22319388cfcSGreg Clayton         {
22419388cfcSGreg Clayton 
225913c4fa1SGreg Clayton             lldb::pid_t pid = Host::LaunchInNewTerminal (m_options.tty_name.c_str(),
226913c4fa1SGreg Clayton                                                          inferior_argv,
22719388cfcSGreg Clayton                                                          inferior_envp,
22819388cfcSGreg Clayton                                                          &exe_module->GetArchitecture(),
22919388cfcSGreg Clayton                                                          true,
23019388cfcSGreg Clayton                                                          process->GetDisableASLR());
23119388cfcSGreg Clayton 
2323fcbed6bSGreg Clayton             if (pid != LLDB_INVALID_PROCESS_ID)
2333fcbed6bSGreg Clayton                 error = process->Attach (pid);
23419388cfcSGreg Clayton         }
23519388cfcSGreg Clayton         else
23619388cfcSGreg Clayton         {
23730fdc8d8SChris Lattner             const char * stdin_path = NULL;
23830fdc8d8SChris Lattner             const char * stdout_path = NULL;
23930fdc8d8SChris Lattner             const char * stderr_path = NULL;
24030fdc8d8SChris Lattner 
241a7015092SGreg Clayton             // Were any standard input/output/error paths given on the command line?
242a7015092SGreg Clayton             if (m_options.stdin_path.empty() &&
24330fdc8d8SChris Lattner                 m_options.stdout_path.empty() &&
244a7015092SGreg Clayton                 m_options.stderr_path.empty())
24530fdc8d8SChris Lattner             {
246a7015092SGreg Clayton                 // No standard file handles were given on the command line, check
247a7015092SGreg Clayton                 // with the process object in case they were give using "set settings"
248a7015092SGreg Clayton                 stdin_path = process->GetStandardInputPath();
249a7015092SGreg Clayton                 stdout_path = process->GetStandardOutputPath();
250a7015092SGreg Clayton                 stderr_path = process->GetStandardErrorPath();
251a7015092SGreg Clayton             }
252a7015092SGreg Clayton             else
253a7015092SGreg Clayton             {
254a7015092SGreg Clayton                 stdin_path = m_options.stdin_path.empty()  ? NULL : m_options.stdin_path.c_str();
255a7015092SGreg Clayton                 stdout_path = m_options.stdout_path.empty() ? NULL : m_options.stdout_path.c_str();
256a7015092SGreg Clayton                 stderr_path = m_options.stderr_path.empty() ? NULL : m_options.stderr_path.c_str();
25730fdc8d8SChris Lattner             }
25830fdc8d8SChris Lattner 
259a7015092SGreg Clayton             if (stdin_path == NULL)
260a7015092SGreg Clayton                 stdin_path = "/dev/null";
261a7015092SGreg Clayton             if (stdout_path == NULL)
262a7015092SGreg Clayton                 stdout_path = "/dev/null";
263a7015092SGreg Clayton             if (stderr_path == NULL)
264a7015092SGreg Clayton                 stderr_path = "/dev/null";
265a7015092SGreg Clayton 
26619388cfcSGreg Clayton             error = process->Launch (inferior_argv,
26719388cfcSGreg Clayton                                      inferior_envp,
268f681b94fSGreg Clayton                                      launch_flags,
26930fdc8d8SChris Lattner                                      stdin_path,
27030fdc8d8SChris Lattner                                      stdout_path,
27119388cfcSGreg Clayton                                      stderr_path);
27219388cfcSGreg Clayton         }
27330fdc8d8SChris Lattner 
27430fdc8d8SChris Lattner         if (error.Success())
27530fdc8d8SChris Lattner         {
27619388cfcSGreg Clayton             const char *archname = exe_module->GetArchitecture().AsCString();
27719388cfcSGreg Clayton 
27819388cfcSGreg Clayton             result.AppendMessageWithFormat ("Process %i launched: '%s' (%s)\n", process->GetID(), filename, archname);
27905faeb71SGreg Clayton             result.SetDidChangeProcessState (true);
28030fdc8d8SChris Lattner             if (m_options.stop_at_entry == false)
28130fdc8d8SChris Lattner             {
28205faeb71SGreg Clayton                 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
28330fdc8d8SChris Lattner                 StateType state = process->WaitForProcessToStop (NULL);
28430fdc8d8SChris Lattner 
28530fdc8d8SChris Lattner                 if (state == eStateStopped)
28630fdc8d8SChris Lattner                 {
28705faeb71SGreg Clayton                     error = process->Resume();
28805faeb71SGreg Clayton                     if (error.Success())
28905faeb71SGreg Clayton                     {
29005faeb71SGreg Clayton                         bool synchronous_execution = m_interpreter.GetSynchronous ();
29130fdc8d8SChris Lattner                         if (synchronous_execution)
29230fdc8d8SChris Lattner                         {
29305faeb71SGreg Clayton                             state = process->WaitForProcessToStop (NULL);
29430fdc8d8SChris Lattner                             result.SetDidChangeProcessState (true);
29505faeb71SGreg Clayton                             result.SetStatus (eReturnStatusSuccessFinishResult);
29605faeb71SGreg Clayton                         }
29705faeb71SGreg Clayton                         else
29805faeb71SGreg Clayton                         {
29905faeb71SGreg Clayton                             result.SetStatus (eReturnStatusSuccessContinuingNoResult);
30005faeb71SGreg Clayton                         }
30105faeb71SGreg Clayton                     }
30230fdc8d8SChris Lattner                 }
30330fdc8d8SChris Lattner             }
30430fdc8d8SChris Lattner         }
30530fdc8d8SChris Lattner 
30630fdc8d8SChris Lattner         return result.Succeeded();
30730fdc8d8SChris Lattner     }
30830fdc8d8SChris Lattner 
309ebc09c36SJim Ingham     virtual const char *GetRepeatCommand (Args &current_command_args, uint32_t index)
310ebc09c36SJim Ingham     {
311ebc09c36SJim Ingham         // No repeat for "process launch"...
312ebc09c36SJim Ingham         return "";
313ebc09c36SJim Ingham     }
314ebc09c36SJim Ingham 
31530fdc8d8SChris Lattner protected:
31630fdc8d8SChris Lattner 
31730fdc8d8SChris Lattner     CommandOptions m_options;
31830fdc8d8SChris Lattner };
31930fdc8d8SChris Lattner 
32030fdc8d8SChris Lattner 
32119388cfcSGreg Clayton #define SET1 LLDB_OPT_SET_1
32219388cfcSGreg Clayton #define SET2 LLDB_OPT_SET_2
32319388cfcSGreg Clayton 
32430fdc8d8SChris Lattner lldb::OptionDefinition
32530fdc8d8SChris Lattner CommandObjectProcessLaunch::CommandOptions::g_option_table[] =
32630fdc8d8SChris Lattner {
32719388cfcSGreg Clayton { SET1 | SET2, false, "stop-at-entry", 's', no_argument,       NULL, 0, eArgTypeNone,    "Stop at the entry point of the program when launching a process."},
32819388cfcSGreg Clayton { SET1       , false, "stdin",         'i', required_argument, NULL, 0, eArgTypePath,    "Redirect stdin for the process to <path>."},
32919388cfcSGreg Clayton { SET1       , false, "stdout",        'o', required_argument, NULL, 0, eArgTypePath,    "Redirect stdout for the process to <path>."},
33019388cfcSGreg Clayton { SET1       , false, "stderr",        'e', required_argument, NULL, 0, eArgTypePath,    "Redirect stderr for the process to <path>."},
33119388cfcSGreg Clayton { SET1 | SET2, false, "plugin",        'p', required_argument, NULL, 0, eArgTypePlugin,  "Name of the process plugin you want to use."},
332913c4fa1SGreg 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."},
333deaab222SCaroline Tice { 0,           false, NULL,             0,  0,                 NULL, 0, eArgTypeNone,    NULL }
33430fdc8d8SChris Lattner };
33530fdc8d8SChris Lattner 
33619388cfcSGreg Clayton #undef SET1
33719388cfcSGreg Clayton #undef SET2
33830fdc8d8SChris Lattner 
33930fdc8d8SChris Lattner //-------------------------------------------------------------------------
34030fdc8d8SChris Lattner // CommandObjectProcessAttach
34130fdc8d8SChris Lattner //-------------------------------------------------------------------------
34230fdc8d8SChris Lattner 
34330fdc8d8SChris Lattner class CommandObjectProcessAttach : public CommandObject
34430fdc8d8SChris Lattner {
34530fdc8d8SChris Lattner public:
34630fdc8d8SChris Lattner 
34730fdc8d8SChris Lattner     class CommandOptions : public Options
34830fdc8d8SChris Lattner     {
34930fdc8d8SChris Lattner     public:
35030fdc8d8SChris Lattner 
35130fdc8d8SChris Lattner         CommandOptions () :
35230fdc8d8SChris Lattner             Options()
35330fdc8d8SChris Lattner         {
35430fdc8d8SChris Lattner             // Keep default values of all options in one place: ResetOptionValues ()
35530fdc8d8SChris Lattner             ResetOptionValues ();
35630fdc8d8SChris Lattner         }
35730fdc8d8SChris Lattner 
35830fdc8d8SChris Lattner         ~CommandOptions ()
35930fdc8d8SChris Lattner         {
36030fdc8d8SChris Lattner         }
36130fdc8d8SChris Lattner 
36230fdc8d8SChris Lattner         Error
36330fdc8d8SChris Lattner         SetOptionValue (int option_idx, const char *option_arg)
36430fdc8d8SChris Lattner         {
36530fdc8d8SChris Lattner             Error error;
36630fdc8d8SChris Lattner             char short_option = (char) m_getopt_table[option_idx].val;
36730fdc8d8SChris Lattner             bool success = false;
36830fdc8d8SChris Lattner             switch (short_option)
36930fdc8d8SChris Lattner             {
37030fdc8d8SChris Lattner                 case 'p':
37130fdc8d8SChris Lattner                     pid = Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success);
37230fdc8d8SChris Lattner                     if (!success || pid == LLDB_INVALID_PROCESS_ID)
37330fdc8d8SChris Lattner                     {
37430fdc8d8SChris Lattner                         error.SetErrorStringWithFormat("Invalid process ID '%s'.\n", option_arg);
37530fdc8d8SChris Lattner                     }
37630fdc8d8SChris Lattner                     break;
37730fdc8d8SChris Lattner 
37830fdc8d8SChris Lattner                 case 'P':
37930fdc8d8SChris Lattner                     plugin_name = option_arg;
38030fdc8d8SChris Lattner                     break;
38130fdc8d8SChris Lattner 
38230fdc8d8SChris Lattner                 case 'n':
38330fdc8d8SChris Lattner                     name.assign(option_arg);
38430fdc8d8SChris Lattner                     break;
38530fdc8d8SChris Lattner 
38630fdc8d8SChris Lattner                 case 'w':
38730fdc8d8SChris Lattner                     waitfor = true;
38830fdc8d8SChris Lattner                     break;
38930fdc8d8SChris Lattner 
39030fdc8d8SChris Lattner                 default:
39130fdc8d8SChris Lattner                     error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
39230fdc8d8SChris Lattner                     break;
39330fdc8d8SChris Lattner             }
39430fdc8d8SChris Lattner             return error;
39530fdc8d8SChris Lattner         }
39630fdc8d8SChris Lattner 
39730fdc8d8SChris Lattner         void
39830fdc8d8SChris Lattner         ResetOptionValues ()
39930fdc8d8SChris Lattner         {
40030fdc8d8SChris Lattner             Options::ResetOptionValues();
40130fdc8d8SChris Lattner             pid = LLDB_INVALID_PROCESS_ID;
40230fdc8d8SChris Lattner             name.clear();
40330fdc8d8SChris Lattner             waitfor = false;
40430fdc8d8SChris Lattner         }
40530fdc8d8SChris Lattner 
40630fdc8d8SChris Lattner         const lldb::OptionDefinition*
40730fdc8d8SChris Lattner         GetDefinitions ()
40830fdc8d8SChris Lattner         {
40930fdc8d8SChris Lattner             return g_option_table;
41030fdc8d8SChris Lattner         }
41130fdc8d8SChris Lattner 
4125aee162fSJim Ingham         virtual bool
413a7015092SGreg Clayton         HandleOptionArgumentCompletion (CommandInterpreter &interpeter,
4145aee162fSJim Ingham                                         Args &input,
4155aee162fSJim Ingham                                         int cursor_index,
4165aee162fSJim Ingham                                         int char_pos,
4175aee162fSJim Ingham                                         OptionElementVector &opt_element_vector,
4185aee162fSJim Ingham                                         int opt_element_index,
4195aee162fSJim Ingham                                         int match_start_point,
4205aee162fSJim Ingham                                         int max_return_elements,
4215aee162fSJim Ingham                                         bool &word_complete,
4225aee162fSJim Ingham                                         StringList &matches)
4235aee162fSJim Ingham         {
4245aee162fSJim Ingham             int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
4255aee162fSJim Ingham             int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
4265aee162fSJim Ingham 
4275aee162fSJim Ingham             // We are only completing the name option for now...
4285aee162fSJim Ingham 
4295aee162fSJim Ingham             const lldb::OptionDefinition *opt_defs = GetDefinitions();
4305aee162fSJim Ingham             if (opt_defs[opt_defs_index].short_option == 'n')
4315aee162fSJim Ingham             {
4325aee162fSJim Ingham                 // Are we in the name?
4335aee162fSJim Ingham 
4345aee162fSJim Ingham                 // Look to see if there is a -P argument provided, and if so use that plugin, otherwise
4355aee162fSJim Ingham                 // use the default plugin.
436a7015092SGreg Clayton                 Process *process = interpeter.GetDebugger().GetExecutionContext().process;
4375aee162fSJim Ingham                 bool need_to_delete_process = false;
4385aee162fSJim Ingham 
4395aee162fSJim Ingham                 const char *partial_name = NULL;
4405aee162fSJim Ingham                 partial_name = input.GetArgumentAtIndex(opt_arg_pos);
4415aee162fSJim Ingham 
4425aee162fSJim Ingham                 if (process && process->IsAlive())
4435aee162fSJim Ingham                     return true;
4445aee162fSJim Ingham 
445a7015092SGreg Clayton                 Target *target = interpeter.GetDebugger().GetSelectedTarget().get();
4465aee162fSJim Ingham                 if (target == NULL)
4475aee162fSJim Ingham                 {
4485aee162fSJim Ingham                     // No target has been set yet, for now do host completion.  Otherwise I don't know how we would
4495aee162fSJim Ingham                     // figure out what the right target to use is...
4505aee162fSJim Ingham                     std::vector<lldb::pid_t> pids;
4515aee162fSJim Ingham                     Host::ListProcessesMatchingName (partial_name, matches, pids);
4525aee162fSJim Ingham                     return true;
4535aee162fSJim Ingham                 }
4545aee162fSJim Ingham                 if (!process)
4555aee162fSJim Ingham                 {
456a7015092SGreg Clayton                     process = target->CreateProcess (interpeter.GetDebugger().GetListener(), partial_name).get();
4575aee162fSJim Ingham                     need_to_delete_process = true;
4585aee162fSJim Ingham                 }
4595aee162fSJim Ingham 
4605aee162fSJim Ingham                 if (process)
4615aee162fSJim Ingham                 {
4625aee162fSJim Ingham                     matches.Clear();
4635aee162fSJim Ingham                     std::vector<lldb::pid_t> pids;
4645aee162fSJim Ingham                     process->ListProcessesMatchingName (NULL, matches, pids);
4655aee162fSJim Ingham                     if (need_to_delete_process)
4665aee162fSJim Ingham                         target->DeleteCurrentProcess();
4675aee162fSJim Ingham                     return true;
4685aee162fSJim Ingham                 }
4695aee162fSJim Ingham             }
4705aee162fSJim Ingham 
4715aee162fSJim Ingham             return false;
4725aee162fSJim Ingham         }
4735aee162fSJim Ingham 
47430fdc8d8SChris Lattner         // Options table: Required for subclasses of Options.
47530fdc8d8SChris Lattner 
47630fdc8d8SChris Lattner         static lldb::OptionDefinition g_option_table[];
47730fdc8d8SChris Lattner 
47830fdc8d8SChris Lattner         // Instance variables to hold the values for command options.
47930fdc8d8SChris Lattner 
48030fdc8d8SChris Lattner         lldb::pid_t pid;
48130fdc8d8SChris Lattner         std::string plugin_name;
48230fdc8d8SChris Lattner         std::string name;
48330fdc8d8SChris Lattner         bool waitfor;
48430fdc8d8SChris Lattner     };
48530fdc8d8SChris Lattner 
486a7015092SGreg Clayton     CommandObjectProcessAttach (CommandInterpreter &interpreter) :
487a7015092SGreg Clayton         CommandObject (interpreter,
488a7015092SGreg Clayton                        "process attach",
489e3d26315SCaroline Tice                        "Attach to a process.",
4905aee162fSJim Ingham                        "process attach <cmd-options>")
4915aee162fSJim Ingham     {
4925aee162fSJim Ingham     }
4935aee162fSJim Ingham 
4945aee162fSJim Ingham     ~CommandObjectProcessAttach ()
4955aee162fSJim Ingham     {
4965aee162fSJim Ingham     }
4975aee162fSJim Ingham 
4985aee162fSJim Ingham     bool
499a7015092SGreg Clayton     Execute (Args& command,
5005aee162fSJim Ingham              CommandReturnObject &result)
5015aee162fSJim Ingham     {
502a7015092SGreg Clayton         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
5035aee162fSJim Ingham 
504a7015092SGreg Clayton         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
5055aee162fSJim Ingham         if (process)
5065aee162fSJim Ingham         {
5075aee162fSJim Ingham             if (process->IsAlive())
5085aee162fSJim Ingham             {
5095aee162fSJim Ingham                 result.AppendErrorWithFormat ("Process %u is currently being debugged, kill the process before attaching.\n",
5105aee162fSJim Ingham                                               process->GetID());
5115aee162fSJim Ingham                 result.SetStatus (eReturnStatusFailed);
5125aee162fSJim Ingham                 return false;
5135aee162fSJim Ingham             }
5145aee162fSJim Ingham         }
5155aee162fSJim Ingham 
5165aee162fSJim Ingham         if (target == NULL)
5175aee162fSJim Ingham         {
5185aee162fSJim Ingham             // If there isn't a current target create one.
5195aee162fSJim Ingham             TargetSP new_target_sp;
5205aee162fSJim Ingham             FileSpec emptyFileSpec;
5215aee162fSJim Ingham             ArchSpec emptyArchSpec;
5225aee162fSJim Ingham             Error error;
5235aee162fSJim Ingham 
524a7015092SGreg Clayton             error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(),
5255aee162fSJim Ingham                                                                               emptyFileSpec,
5265aee162fSJim Ingham                                                                               emptyArchSpec,
5275aee162fSJim Ingham                                                                               NULL,
5285aee162fSJim Ingham                                                                               false,
5295aee162fSJim Ingham                                                                               new_target_sp);
5305aee162fSJim Ingham             target = new_target_sp.get();
5315aee162fSJim Ingham             if (target == NULL || error.Fail())
5325aee162fSJim Ingham             {
5335aee162fSJim Ingham                 result.AppendError(error.AsCString("Error creating empty target"));
5345aee162fSJim Ingham                 return false;
5355aee162fSJim Ingham             }
536a7015092SGreg Clayton             m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target);
5375aee162fSJim Ingham         }
5385aee162fSJim Ingham 
5395aee162fSJim Ingham         // Record the old executable module, we want to issue a warning if the process of attaching changed the
5405aee162fSJim Ingham         // current executable (like somebody said "file foo" then attached to a PID whose executable was bar.)
5415aee162fSJim Ingham 
5425aee162fSJim Ingham         ModuleSP old_exec_module_sp = target->GetExecutableModule();
5435aee162fSJim Ingham         ArchSpec old_arch_spec = target->GetArchitecture();
5445aee162fSJim Ingham 
5455aee162fSJim Ingham         if (command.GetArgumentCount())
5465aee162fSJim Ingham         {
5475aee162fSJim Ingham             result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: \n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
5485aee162fSJim Ingham             result.SetStatus (eReturnStatusFailed);
5495aee162fSJim Ingham         }
5505aee162fSJim Ingham         else
5515aee162fSJim Ingham         {
5525aee162fSJim Ingham             const char *plugin_name = NULL;
5535aee162fSJim Ingham 
5545aee162fSJim Ingham             if (!m_options.plugin_name.empty())
5555aee162fSJim Ingham                 plugin_name = m_options.plugin_name.c_str();
5565aee162fSJim Ingham 
557a7015092SGreg Clayton             process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name).get();
5585aee162fSJim Ingham 
5595aee162fSJim Ingham             if (process)
5605aee162fSJim Ingham             {
5615aee162fSJim Ingham                 Error error;
5625aee162fSJim Ingham                 int attach_pid = m_options.pid;
5635aee162fSJim Ingham 
5643a0b9cdfSJim Ingham                 const char *wait_name = NULL;
5653a0b9cdfSJim Ingham 
5665aee162fSJim Ingham                 if (m_options.name.empty())
5675aee162fSJim Ingham                 {
5683a0b9cdfSJim Ingham                     if (old_exec_module_sp)
5693a0b9cdfSJim Ingham                     {
5703a0b9cdfSJim Ingham                         wait_name = old_exec_module_sp->GetFileSpec().GetFilename().AsCString();
5713a0b9cdfSJim Ingham                     }
5725aee162fSJim Ingham                 }
5735aee162fSJim Ingham                 else
5745aee162fSJim Ingham                 {
5753a0b9cdfSJim Ingham                     wait_name = m_options.name.c_str();
5763a0b9cdfSJim Ingham                 }
5773a0b9cdfSJim Ingham 
5783a0b9cdfSJim Ingham                 // If we are waiting for a process with this name to show up, do that first.
5793a0b9cdfSJim Ingham                 if (m_options.waitfor)
5803a0b9cdfSJim Ingham                 {
5813a0b9cdfSJim Ingham 
5823a0b9cdfSJim Ingham                     if (wait_name == NULL)
5833a0b9cdfSJim Ingham                     {
5843a0b9cdfSJim Ingham                         result.AppendError("Invalid arguments: must have a file loaded or supply a process name with the waitfor option.\n");
5853a0b9cdfSJim Ingham                         result.SetStatus (eReturnStatusFailed);
5863a0b9cdfSJim Ingham                         return false;
5873a0b9cdfSJim Ingham                     }
5883a0b9cdfSJim Ingham 
589a7015092SGreg Clayton                     m_interpreter.GetDebugger().GetOutputStream().Printf("Waiting to attach to a process named \"%s\".\n", wait_name);
5903a0b9cdfSJim Ingham                     error = process->Attach (wait_name, m_options.waitfor);
5915aee162fSJim Ingham                     if (error.Success())
5925aee162fSJim Ingham                     {
5935aee162fSJim Ingham                         result.SetStatus (eReturnStatusSuccessContinuingNoResult);
5945aee162fSJim Ingham                     }
5955aee162fSJim Ingham                     else
5965aee162fSJim Ingham                     {
5975aee162fSJim Ingham                         result.AppendErrorWithFormat ("Waiting for a process to launch named '%s': %s\n",
5983a0b9cdfSJim Ingham                                                          wait_name,
5995aee162fSJim Ingham                                                          error.AsCString());
6005aee162fSJim Ingham                         result.SetStatus (eReturnStatusFailed);
6015aee162fSJim Ingham                         return false;
6025aee162fSJim Ingham                     }
6035aee162fSJim Ingham                 }
6045aee162fSJim Ingham                 else
6055aee162fSJim Ingham                 {
6065aee162fSJim Ingham                     // If the process was specified by name look it up, so we can warn if there are multiple
6075aee162fSJim Ingham                     // processes with this pid.
6085aee162fSJim Ingham 
6093a0b9cdfSJim Ingham                     if (attach_pid == LLDB_INVALID_PROCESS_ID && wait_name != NULL)
6105aee162fSJim Ingham                     {
6115aee162fSJim Ingham                         std::vector<lldb::pid_t> pids;
6125aee162fSJim Ingham                         StringList matches;
6135aee162fSJim Ingham 
6143a0b9cdfSJim Ingham                         process->ListProcessesMatchingName(wait_name, matches, pids);
6155aee162fSJim Ingham                         if (matches.GetSize() > 1)
6165aee162fSJim Ingham                         {
6173a0b9cdfSJim Ingham                             result.AppendErrorWithFormat("More than one process named %s\n", wait_name);
6185aee162fSJim Ingham                             result.SetStatus (eReturnStatusFailed);
6195aee162fSJim Ingham                             return false;
6205aee162fSJim Ingham                         }
6215aee162fSJim Ingham                         else if (matches.GetSize() == 0)
6225aee162fSJim Ingham                         {
6233a0b9cdfSJim Ingham                             result.AppendErrorWithFormat("Could not find a process named %s\n", wait_name);
6245aee162fSJim Ingham                             result.SetStatus (eReturnStatusFailed);
6255aee162fSJim Ingham                             return false;
6265aee162fSJim Ingham                         }
6275aee162fSJim Ingham                         else
6285aee162fSJim Ingham                         {
6295aee162fSJim Ingham                             attach_pid = pids[0];
6305aee162fSJim Ingham                         }
6315aee162fSJim Ingham 
6325aee162fSJim Ingham                     }
6335aee162fSJim Ingham 
6345aee162fSJim Ingham                     if (attach_pid != LLDB_INVALID_PROCESS_ID)
6355aee162fSJim Ingham                     {
6365aee162fSJim Ingham                         error = process->Attach (attach_pid);
6375aee162fSJim Ingham                         if (error.Success())
6385aee162fSJim Ingham                         {
6395aee162fSJim Ingham                             result.SetStatus (eReturnStatusSuccessContinuingNoResult);
6405aee162fSJim Ingham                         }
6415aee162fSJim Ingham                         else
6425aee162fSJim Ingham                         {
6435aee162fSJim Ingham                             result.AppendErrorWithFormat ("Attaching to process %i failed: %s.\n",
6445aee162fSJim Ingham                                                          attach_pid,
6455aee162fSJim Ingham                                                          error.AsCString());
6465aee162fSJim Ingham                             result.SetStatus (eReturnStatusFailed);
6475aee162fSJim Ingham                         }
6485aee162fSJim Ingham                     }
6495aee162fSJim Ingham                     else
6505aee162fSJim Ingham                     {
6515aee162fSJim Ingham                         result.AppendErrorWithFormat ("No PID specified for attach\n",
6525aee162fSJim Ingham                                                          attach_pid,
6535aee162fSJim Ingham                                                          error.AsCString());
6545aee162fSJim Ingham                         result.SetStatus (eReturnStatusFailed);
6555aee162fSJim Ingham 
6565aee162fSJim Ingham                     }
6575aee162fSJim Ingham                 }
6585aee162fSJim Ingham             }
6595aee162fSJim Ingham         }
6605aee162fSJim Ingham 
6615aee162fSJim Ingham         if (result.Succeeded())
6625aee162fSJim Ingham         {
6635aee162fSJim Ingham             // Okay, we're done.  Last step is to warn if the executable module has changed:
6645aee162fSJim Ingham             if (!old_exec_module_sp)
6655aee162fSJim Ingham             {
6665aee162fSJim Ingham                 char new_path[PATH_MAX + 1];
6675aee162fSJim Ingham                 target->GetExecutableModule()->GetFileSpec().GetPath(new_path, PATH_MAX);
6685aee162fSJim Ingham 
6695aee162fSJim Ingham                 result.AppendMessageWithFormat("Executable module set to \"%s\".\n",
6705aee162fSJim Ingham                     new_path);
6715aee162fSJim Ingham             }
6725aee162fSJim Ingham             else if (old_exec_module_sp->GetFileSpec() != target->GetExecutableModule()->GetFileSpec())
6735aee162fSJim Ingham             {
6745aee162fSJim Ingham                 char old_path[PATH_MAX + 1];
6755aee162fSJim Ingham                 char new_path[PATH_MAX + 1];
6765aee162fSJim Ingham 
6775aee162fSJim Ingham                 old_exec_module_sp->GetFileSpec().GetPath(old_path, PATH_MAX);
6785aee162fSJim Ingham                 target->GetExecutableModule()->GetFileSpec().GetPath (new_path, PATH_MAX);
6795aee162fSJim Ingham 
6805aee162fSJim Ingham                 result.AppendWarningWithFormat("Executable module changed from \"%s\" to \"%s\".\n",
6815aee162fSJim Ingham                                                     old_path, new_path);
6825aee162fSJim Ingham             }
6835aee162fSJim Ingham 
6845aee162fSJim Ingham             if (!old_arch_spec.IsValid())
6855aee162fSJim Ingham             {
6865aee162fSJim Ingham                 result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().AsCString());
6875aee162fSJim Ingham             }
6885aee162fSJim Ingham             else if (old_arch_spec != target->GetArchitecture())
6895aee162fSJim Ingham             {
6905aee162fSJim Ingham                 result.AppendWarningWithFormat("Architecture changed from %s to %s.\n",
6915aee162fSJim Ingham                                                 old_arch_spec.AsCString(), target->GetArchitecture().AsCString());
6925aee162fSJim Ingham             }
6935aee162fSJim Ingham         }
6945aee162fSJim Ingham         return result.Succeeded();
6955aee162fSJim Ingham     }
6965aee162fSJim Ingham 
6975aee162fSJim Ingham     Options *
6985aee162fSJim Ingham     GetOptions ()
6995aee162fSJim Ingham     {
7005aee162fSJim Ingham         return &m_options;
7015aee162fSJim Ingham     }
7025aee162fSJim Ingham 
70330fdc8d8SChris Lattner protected:
70430fdc8d8SChris Lattner 
70530fdc8d8SChris Lattner     CommandOptions m_options;
70630fdc8d8SChris Lattner };
70730fdc8d8SChris Lattner 
70830fdc8d8SChris Lattner 
70930fdc8d8SChris Lattner lldb::OptionDefinition
71030fdc8d8SChris Lattner CommandObjectProcessAttach::CommandOptions::g_option_table[] =
71130fdc8d8SChris Lattner {
712deaab222SCaroline Tice { LLDB_OPT_SET_ALL, false, "plugin", 'P', required_argument, NULL, 0, eArgTypePlugin,        "Name of the process plugin you want to use."},
713deaab222SCaroline Tice { LLDB_OPT_SET_1,   false, "pid",    'p', required_argument, NULL, 0, eArgTypePid,           "The process ID of an existing process to attach to."},
714deaab222SCaroline Tice { LLDB_OPT_SET_2,   false, "name",   'n', required_argument, NULL, 0, eArgTypeProcessName,  "The name of the process to attach to."},
715deaab222SCaroline Tice { LLDB_OPT_SET_2,   false, "waitfor",'w', no_argument,       NULL, 0, eArgTypeNone,              "Wait for the the process with <process-name> to launch."},
716deaab222SCaroline Tice { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
71730fdc8d8SChris Lattner };
71830fdc8d8SChris Lattner 
71930fdc8d8SChris Lattner //-------------------------------------------------------------------------
72030fdc8d8SChris Lattner // CommandObjectProcessContinue
72130fdc8d8SChris Lattner //-------------------------------------------------------------------------
72230fdc8d8SChris Lattner 
72330fdc8d8SChris Lattner class CommandObjectProcessContinue : public CommandObject
72430fdc8d8SChris Lattner {
72530fdc8d8SChris Lattner public:
72630fdc8d8SChris Lattner 
727a7015092SGreg Clayton     CommandObjectProcessContinue (CommandInterpreter &interpreter) :
728a7015092SGreg Clayton         CommandObject (interpreter,
729a7015092SGreg Clayton                        "process continue",
730e3d26315SCaroline Tice                        "Continue execution of all threads in the current process.",
73130fdc8d8SChris Lattner                        "process continue",
73230fdc8d8SChris Lattner                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
73330fdc8d8SChris Lattner     {
73430fdc8d8SChris Lattner     }
73530fdc8d8SChris Lattner 
73630fdc8d8SChris Lattner 
73730fdc8d8SChris Lattner     ~CommandObjectProcessContinue ()
73830fdc8d8SChris Lattner     {
73930fdc8d8SChris Lattner     }
74030fdc8d8SChris Lattner 
74130fdc8d8SChris Lattner     bool
742a7015092SGreg Clayton     Execute (Args& command,
74330fdc8d8SChris Lattner              CommandReturnObject &result)
74430fdc8d8SChris Lattner     {
745a7015092SGreg Clayton         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
746a7015092SGreg Clayton         bool synchronous_execution = m_interpreter.GetSynchronous ();
74730fdc8d8SChris Lattner 
74830fdc8d8SChris Lattner         if (process == NULL)
74930fdc8d8SChris Lattner         {
75030fdc8d8SChris Lattner             result.AppendError ("no process to continue");
75130fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
75230fdc8d8SChris Lattner             return false;
75330fdc8d8SChris Lattner          }
75430fdc8d8SChris Lattner 
75530fdc8d8SChris Lattner         StateType state = process->GetState();
75630fdc8d8SChris Lattner         if (state == eStateStopped)
75730fdc8d8SChris Lattner         {
75830fdc8d8SChris Lattner             if (command.GetArgumentCount() != 0)
75930fdc8d8SChris Lattner             {
76030fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("The '%s' command does not take any arguments.\n", m_cmd_name.c_str());
76130fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
76230fdc8d8SChris Lattner                 return false;
76330fdc8d8SChris Lattner             }
76430fdc8d8SChris Lattner 
76530fdc8d8SChris Lattner             const uint32_t num_threads = process->GetThreadList().GetSize();
76630fdc8d8SChris Lattner 
76730fdc8d8SChris Lattner             // Set the actions that the threads should each take when resuming
76830fdc8d8SChris Lattner             for (uint32_t idx=0; idx<num_threads; ++idx)
76930fdc8d8SChris Lattner             {
77030fdc8d8SChris Lattner                 process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState (eStateRunning);
77130fdc8d8SChris Lattner             }
77230fdc8d8SChris Lattner 
77330fdc8d8SChris Lattner             Error error(process->Resume());
77430fdc8d8SChris Lattner             if (error.Success())
77530fdc8d8SChris Lattner             {
77619388cfcSGreg Clayton                 result.AppendMessageWithFormat ("Process %i resuming\n", process->GetID());
77730fdc8d8SChris Lattner                 if (synchronous_execution)
77830fdc8d8SChris Lattner                 {
779b132097bSGreg Clayton                     state = process->WaitForProcessToStop (NULL);
78030fdc8d8SChris Lattner 
78130fdc8d8SChris Lattner                     result.SetDidChangeProcessState (true);
78230fdc8d8SChris Lattner                     result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state));
78330fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
78430fdc8d8SChris Lattner                 }
78530fdc8d8SChris Lattner                 else
78630fdc8d8SChris Lattner                 {
78730fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusSuccessContinuingNoResult);
78830fdc8d8SChris Lattner                 }
78930fdc8d8SChris Lattner             }
79030fdc8d8SChris Lattner             else
79130fdc8d8SChris Lattner             {
79230fdc8d8SChris Lattner                 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
79330fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
79430fdc8d8SChris Lattner             }
79530fdc8d8SChris Lattner         }
79630fdc8d8SChris Lattner         else
79730fdc8d8SChris Lattner         {
79830fdc8d8SChris Lattner             result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
79930fdc8d8SChris Lattner                                          StateAsCString(state));
80030fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
80130fdc8d8SChris Lattner         }
80230fdc8d8SChris Lattner         return result.Succeeded();
80330fdc8d8SChris Lattner     }
80430fdc8d8SChris Lattner };
80530fdc8d8SChris Lattner 
80630fdc8d8SChris Lattner //-------------------------------------------------------------------------
80730fdc8d8SChris Lattner // CommandObjectProcessDetach
80830fdc8d8SChris Lattner //-------------------------------------------------------------------------
80930fdc8d8SChris Lattner 
81030fdc8d8SChris Lattner class CommandObjectProcessDetach : public CommandObject
81130fdc8d8SChris Lattner {
81230fdc8d8SChris Lattner public:
81330fdc8d8SChris Lattner 
814a7015092SGreg Clayton     CommandObjectProcessDetach (CommandInterpreter &interpreter) :
815a7015092SGreg Clayton         CommandObject (interpreter,
816a7015092SGreg Clayton                        "process detach",
817e3d26315SCaroline Tice                        "Detach from the current process being debugged.",
81830fdc8d8SChris Lattner                        "process detach",
81930fdc8d8SChris Lattner                        eFlagProcessMustBeLaunched)
82030fdc8d8SChris Lattner     {
82130fdc8d8SChris Lattner     }
82230fdc8d8SChris Lattner 
82330fdc8d8SChris Lattner     ~CommandObjectProcessDetach ()
82430fdc8d8SChris Lattner     {
82530fdc8d8SChris Lattner     }
82630fdc8d8SChris Lattner 
82730fdc8d8SChris Lattner     bool
828a7015092SGreg Clayton     Execute (Args& command,
82930fdc8d8SChris Lattner              CommandReturnObject &result)
83030fdc8d8SChris Lattner     {
831a7015092SGreg Clayton         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
83230fdc8d8SChris Lattner         if (process == NULL)
83330fdc8d8SChris Lattner         {
83430fdc8d8SChris Lattner             result.AppendError ("must have a valid process in order to detach");
83530fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
83630fdc8d8SChris Lattner             return false;
83730fdc8d8SChris Lattner         }
83830fdc8d8SChris Lattner 
8395d7be2e6SCaroline Tice         result.AppendMessageWithFormat ("Detaching from process %i\n", process->GetID());
84030fdc8d8SChris Lattner         Error error (process->Detach());
84130fdc8d8SChris Lattner         if (error.Success())
84230fdc8d8SChris Lattner         {
84330fdc8d8SChris Lattner             result.SetStatus (eReturnStatusSuccessFinishResult);
84430fdc8d8SChris Lattner         }
84530fdc8d8SChris Lattner         else
84630fdc8d8SChris Lattner         {
84730fdc8d8SChris Lattner             result.AppendErrorWithFormat ("Detach failed: %s\n", error.AsCString());
84830fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
84930fdc8d8SChris Lattner             return false;
85030fdc8d8SChris Lattner         }
85130fdc8d8SChris Lattner         return result.Succeeded();
85230fdc8d8SChris Lattner     }
85330fdc8d8SChris Lattner };
85430fdc8d8SChris Lattner 
85530fdc8d8SChris Lattner //-------------------------------------------------------------------------
856*8f343b09SGreg Clayton // CommandObjectProcessLoad
857*8f343b09SGreg Clayton //-------------------------------------------------------------------------
858*8f343b09SGreg Clayton 
859*8f343b09SGreg Clayton class CommandObjectProcessLoad : public CommandObject
860*8f343b09SGreg Clayton {
861*8f343b09SGreg Clayton public:
862*8f343b09SGreg Clayton 
863*8f343b09SGreg Clayton     CommandObjectProcessLoad (CommandInterpreter &interpreter) :
864*8f343b09SGreg Clayton         CommandObject (interpreter,
865*8f343b09SGreg Clayton                        "process load",
866*8f343b09SGreg Clayton                        "Load a shared library into the current process.",
867*8f343b09SGreg Clayton                        "process load <filename> [<filename> ...]",
868*8f343b09SGreg Clayton                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
869*8f343b09SGreg Clayton     {
870*8f343b09SGreg Clayton     }
871*8f343b09SGreg Clayton 
872*8f343b09SGreg Clayton     ~CommandObjectProcessLoad ()
873*8f343b09SGreg Clayton     {
874*8f343b09SGreg Clayton     }
875*8f343b09SGreg Clayton 
876*8f343b09SGreg Clayton     bool
877*8f343b09SGreg Clayton     Execute (Args& command,
878*8f343b09SGreg Clayton              CommandReturnObject &result)
879*8f343b09SGreg Clayton     {
880*8f343b09SGreg Clayton         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
881*8f343b09SGreg Clayton         if (process == NULL)
882*8f343b09SGreg Clayton         {
883*8f343b09SGreg Clayton             result.AppendError ("must have a valid process in order to load a shared library");
884*8f343b09SGreg Clayton             result.SetStatus (eReturnStatusFailed);
885*8f343b09SGreg Clayton             return false;
886*8f343b09SGreg Clayton         }
887*8f343b09SGreg Clayton 
888*8f343b09SGreg Clayton         const uint32_t argc = command.GetArgumentCount();
889*8f343b09SGreg Clayton 
890*8f343b09SGreg Clayton         for (uint32_t i=0; i<argc; ++i)
891*8f343b09SGreg Clayton         {
892*8f343b09SGreg Clayton             Error error;
893*8f343b09SGreg Clayton             const char *image_path = command.GetArgumentAtIndex(i);
894*8f343b09SGreg Clayton             FileSpec image_spec (image_path, false);
895*8f343b09SGreg Clayton             uint32_t image_token = process->LoadImage(image_spec, error);
896*8f343b09SGreg Clayton             if (image_token != LLDB_INVALID_IMAGE_TOKEN)
897*8f343b09SGreg Clayton             {
898*8f343b09SGreg Clayton                 result.AppendMessageWithFormat ("Loading \"%s\"...ok\nImage %u loaded.\n", image_path, image_token);
899*8f343b09SGreg Clayton                 result.SetStatus (eReturnStatusSuccessFinishResult);
900*8f343b09SGreg Clayton             }
901*8f343b09SGreg Clayton             else
902*8f343b09SGreg Clayton             {
903*8f343b09SGreg Clayton                 result.AppendErrorWithFormat ("failed to load '%s': %s", image_path, error.AsCString());
904*8f343b09SGreg Clayton                 result.SetStatus (eReturnStatusFailed);
905*8f343b09SGreg Clayton             }
906*8f343b09SGreg Clayton         }
907*8f343b09SGreg Clayton         return result.Succeeded();
908*8f343b09SGreg Clayton     }
909*8f343b09SGreg Clayton };
910*8f343b09SGreg Clayton 
911*8f343b09SGreg Clayton 
912*8f343b09SGreg Clayton //-------------------------------------------------------------------------
913*8f343b09SGreg Clayton // CommandObjectProcessUnload
914*8f343b09SGreg Clayton //-------------------------------------------------------------------------
915*8f343b09SGreg Clayton 
916*8f343b09SGreg Clayton class CommandObjectProcessUnload : public CommandObject
917*8f343b09SGreg Clayton {
918*8f343b09SGreg Clayton public:
919*8f343b09SGreg Clayton 
920*8f343b09SGreg Clayton     CommandObjectProcessUnload (CommandInterpreter &interpreter) :
921*8f343b09SGreg Clayton         CommandObject (interpreter,
922*8f343b09SGreg Clayton                        "process unload",
923*8f343b09SGreg Clayton                        "Unload a shared library from the current process using the index returned by a previous call to \"process load\".",
924*8f343b09SGreg Clayton                        "process unload <index>",
925*8f343b09SGreg Clayton                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
926*8f343b09SGreg Clayton     {
927*8f343b09SGreg Clayton     }
928*8f343b09SGreg Clayton 
929*8f343b09SGreg Clayton     ~CommandObjectProcessUnload ()
930*8f343b09SGreg Clayton     {
931*8f343b09SGreg Clayton     }
932*8f343b09SGreg Clayton 
933*8f343b09SGreg Clayton     bool
934*8f343b09SGreg Clayton     Execute (Args& command,
935*8f343b09SGreg Clayton              CommandReturnObject &result)
936*8f343b09SGreg Clayton     {
937*8f343b09SGreg Clayton         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
938*8f343b09SGreg Clayton         if (process == NULL)
939*8f343b09SGreg Clayton         {
940*8f343b09SGreg Clayton             result.AppendError ("must have a valid process in order to load a shared library");
941*8f343b09SGreg Clayton             result.SetStatus (eReturnStatusFailed);
942*8f343b09SGreg Clayton             return false;
943*8f343b09SGreg Clayton         }
944*8f343b09SGreg Clayton 
945*8f343b09SGreg Clayton         const uint32_t argc = command.GetArgumentCount();
946*8f343b09SGreg Clayton 
947*8f343b09SGreg Clayton         for (uint32_t i=0; i<argc; ++i)
948*8f343b09SGreg Clayton         {
949*8f343b09SGreg Clayton             const char *image_token_cstr = command.GetArgumentAtIndex(i);
950*8f343b09SGreg Clayton             uint32_t image_token = Args::StringToUInt32(image_token_cstr, LLDB_INVALID_IMAGE_TOKEN, 0);
951*8f343b09SGreg Clayton             if (image_token == LLDB_INVALID_IMAGE_TOKEN)
952*8f343b09SGreg Clayton             {
953*8f343b09SGreg Clayton                 result.AppendErrorWithFormat ("invalid image index argument '%s'", image_token_cstr);
954*8f343b09SGreg Clayton                 result.SetStatus (eReturnStatusFailed);
955*8f343b09SGreg Clayton                 break;
956*8f343b09SGreg Clayton             }
957*8f343b09SGreg Clayton             else
958*8f343b09SGreg Clayton             {
959*8f343b09SGreg Clayton                 Error error (process->UnloadImage(image_token));
960*8f343b09SGreg Clayton                 if (error.Success())
961*8f343b09SGreg Clayton                 {
962*8f343b09SGreg Clayton                     result.AppendMessageWithFormat ("Unloading shared library with index %u...ok\n", image_token);
963*8f343b09SGreg Clayton                     result.SetStatus (eReturnStatusSuccessFinishResult);
964*8f343b09SGreg Clayton                 }
965*8f343b09SGreg Clayton                 else
966*8f343b09SGreg Clayton                 {
967*8f343b09SGreg Clayton                     result.AppendErrorWithFormat ("failed to unload image: %s", error.AsCString());
968*8f343b09SGreg Clayton                     result.SetStatus (eReturnStatusFailed);
969*8f343b09SGreg Clayton                     break;
970*8f343b09SGreg Clayton                 }
971*8f343b09SGreg Clayton             }
972*8f343b09SGreg Clayton         }
973*8f343b09SGreg Clayton         return result.Succeeded();
974*8f343b09SGreg Clayton     }
975*8f343b09SGreg Clayton };
976*8f343b09SGreg Clayton 
977*8f343b09SGreg Clayton //-------------------------------------------------------------------------
97830fdc8d8SChris Lattner // CommandObjectProcessSignal
97930fdc8d8SChris Lattner //-------------------------------------------------------------------------
98030fdc8d8SChris Lattner 
98130fdc8d8SChris Lattner class CommandObjectProcessSignal : public CommandObject
98230fdc8d8SChris Lattner {
98330fdc8d8SChris Lattner public:
98430fdc8d8SChris Lattner 
985a7015092SGreg Clayton     CommandObjectProcessSignal (CommandInterpreter &interpreter) :
986a7015092SGreg Clayton         CommandObject (interpreter,
987a7015092SGreg Clayton                        "process signal",
988e3d26315SCaroline Tice                        "Send a UNIX signal to the current process being debugged.",
989405fe67fSCaroline Tice                        NULL)
99030fdc8d8SChris Lattner     {
991405fe67fSCaroline Tice         CommandArgumentEntry arg;
992405fe67fSCaroline Tice         CommandArgumentData signal_arg;
993405fe67fSCaroline Tice 
994405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
995c0dbdfb6SCaroline Tice         signal_arg.arg_type = eArgTypeUnixSignal;
996405fe67fSCaroline Tice         signal_arg.arg_repetition = eArgRepeatPlain;
997405fe67fSCaroline Tice 
998405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
999405fe67fSCaroline Tice         arg.push_back (signal_arg);
1000405fe67fSCaroline Tice 
1001405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
1002405fe67fSCaroline Tice         m_arguments.push_back (arg);
100330fdc8d8SChris Lattner     }
100430fdc8d8SChris Lattner 
100530fdc8d8SChris Lattner     ~CommandObjectProcessSignal ()
100630fdc8d8SChris Lattner     {
100730fdc8d8SChris Lattner     }
100830fdc8d8SChris Lattner 
100930fdc8d8SChris Lattner     bool
1010a7015092SGreg Clayton     Execute (Args& command,
101130fdc8d8SChris Lattner              CommandReturnObject &result)
101230fdc8d8SChris Lattner     {
1013a7015092SGreg Clayton         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
101430fdc8d8SChris Lattner         if (process == NULL)
101530fdc8d8SChris Lattner         {
101630fdc8d8SChris Lattner             result.AppendError ("no process to signal");
101730fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
101830fdc8d8SChris Lattner             return false;
101930fdc8d8SChris Lattner         }
102030fdc8d8SChris Lattner 
102130fdc8d8SChris Lattner         if (command.GetArgumentCount() == 1)
102230fdc8d8SChris Lattner         {
1023237cd906SGreg Clayton             int signo = LLDB_INVALID_SIGNAL_NUMBER;
1024237cd906SGreg Clayton 
1025237cd906SGreg Clayton             const char *signal_name = command.GetArgumentAtIndex(0);
1026237cd906SGreg Clayton             if (::isxdigit (signal_name[0]))
1027237cd906SGreg Clayton                 signo = Args::StringToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0);
1028237cd906SGreg Clayton             else
1029237cd906SGreg Clayton                 signo = process->GetUnixSignals().GetSignalNumberFromName (signal_name);
1030237cd906SGreg Clayton 
1031237cd906SGreg Clayton             if (signo == LLDB_INVALID_SIGNAL_NUMBER)
103230fdc8d8SChris Lattner             {
103330fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("Invalid signal argument '%s'.\n", command.GetArgumentAtIndex(0));
103430fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
103530fdc8d8SChris Lattner             }
103630fdc8d8SChris Lattner             else
103730fdc8d8SChris Lattner             {
103830fdc8d8SChris Lattner                 Error error (process->Signal (signo));
103930fdc8d8SChris Lattner                 if (error.Success())
104030fdc8d8SChris Lattner                 {
104130fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusSuccessFinishResult);
104230fdc8d8SChris Lattner                 }
104330fdc8d8SChris Lattner                 else
104430fdc8d8SChris Lattner                 {
104530fdc8d8SChris Lattner                     result.AppendErrorWithFormat ("Failed to send signal %i: %s\n", signo, error.AsCString());
104630fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
104730fdc8d8SChris Lattner                 }
104830fdc8d8SChris Lattner             }
104930fdc8d8SChris Lattner         }
105030fdc8d8SChris Lattner         else
105130fdc8d8SChris Lattner         {
105230fdc8d8SChris Lattner             result.AppendErrorWithFormat("'%s' takes exactly one signal number argument:\nUsage: \n", m_cmd_name.c_str(),
105330fdc8d8SChris Lattner                                         m_cmd_syntax.c_str());
105430fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
105530fdc8d8SChris Lattner         }
105630fdc8d8SChris Lattner         return result.Succeeded();
105730fdc8d8SChris Lattner     }
105830fdc8d8SChris Lattner };
105930fdc8d8SChris Lattner 
106030fdc8d8SChris Lattner 
106130fdc8d8SChris Lattner //-------------------------------------------------------------------------
106230fdc8d8SChris Lattner // CommandObjectProcessInterrupt
106330fdc8d8SChris Lattner //-------------------------------------------------------------------------
106430fdc8d8SChris Lattner 
106530fdc8d8SChris Lattner class CommandObjectProcessInterrupt : public CommandObject
106630fdc8d8SChris Lattner {
106730fdc8d8SChris Lattner public:
106830fdc8d8SChris Lattner 
106930fdc8d8SChris Lattner 
1070a7015092SGreg Clayton     CommandObjectProcessInterrupt (CommandInterpreter &interpreter) :
1071a7015092SGreg Clayton     CommandObject (interpreter,
1072a7015092SGreg Clayton                    "process interrupt",
1073e3d26315SCaroline Tice                    "Interrupt the current process being debugged.",
107430fdc8d8SChris Lattner                    "process interrupt",
107530fdc8d8SChris Lattner                    eFlagProcessMustBeLaunched)
107630fdc8d8SChris Lattner     {
107730fdc8d8SChris Lattner     }
107830fdc8d8SChris Lattner 
107930fdc8d8SChris Lattner     ~CommandObjectProcessInterrupt ()
108030fdc8d8SChris Lattner     {
108130fdc8d8SChris Lattner     }
108230fdc8d8SChris Lattner 
108330fdc8d8SChris Lattner     bool
1084a7015092SGreg Clayton     Execute (Args& command,
108530fdc8d8SChris Lattner              CommandReturnObject &result)
108630fdc8d8SChris Lattner     {
1087a7015092SGreg Clayton         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
108830fdc8d8SChris Lattner         if (process == NULL)
108930fdc8d8SChris Lattner         {
109030fdc8d8SChris Lattner             result.AppendError ("no process to halt");
109130fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
109230fdc8d8SChris Lattner             return false;
109330fdc8d8SChris Lattner         }
109430fdc8d8SChris Lattner 
109530fdc8d8SChris Lattner         if (command.GetArgumentCount() == 0)
109630fdc8d8SChris Lattner         {
109730fdc8d8SChris Lattner             Error error(process->Halt ());
109830fdc8d8SChris Lattner             if (error.Success())
109930fdc8d8SChris Lattner             {
110030fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusSuccessFinishResult);
110130fdc8d8SChris Lattner 
110230fdc8d8SChris Lattner                 // Maybe we should add a "SuspendThreadPlans so we
110330fdc8d8SChris Lattner                 // can halt, and keep in place all the current thread plans.
110430fdc8d8SChris Lattner                 process->GetThreadList().DiscardThreadPlans();
110530fdc8d8SChris Lattner             }
110630fdc8d8SChris Lattner             else
110730fdc8d8SChris Lattner             {
110830fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("Failed to halt process: %s\n", error.AsCString());
110930fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
111030fdc8d8SChris Lattner             }
111130fdc8d8SChris Lattner         }
111230fdc8d8SChris Lattner         else
111330fdc8d8SChris Lattner         {
111430fdc8d8SChris Lattner             result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: \n",
111530fdc8d8SChris Lattner                                         m_cmd_name.c_str(),
111630fdc8d8SChris Lattner                                         m_cmd_syntax.c_str());
111730fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
111830fdc8d8SChris Lattner         }
111930fdc8d8SChris Lattner         return result.Succeeded();
112030fdc8d8SChris Lattner     }
112130fdc8d8SChris Lattner };
112230fdc8d8SChris Lattner 
112330fdc8d8SChris Lattner //-------------------------------------------------------------------------
112430fdc8d8SChris Lattner // CommandObjectProcessKill
112530fdc8d8SChris Lattner //-------------------------------------------------------------------------
112630fdc8d8SChris Lattner 
112730fdc8d8SChris Lattner class CommandObjectProcessKill : public CommandObject
112830fdc8d8SChris Lattner {
112930fdc8d8SChris Lattner public:
113030fdc8d8SChris Lattner 
1131a7015092SGreg Clayton     CommandObjectProcessKill (CommandInterpreter &interpreter) :
1132a7015092SGreg Clayton     CommandObject (interpreter,
1133a7015092SGreg Clayton                    "process kill",
1134e3d26315SCaroline Tice                    "Terminate the current process being debugged.",
113530fdc8d8SChris Lattner                    "process kill",
113630fdc8d8SChris Lattner                    eFlagProcessMustBeLaunched)
113730fdc8d8SChris Lattner     {
113830fdc8d8SChris Lattner     }
113930fdc8d8SChris Lattner 
114030fdc8d8SChris Lattner     ~CommandObjectProcessKill ()
114130fdc8d8SChris Lattner     {
114230fdc8d8SChris Lattner     }
114330fdc8d8SChris Lattner 
114430fdc8d8SChris Lattner     bool
1145a7015092SGreg Clayton     Execute (Args& command,
114630fdc8d8SChris Lattner              CommandReturnObject &result)
114730fdc8d8SChris Lattner     {
1148a7015092SGreg Clayton         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
114930fdc8d8SChris Lattner         if (process == NULL)
115030fdc8d8SChris Lattner         {
115130fdc8d8SChris Lattner             result.AppendError ("no process to kill");
115230fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
115330fdc8d8SChris Lattner             return false;
115430fdc8d8SChris Lattner         }
115530fdc8d8SChris Lattner 
115630fdc8d8SChris Lattner         if (command.GetArgumentCount() == 0)
115730fdc8d8SChris Lattner         {
115830fdc8d8SChris Lattner             Error error (process->Destroy());
115930fdc8d8SChris Lattner             if (error.Success())
116030fdc8d8SChris Lattner             {
116130fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusSuccessFinishResult);
116230fdc8d8SChris Lattner             }
116330fdc8d8SChris Lattner             else
116430fdc8d8SChris Lattner             {
116530fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString());
116630fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
116730fdc8d8SChris Lattner             }
116830fdc8d8SChris Lattner         }
116930fdc8d8SChris Lattner         else
117030fdc8d8SChris Lattner         {
117130fdc8d8SChris Lattner             result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: \n",
117230fdc8d8SChris Lattner                                         m_cmd_name.c_str(),
117330fdc8d8SChris Lattner                                         m_cmd_syntax.c_str());
117430fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
117530fdc8d8SChris Lattner         }
117630fdc8d8SChris Lattner         return result.Succeeded();
117730fdc8d8SChris Lattner     }
117830fdc8d8SChris Lattner };
117930fdc8d8SChris Lattner 
118030fdc8d8SChris Lattner //-------------------------------------------------------------------------
11814b9bea87SJim Ingham // CommandObjectProcessStatus
11824b9bea87SJim Ingham //-------------------------------------------------------------------------
11834b9bea87SJim Ingham class CommandObjectProcessStatus : public CommandObject
11844b9bea87SJim Ingham {
11854b9bea87SJim Ingham public:
1186a7015092SGreg Clayton     CommandObjectProcessStatus (CommandInterpreter &interpreter) :
1187a7015092SGreg Clayton     CommandObject (interpreter,
1188a7015092SGreg Clayton                    "process status",
1189e3d26315SCaroline Tice                    "Show the current status and location of executing process.",
1190e3d26315SCaroline Tice                    "process status",
11914b9bea87SJim Ingham                    0)
11924b9bea87SJim Ingham     {
11934b9bea87SJim Ingham     }
11944b9bea87SJim Ingham 
11954b9bea87SJim Ingham     ~CommandObjectProcessStatus()
11964b9bea87SJim Ingham     {
11974b9bea87SJim Ingham     }
11984b9bea87SJim Ingham 
11994b9bea87SJim Ingham 
12004b9bea87SJim Ingham     bool
12014b9bea87SJim Ingham     Execute
12024b9bea87SJim Ingham     (
12034b9bea87SJim Ingham         Args& command,
12044b9bea87SJim Ingham         CommandReturnObject &result
12054b9bea87SJim Ingham     )
12064b9bea87SJim Ingham     {
12074b9bea87SJim Ingham         StreamString &output_stream = result.GetOutputStream();
12084b9bea87SJim Ingham         result.SetStatus (eReturnStatusSuccessFinishNoResult);
1209a7015092SGreg Clayton         ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext());
12104b9bea87SJim Ingham         if (exe_ctx.process)
12114b9bea87SJim Ingham         {
12124b9bea87SJim Ingham             const StateType state = exe_ctx.process->GetState();
12134b9bea87SJim Ingham             if (StateIsStoppedState(state))
12144b9bea87SJim Ingham             {
12154b9bea87SJim Ingham                 if (state == eStateExited)
12164b9bea87SJim Ingham                 {
12174b9bea87SJim Ingham                     int exit_status = exe_ctx.process->GetExitStatus();
12184b9bea87SJim Ingham                     const char *exit_description = exe_ctx.process->GetExitDescription();
12194b9bea87SJim Ingham                     output_stream.Printf ("Process %d exited with status = %i (0x%8.8x) %s\n",
12204b9bea87SJim Ingham                                           exe_ctx.process->GetID(),
12214b9bea87SJim Ingham                                           exit_status,
12224b9bea87SJim Ingham                                           exit_status,
12234b9bea87SJim Ingham                                           exit_description ? exit_description : "");
12244b9bea87SJim Ingham                 }
12254b9bea87SJim Ingham                 else
12264b9bea87SJim Ingham                 {
12274b9bea87SJim Ingham                     output_stream.Printf ("Process %d %s\n", exe_ctx.process->GetID(), StateAsCString (state));
12284b9bea87SJim Ingham                     if (exe_ctx.thread == NULL)
12294b9bea87SJim Ingham                         exe_ctx.thread = exe_ctx.process->GetThreadList().GetThreadAtIndex(0).get();
12304b9bea87SJim Ingham                     if (exe_ctx.thread != NULL)
12314b9bea87SJim Ingham                     {
1232a7015092SGreg Clayton                         DisplayThreadsInfo (m_interpreter, &exe_ctx, result, true, true);
12334b9bea87SJim Ingham                     }
12344b9bea87SJim Ingham                     else
12354b9bea87SJim Ingham                     {
12364b9bea87SJim Ingham                         result.AppendError ("No valid thread found in current process.");
12374b9bea87SJim Ingham                         result.SetStatus (eReturnStatusFailed);
12384b9bea87SJim Ingham                     }
12394b9bea87SJim Ingham                 }
12404b9bea87SJim Ingham             }
12414b9bea87SJim Ingham             else
12424b9bea87SJim Ingham             {
12434b9bea87SJim Ingham                 output_stream.Printf ("Process %d is running.\n",
12444b9bea87SJim Ingham                                           exe_ctx.process->GetID());
12454b9bea87SJim Ingham             }
12464b9bea87SJim Ingham         }
12474b9bea87SJim Ingham         else
12484b9bea87SJim Ingham         {
12494b9bea87SJim Ingham             result.AppendError ("No current location or status available.");
12504b9bea87SJim Ingham             result.SetStatus (eReturnStatusFailed);
12514b9bea87SJim Ingham         }
12524b9bea87SJim Ingham         return result.Succeeded();
12534b9bea87SJim Ingham     }
12544b9bea87SJim Ingham };
12554b9bea87SJim Ingham 
12564b9bea87SJim Ingham //-------------------------------------------------------------------------
125735731357SCaroline Tice // CommandObjectProcessHandle
125835731357SCaroline Tice //-------------------------------------------------------------------------
125935731357SCaroline Tice 
126035731357SCaroline Tice class CommandObjectProcessHandle : public CommandObject
126135731357SCaroline Tice {
126235731357SCaroline Tice public:
126335731357SCaroline Tice 
126435731357SCaroline Tice     class CommandOptions : public Options
126535731357SCaroline Tice     {
126635731357SCaroline Tice     public:
126735731357SCaroline Tice 
126835731357SCaroline Tice         CommandOptions () :
126935731357SCaroline Tice             Options ()
127035731357SCaroline Tice         {
127135731357SCaroline Tice             ResetOptionValues ();
127235731357SCaroline Tice         }
127335731357SCaroline Tice 
127435731357SCaroline Tice         ~CommandOptions ()
127535731357SCaroline Tice         {
127635731357SCaroline Tice         }
127735731357SCaroline Tice 
127835731357SCaroline Tice         Error
127935731357SCaroline Tice         SetOptionValue (int option_idx, const char *option_arg)
128035731357SCaroline Tice         {
128135731357SCaroline Tice             Error error;
128235731357SCaroline Tice             char short_option = (char) m_getopt_table[option_idx].val;
128335731357SCaroline Tice 
128435731357SCaroline Tice             switch (short_option)
128535731357SCaroline Tice             {
128635731357SCaroline Tice                 case 's':
128735731357SCaroline Tice                     stop = option_arg;
128835731357SCaroline Tice                     break;
128935731357SCaroline Tice                 case 'n':
129035731357SCaroline Tice                     notify = option_arg;
129135731357SCaroline Tice                     break;
129235731357SCaroline Tice                 case 'p':
129335731357SCaroline Tice                     pass = option_arg;
129435731357SCaroline Tice                     break;
129535731357SCaroline Tice                 default:
129635731357SCaroline Tice                     error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
129735731357SCaroline Tice                     break;
129835731357SCaroline Tice             }
129935731357SCaroline Tice             return error;
130035731357SCaroline Tice         }
130135731357SCaroline Tice 
130235731357SCaroline Tice         void
130335731357SCaroline Tice         ResetOptionValues ()
130435731357SCaroline Tice         {
130535731357SCaroline Tice             Options::ResetOptionValues();
130635731357SCaroline Tice             stop.clear();
130735731357SCaroline Tice             notify.clear();
130835731357SCaroline Tice             pass.clear();
130935731357SCaroline Tice         }
131035731357SCaroline Tice 
131135731357SCaroline Tice         const lldb::OptionDefinition*
131235731357SCaroline Tice         GetDefinitions ()
131335731357SCaroline Tice         {
131435731357SCaroline Tice             return g_option_table;
131535731357SCaroline Tice         }
131635731357SCaroline Tice 
131735731357SCaroline Tice         // Options table: Required for subclasses of Options.
131835731357SCaroline Tice 
131935731357SCaroline Tice         static lldb::OptionDefinition g_option_table[];
132035731357SCaroline Tice 
132135731357SCaroline Tice         // Instance variables to hold the values for command options.
132235731357SCaroline Tice 
132335731357SCaroline Tice         std::string stop;
132435731357SCaroline Tice         std::string notify;
132535731357SCaroline Tice         std::string pass;
132635731357SCaroline Tice     };
132735731357SCaroline Tice 
132835731357SCaroline Tice 
132935731357SCaroline Tice     CommandObjectProcessHandle (CommandInterpreter &interpreter) :
133035731357SCaroline Tice         CommandObject (interpreter,
133135731357SCaroline Tice                        "process handle",
133210ad7993SCaroline Tice                        "Show or update what the process and debugger should do with various signals received from the OS.",
133335731357SCaroline Tice                        NULL)
133435731357SCaroline Tice     {
133510ad7993SCaroline Tice         SetHelpLong ("If no signals are specified, update them all.  If no update option is specified, list the current values.\n");
133635731357SCaroline Tice         CommandArgumentEntry arg;
1337c0dbdfb6SCaroline Tice         CommandArgumentData signal_arg;
133835731357SCaroline Tice 
1339c0dbdfb6SCaroline Tice         signal_arg.arg_type = eArgTypeUnixSignal;
1340c0dbdfb6SCaroline Tice         signal_arg.arg_repetition = eArgRepeatStar;
134135731357SCaroline Tice 
1342c0dbdfb6SCaroline Tice         arg.push_back (signal_arg);
134335731357SCaroline Tice 
134435731357SCaroline Tice         m_arguments.push_back (arg);
134535731357SCaroline Tice     }
134635731357SCaroline Tice 
134735731357SCaroline Tice     ~CommandObjectProcessHandle ()
134835731357SCaroline Tice     {
134935731357SCaroline Tice     }
135035731357SCaroline Tice 
135135731357SCaroline Tice     Options *
135235731357SCaroline Tice     GetOptions ()
135335731357SCaroline Tice     {
135435731357SCaroline Tice         return &m_options;
135535731357SCaroline Tice     }
135635731357SCaroline Tice 
135735731357SCaroline Tice     bool
135810ad7993SCaroline Tice     VerifyCommandOptionValue (const std::string &option, int &real_value)
135935731357SCaroline Tice     {
136035731357SCaroline Tice         bool okay = true;
136135731357SCaroline Tice 
136210ad7993SCaroline Tice         bool success = false;
136310ad7993SCaroline Tice         bool tmp_value = Args::StringToBoolean (option.c_str(), false, &success);
136410ad7993SCaroline Tice 
136510ad7993SCaroline Tice         if (success && tmp_value)
136610ad7993SCaroline Tice             real_value = 1;
136710ad7993SCaroline Tice         else if (success && !tmp_value)
136810ad7993SCaroline Tice             real_value = 0;
136935731357SCaroline Tice         else
137035731357SCaroline Tice         {
137135731357SCaroline Tice             // If the value isn't 'true' or 'false', it had better be 0 or 1.
137210ad7993SCaroline Tice             real_value = Args::StringToUInt32 (option.c_str(), 3);
137310ad7993SCaroline Tice             if (real_value != 0 && real_value != 1)
137435731357SCaroline Tice                 okay = false;
137535731357SCaroline Tice         }
137635731357SCaroline Tice 
137735731357SCaroline Tice         return okay;
137835731357SCaroline Tice     }
137935731357SCaroline Tice 
138010ad7993SCaroline Tice     void
138110ad7993SCaroline Tice     PrintSignalHeader (Stream &str)
138210ad7993SCaroline Tice     {
138310ad7993SCaroline Tice         str.Printf ("NAME        PASS   STOP   NOTIFY\n");
138410ad7993SCaroline Tice         str.Printf ("==========  =====  =====  ======\n");
138510ad7993SCaroline Tice     }
138610ad7993SCaroline Tice 
138710ad7993SCaroline Tice     void
138810ad7993SCaroline Tice     PrintSignal (Stream &str, int32_t signo, const char *sig_name, UnixSignals &signals)
138910ad7993SCaroline Tice     {
139010ad7993SCaroline Tice         bool stop;
139110ad7993SCaroline Tice         bool suppress;
139210ad7993SCaroline Tice         bool notify;
139310ad7993SCaroline Tice 
139410ad7993SCaroline Tice         str.Printf ("%-10s  ", sig_name);
139510ad7993SCaroline Tice         if (signals.GetSignalInfo (signo, suppress, stop, notify))
139610ad7993SCaroline Tice         {
139710ad7993SCaroline Tice             bool pass = !suppress;
139810ad7993SCaroline Tice             str.Printf ("%s  %s  %s",
139910ad7993SCaroline Tice                         (pass ? "true " : "false"),
140010ad7993SCaroline Tice                         (stop ? "true " : "false"),
140110ad7993SCaroline Tice                         (notify ? "true " : "false"));
140210ad7993SCaroline Tice         }
140310ad7993SCaroline Tice         str.Printf ("\n");
140410ad7993SCaroline Tice     }
140510ad7993SCaroline Tice 
140610ad7993SCaroline Tice     void
140710ad7993SCaroline Tice     PrintSignalInformation (Stream &str, Args &signal_args, int num_valid_signals, UnixSignals &signals)
140810ad7993SCaroline Tice     {
140910ad7993SCaroline Tice         PrintSignalHeader (str);
141010ad7993SCaroline Tice 
141110ad7993SCaroline Tice         if (num_valid_signals > 0)
141210ad7993SCaroline Tice         {
141310ad7993SCaroline Tice             size_t num_args = signal_args.GetArgumentCount();
141410ad7993SCaroline Tice             for (size_t i = 0; i < num_args; ++i)
141510ad7993SCaroline Tice             {
141610ad7993SCaroline Tice                 int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i));
141710ad7993SCaroline Tice                 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
141810ad7993SCaroline Tice                     PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals);
141910ad7993SCaroline Tice             }
142010ad7993SCaroline Tice         }
142110ad7993SCaroline Tice         else // Print info for ALL signals
142210ad7993SCaroline Tice         {
142310ad7993SCaroline Tice             int32_t signo = signals.GetFirstSignalNumber();
142410ad7993SCaroline Tice             while (signo != LLDB_INVALID_SIGNAL_NUMBER)
142510ad7993SCaroline Tice             {
142610ad7993SCaroline Tice                 PrintSignal (str, signo, signals.GetSignalAsCString (signo), signals);
142710ad7993SCaroline Tice                 signo = signals.GetNextSignalNumber (signo);
142810ad7993SCaroline Tice             }
142910ad7993SCaroline Tice         }
143010ad7993SCaroline Tice     }
143110ad7993SCaroline Tice 
143235731357SCaroline Tice     bool
143335731357SCaroline Tice     Execute (Args &signal_args, CommandReturnObject &result)
143435731357SCaroline Tice     {
143535731357SCaroline Tice         TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
143635731357SCaroline Tice 
143735731357SCaroline Tice         if (!target_sp)
143835731357SCaroline Tice         {
143935731357SCaroline Tice             result.AppendError ("No current target;"
144035731357SCaroline Tice                                 " cannot handle signals until you have a valid target and process.\n");
144135731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
144235731357SCaroline Tice             return false;
144335731357SCaroline Tice         }
144435731357SCaroline Tice 
144535731357SCaroline Tice         ProcessSP process_sp = target_sp->GetProcessSP();
144635731357SCaroline Tice 
144735731357SCaroline Tice         if (!process_sp)
144835731357SCaroline Tice         {
144935731357SCaroline Tice             result.AppendError ("No current process; cannot handle signals until you have a valid process.\n");
145035731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
145135731357SCaroline Tice             return false;
145235731357SCaroline Tice         }
145335731357SCaroline Tice 
145435731357SCaroline Tice         int stop_action = -1;   // -1 means leave the current setting alone
145535731357SCaroline Tice         int pass_action = -1;   // -1 means leave the current setting alone
145635731357SCaroline Tice         int notify_action = -1; // -1 means leave the current setting alone
145735731357SCaroline Tice 
145835731357SCaroline Tice         if (! m_options.stop.empty()
145910ad7993SCaroline Tice             && ! VerifyCommandOptionValue (m_options.stop, stop_action))
146035731357SCaroline Tice         {
146135731357SCaroline Tice             result.AppendError ("Invalid argument for command option --stop; must be true or false.\n");
146235731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
146335731357SCaroline Tice             return false;
146435731357SCaroline Tice         }
146535731357SCaroline Tice 
146635731357SCaroline Tice         if (! m_options.notify.empty()
146710ad7993SCaroline Tice             && ! VerifyCommandOptionValue (m_options.notify, notify_action))
146835731357SCaroline Tice         {
146935731357SCaroline Tice             result.AppendError ("Invalid argument for command option --notify; must be true or false.\n");
147035731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
147135731357SCaroline Tice             return false;
147235731357SCaroline Tice         }
147335731357SCaroline Tice 
147435731357SCaroline Tice         if (! m_options.pass.empty()
147510ad7993SCaroline Tice             && ! VerifyCommandOptionValue (m_options.pass, pass_action))
147635731357SCaroline Tice         {
147735731357SCaroline Tice             result.AppendError ("Invalid argument for command option --pass; must be true or false.\n");
147835731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
147935731357SCaroline Tice             return false;
148035731357SCaroline Tice         }
148135731357SCaroline Tice 
148235731357SCaroline Tice         size_t num_args = signal_args.GetArgumentCount();
148335731357SCaroline Tice         UnixSignals &signals = process_sp->GetUnixSignals();
148435731357SCaroline Tice         int num_signals_set = 0;
148535731357SCaroline Tice 
148610ad7993SCaroline Tice         if (num_args > 0)
148710ad7993SCaroline Tice         {
148835731357SCaroline Tice             for (size_t i = 0; i < num_args; ++i)
148935731357SCaroline Tice             {
149035731357SCaroline Tice                 int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i));
149135731357SCaroline Tice                 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
149235731357SCaroline Tice                 {
149310ad7993SCaroline Tice                     // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees
149435731357SCaroline Tice                     // the value is either 0 or 1.
149535731357SCaroline Tice                     if (stop_action != -1)
149635731357SCaroline Tice                         signals.SetShouldStop (signo, (bool) stop_action);
149735731357SCaroline Tice                     if (pass_action != -1)
149835731357SCaroline Tice                     {
149910ad7993SCaroline Tice                         bool suppress = ! ((bool) pass_action);
150010ad7993SCaroline Tice                         signals.SetShouldSuppress (signo, suppress);
150135731357SCaroline Tice                     }
150235731357SCaroline Tice                     if (notify_action != -1)
150335731357SCaroline Tice                         signals.SetShouldNotify (signo, (bool) notify_action);
150435731357SCaroline Tice                     ++num_signals_set;
150535731357SCaroline Tice                 }
150635731357SCaroline Tice                 else
150735731357SCaroline Tice                 {
150835731357SCaroline Tice                     result.AppendErrorWithFormat ("Invalid signal name '%s'\n", signal_args.GetArgumentAtIndex (i));
150935731357SCaroline Tice                 }
151035731357SCaroline Tice             }
151110ad7993SCaroline Tice         }
151210ad7993SCaroline Tice         else
151310ad7993SCaroline Tice         {
151410ad7993SCaroline Tice             // No signal specified, if any command options were specified, update ALL signals.
151510ad7993SCaroline Tice             if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1))
151610ad7993SCaroline Tice             {
151710ad7993SCaroline Tice                 if (m_interpreter.Confirm ("Do you really want to update all the signals?", false))
151810ad7993SCaroline Tice                 {
151910ad7993SCaroline Tice                     int32_t signo = signals.GetFirstSignalNumber();
152010ad7993SCaroline Tice                     while (signo != LLDB_INVALID_SIGNAL_NUMBER)
152110ad7993SCaroline Tice                     {
152210ad7993SCaroline Tice                         if (notify_action != -1)
152310ad7993SCaroline Tice                             signals.SetShouldNotify (signo, (bool) notify_action);
152410ad7993SCaroline Tice                         if (stop_action != -1)
152510ad7993SCaroline Tice                             signals.SetShouldStop (signo, (bool) stop_action);
152610ad7993SCaroline Tice                         if (pass_action != -1)
152710ad7993SCaroline Tice                         {
152810ad7993SCaroline Tice                             bool suppress = ! ((bool) pass_action);
152910ad7993SCaroline Tice                             signals.SetShouldSuppress (signo, suppress);
153010ad7993SCaroline Tice                         }
153110ad7993SCaroline Tice                         signo = signals.GetNextSignalNumber (signo);
153210ad7993SCaroline Tice                     }
153310ad7993SCaroline Tice                 }
153410ad7993SCaroline Tice             }
153510ad7993SCaroline Tice         }
153610ad7993SCaroline Tice 
153710ad7993SCaroline Tice         PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals);
153835731357SCaroline Tice 
153935731357SCaroline Tice         if (num_signals_set > 0)
154035731357SCaroline Tice             result.SetStatus (eReturnStatusSuccessFinishNoResult);
154135731357SCaroline Tice         else
154235731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
154335731357SCaroline Tice 
154435731357SCaroline Tice         return result.Succeeded();
154535731357SCaroline Tice     }
154635731357SCaroline Tice 
154735731357SCaroline Tice protected:
154835731357SCaroline Tice 
154935731357SCaroline Tice     CommandOptions m_options;
155035731357SCaroline Tice };
155135731357SCaroline Tice 
155235731357SCaroline Tice lldb::OptionDefinition
155335731357SCaroline Tice CommandObjectProcessHandle::CommandOptions::g_option_table[] =
155435731357SCaroline Tice {
155535731357SCaroline 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." },
155635731357SCaroline 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." },
155735731357SCaroline Tice { LLDB_OPT_SET_1, false, "pass",  'p', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." },
155835731357SCaroline Tice { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
155935731357SCaroline Tice };
156035731357SCaroline Tice 
156135731357SCaroline Tice //-------------------------------------------------------------------------
156230fdc8d8SChris Lattner // CommandObjectMultiwordProcess
156330fdc8d8SChris Lattner //-------------------------------------------------------------------------
156430fdc8d8SChris Lattner 
15656611103cSGreg Clayton CommandObjectMultiwordProcess::CommandObjectMultiwordProcess (CommandInterpreter &interpreter) :
1566a7015092SGreg Clayton     CommandObjectMultiword (interpreter,
1567a7015092SGreg Clayton                             "process",
156830fdc8d8SChris Lattner                             "A set of commands for operating on a process.",
156930fdc8d8SChris Lattner                             "process <subcommand> [<subcommand-options>]")
157030fdc8d8SChris Lattner {
1571a7015092SGreg Clayton     LoadSubCommand ("attach",      CommandObjectSP (new CommandObjectProcessAttach (interpreter)));
1572a7015092SGreg Clayton     LoadSubCommand ("launch",      CommandObjectSP (new CommandObjectProcessLaunch (interpreter)));
1573a7015092SGreg Clayton     LoadSubCommand ("continue",    CommandObjectSP (new CommandObjectProcessContinue (interpreter)));
1574a7015092SGreg Clayton     LoadSubCommand ("detach",      CommandObjectSP (new CommandObjectProcessDetach (interpreter)));
1575*8f343b09SGreg Clayton     LoadSubCommand ("load",        CommandObjectSP (new CommandObjectProcessLoad (interpreter)));
1576*8f343b09SGreg Clayton     LoadSubCommand ("unload",      CommandObjectSP (new CommandObjectProcessUnload (interpreter)));
1577a7015092SGreg Clayton     LoadSubCommand ("signal",      CommandObjectSP (new CommandObjectProcessSignal (interpreter)));
157835731357SCaroline Tice     LoadSubCommand ("handle",      CommandObjectSP (new CommandObjectProcessHandle (interpreter)));
1579a7015092SGreg Clayton     LoadSubCommand ("status",      CommandObjectSP (new CommandObjectProcessStatus (interpreter)));
1580a7015092SGreg Clayton     LoadSubCommand ("interrupt",   CommandObjectSP (new CommandObjectProcessInterrupt (interpreter)));
1581a7015092SGreg Clayton     LoadSubCommand ("kill",        CommandObjectSP (new CommandObjectProcessKill (interpreter)));
158230fdc8d8SChris Lattner }
158330fdc8d8SChris Lattner 
158430fdc8d8SChris Lattner CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess ()
158530fdc8d8SChris Lattner {
158630fdc8d8SChris Lattner }
158730fdc8d8SChris Lattner 
1588