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 //-------------------------------------------------------------------------
32*bb9caf73SJim Ingham #pragma mark CommandObjectProjectLaunch
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;
65f8da8631SCaroline Tice                 case 'n':   no_stdio = true;            break;
66913c4fa1SGreg Clayton                 case 't':
67913c4fa1SGreg Clayton                     if (option_arg && option_arg[0])
68913c4fa1SGreg Clayton                         tty_name.assign (option_arg);
69913c4fa1SGreg Clayton                     in_new_tty = true;
70913c4fa1SGreg Clayton                     break;
7130fdc8d8SChris Lattner                 default:
7230fdc8d8SChris Lattner                     error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
7330fdc8d8SChris Lattner                     break;
7430fdc8d8SChris Lattner 
7530fdc8d8SChris Lattner             }
7630fdc8d8SChris Lattner             return error;
7730fdc8d8SChris Lattner         }
7830fdc8d8SChris Lattner 
7930fdc8d8SChris Lattner         void
8030fdc8d8SChris Lattner         ResetOptionValues ()
8130fdc8d8SChris Lattner         {
8230fdc8d8SChris Lattner             Options::ResetOptionValues();
8330fdc8d8SChris Lattner             stop_at_entry = false;
8419388cfcSGreg Clayton             in_new_tty = false;
85913c4fa1SGreg Clayton             tty_name.clear();
8630fdc8d8SChris Lattner             stdin_path.clear();
8730fdc8d8SChris Lattner             stdout_path.clear();
8830fdc8d8SChris Lattner             stderr_path.clear();
8930fdc8d8SChris Lattner             plugin_name.clear();
90f8da8631SCaroline Tice             no_stdio = false;
9130fdc8d8SChris Lattner         }
9230fdc8d8SChris Lattner 
9330fdc8d8SChris Lattner         const lldb::OptionDefinition*
9430fdc8d8SChris Lattner         GetDefinitions ()
9530fdc8d8SChris Lattner         {
9630fdc8d8SChris Lattner             return g_option_table;
9730fdc8d8SChris Lattner         }
9830fdc8d8SChris Lattner 
9930fdc8d8SChris Lattner         // Options table: Required for subclasses of Options.
10030fdc8d8SChris Lattner 
10130fdc8d8SChris Lattner         static lldb::OptionDefinition g_option_table[];
10230fdc8d8SChris Lattner 
10330fdc8d8SChris Lattner         // Instance variables to hold the values for command options.
10430fdc8d8SChris Lattner 
10530fdc8d8SChris Lattner         bool stop_at_entry;
10619388cfcSGreg Clayton         bool in_new_tty;
107f8da8631SCaroline Tice         bool no_stdio;
108913c4fa1SGreg Clayton         std::string tty_name;
10930fdc8d8SChris Lattner         std::string stderr_path;
11030fdc8d8SChris Lattner         std::string stdin_path;
11130fdc8d8SChris Lattner         std::string stdout_path;
11230fdc8d8SChris Lattner         std::string plugin_name;
11330fdc8d8SChris Lattner 
11430fdc8d8SChris Lattner     };
11530fdc8d8SChris Lattner 
116a7015092SGreg Clayton     CommandObjectProcessLaunch (CommandInterpreter &interpreter) :
117a7015092SGreg Clayton         CommandObject (interpreter,
118a7015092SGreg Clayton                        "process launch",
119e3d26315SCaroline Tice                        "Launch the executable in the debugger.",
120405fe67fSCaroline Tice                        NULL)
12130fdc8d8SChris Lattner     {
122405fe67fSCaroline Tice         CommandArgumentEntry arg;
123405fe67fSCaroline Tice         CommandArgumentData run_args_arg;
124405fe67fSCaroline Tice 
125405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
126405fe67fSCaroline Tice         run_args_arg.arg_type = eArgTypeRunArgs;
127405fe67fSCaroline Tice         run_args_arg.arg_repetition = eArgRepeatOptional;
128405fe67fSCaroline Tice 
129405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
130405fe67fSCaroline Tice         arg.push_back (run_args_arg);
131405fe67fSCaroline Tice 
132405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
133405fe67fSCaroline Tice         m_arguments.push_back (arg);
13430fdc8d8SChris Lattner     }
13530fdc8d8SChris Lattner 
13630fdc8d8SChris Lattner 
13730fdc8d8SChris Lattner     ~CommandObjectProcessLaunch ()
13830fdc8d8SChris Lattner     {
13930fdc8d8SChris Lattner     }
14030fdc8d8SChris Lattner 
14130fdc8d8SChris Lattner     Options *
14230fdc8d8SChris Lattner     GetOptions ()
14330fdc8d8SChris Lattner     {
14430fdc8d8SChris Lattner         return &m_options;
14530fdc8d8SChris Lattner     }
14630fdc8d8SChris Lattner 
14730fdc8d8SChris Lattner     bool
14805faeb71SGreg Clayton     Execute (Args& launch_args, CommandReturnObject &result)
14930fdc8d8SChris Lattner     {
150a7015092SGreg Clayton         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
15130fdc8d8SChris Lattner 
15230fdc8d8SChris Lattner         if (target == NULL)
15330fdc8d8SChris Lattner         {
15430fdc8d8SChris Lattner             result.AppendError ("invalid target, set executable file using 'file' command");
15530fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
15630fdc8d8SChris Lattner             return false;
15730fdc8d8SChris Lattner         }
15830fdc8d8SChris Lattner 
15930fdc8d8SChris Lattner         // If our listener is NULL, users aren't allows to launch
16030fdc8d8SChris Lattner         char filename[PATH_MAX];
16119388cfcSGreg Clayton         const Module *exe_module = target->GetExecutableModule().get();
16230fdc8d8SChris Lattner         exe_module->GetFileSpec().GetPath(filename, sizeof(filename));
16330fdc8d8SChris Lattner 
164a7015092SGreg Clayton         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
165a7015092SGreg Clayton         if (process && process->IsAlive())
16630fdc8d8SChris Lattner         {
167*bb9caf73SJim Ingham             if (!m_interpreter.Confirm ("There is a running process, kill it and restart?", true))
168*bb9caf73SJim Ingham             {
169*bb9caf73SJim Ingham                 result.AppendErrorWithFormat ("Process %u is currently being debugged, restart cancelled.\n",
17030fdc8d8SChris Lattner                                               process->GetID());
17130fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
17230fdc8d8SChris Lattner                 return false;
17330fdc8d8SChris Lattner             }
174*bb9caf73SJim Ingham             else
175*bb9caf73SJim Ingham             {
176*bb9caf73SJim Ingham                 Error error (process->Destroy());
177*bb9caf73SJim Ingham                 if (error.Success())
178*bb9caf73SJim Ingham                 {
179*bb9caf73SJim Ingham                     result.SetStatus (eReturnStatusSuccessFinishResult);
180*bb9caf73SJim Ingham                 }
181*bb9caf73SJim Ingham                 else
182*bb9caf73SJim Ingham                 {
183*bb9caf73SJim Ingham                     result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString());
184*bb9caf73SJim Ingham                     result.SetStatus (eReturnStatusFailed);
185*bb9caf73SJim Ingham                 }
186*bb9caf73SJim Ingham             }
187*bb9caf73SJim Ingham         }
18830fdc8d8SChris Lattner 
18930fdc8d8SChris Lattner         const char *plugin_name;
19030fdc8d8SChris Lattner         if (!m_options.plugin_name.empty())
19130fdc8d8SChris Lattner             plugin_name = m_options.plugin_name.c_str();
19230fdc8d8SChris Lattner         else
19330fdc8d8SChris Lattner             plugin_name = NULL;
19430fdc8d8SChris Lattner 
195a7015092SGreg Clayton         process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name).get();
19630fdc8d8SChris Lattner 
197a7015092SGreg Clayton         if (process == NULL)
1983df9a8dfSCaroline Tice         {
19943a8c39bSCaroline Tice             result.AppendErrorWithFormat ("Failed to find a process plugin for executable.\n");
200a7015092SGreg Clayton             result.SetStatus (eReturnStatusFailed);
201a7015092SGreg Clayton             return false;
2023df9a8dfSCaroline Tice         }
2033df9a8dfSCaroline Tice 
204a7015092SGreg Clayton         // If no launch args were given on the command line, then use any that
205a7015092SGreg Clayton         // might have been set using the "run-args" set variable.
20630fdc8d8SChris Lattner         if (launch_args.GetArgumentCount() == 0)
20730fdc8d8SChris Lattner         {
208a7015092SGreg Clayton             if (process->GetRunArguments().GetArgumentCount() > 0)
209a7015092SGreg Clayton                 launch_args = process->GetRunArguments();
21030fdc8d8SChris Lattner         }
21130fdc8d8SChris Lattner 
21219388cfcSGreg Clayton         if (m_options.in_new_tty)
21319388cfcSGreg Clayton         {
21419388cfcSGreg Clayton             char exec_file_path[PATH_MAX];
21519388cfcSGreg Clayton             if (exe_module->GetFileSpec().GetPath(exec_file_path, sizeof(exec_file_path)))
21619388cfcSGreg Clayton             {
21719388cfcSGreg Clayton                 launch_args.InsertArgumentAtIndex(0, exec_file_path);
21819388cfcSGreg Clayton             }
21919388cfcSGreg Clayton             else
22019388cfcSGreg Clayton             {
22119388cfcSGreg Clayton                 result.AppendError("invalid executable");
22219388cfcSGreg Clayton                 result.SetStatus (eReturnStatusFailed);
22319388cfcSGreg Clayton                 return false;
22419388cfcSGreg Clayton             }
22519388cfcSGreg Clayton         }
22619388cfcSGreg Clayton 
227a7015092SGreg Clayton         Args environment;
22830fdc8d8SChris Lattner 
229a7015092SGreg Clayton         process->GetEnvironmentAsArgs (environment);
230a7015092SGreg Clayton 
231a7015092SGreg Clayton         uint32_t launch_flags = eLaunchFlagNone;
232a7015092SGreg Clayton 
233a7015092SGreg Clayton         if (process->GetDisableASLR())
234a7015092SGreg Clayton             launch_flags |= eLaunchFlagDisableASLR;
235a7015092SGreg Clayton 
236f8da8631SCaroline Tice         if (m_options.no_stdio)
237f8da8631SCaroline Tice             launch_flags |= eLaunchFlagDisableSTDIO;
238f8da8631SCaroline Tice         else if (!m_options.in_new_tty
239f8da8631SCaroline Tice                  && m_options.stdin_path.empty()
240f8da8631SCaroline Tice                  && m_options.stdout_path.empty()
241f8da8631SCaroline Tice                  && m_options.stderr_path.empty())
242f8da8631SCaroline Tice         {
243f8da8631SCaroline Tice             // Only use the settings value if the user hasn't specified any options that would override it.
244f8da8631SCaroline Tice             if (process->GetDisableSTDIO())
245f8da8631SCaroline Tice                 launch_flags |= eLaunchFlagDisableSTDIO;
246f8da8631SCaroline Tice         }
247f8da8631SCaroline Tice 
24819388cfcSGreg Clayton         const char **inferior_argv = launch_args.GetArgumentCount() ? launch_args.GetConstArgumentVector() : NULL;
24919388cfcSGreg Clayton         const char **inferior_envp = environment.GetArgumentCount() ? environment.GetConstArgumentVector() : NULL;
25030fdc8d8SChris Lattner 
25119388cfcSGreg Clayton         Error error;
25219388cfcSGreg Clayton 
25319388cfcSGreg Clayton         if (m_options.in_new_tty)
25419388cfcSGreg Clayton         {
25519388cfcSGreg Clayton 
256913c4fa1SGreg Clayton             lldb::pid_t pid = Host::LaunchInNewTerminal (m_options.tty_name.c_str(),
257913c4fa1SGreg Clayton                                                          inferior_argv,
25819388cfcSGreg Clayton                                                          inferior_envp,
25919388cfcSGreg Clayton                                                          &exe_module->GetArchitecture(),
26019388cfcSGreg Clayton                                                          true,
26119388cfcSGreg Clayton                                                          process->GetDisableASLR());
26219388cfcSGreg Clayton 
2633fcbed6bSGreg Clayton             if (pid != LLDB_INVALID_PROCESS_ID)
2643fcbed6bSGreg Clayton                 error = process->Attach (pid);
26519388cfcSGreg Clayton         }
26619388cfcSGreg Clayton         else
26719388cfcSGreg Clayton         {
26830fdc8d8SChris Lattner             const char * stdin_path = NULL;
26930fdc8d8SChris Lattner             const char * stdout_path = NULL;
27030fdc8d8SChris Lattner             const char * stderr_path = NULL;
27130fdc8d8SChris Lattner 
272a7015092SGreg Clayton             // Were any standard input/output/error paths given on the command line?
273a7015092SGreg Clayton             if (m_options.stdin_path.empty() &&
27430fdc8d8SChris Lattner                 m_options.stdout_path.empty() &&
275a7015092SGreg Clayton                 m_options.stderr_path.empty())
27630fdc8d8SChris Lattner             {
277a7015092SGreg Clayton                 // No standard file handles were given on the command line, check
278a7015092SGreg Clayton                 // with the process object in case they were give using "set settings"
279a7015092SGreg Clayton                 stdin_path = process->GetStandardInputPath();
280a7015092SGreg Clayton                 stdout_path = process->GetStandardOutputPath();
281a7015092SGreg Clayton                 stderr_path = process->GetStandardErrorPath();
282a7015092SGreg Clayton             }
283a7015092SGreg Clayton             else
284a7015092SGreg Clayton             {
285a7015092SGreg Clayton                 stdin_path = m_options.stdin_path.empty()  ? NULL : m_options.stdin_path.c_str();
286a7015092SGreg Clayton                 stdout_path = m_options.stdout_path.empty() ? NULL : m_options.stdout_path.c_str();
287a7015092SGreg Clayton                 stderr_path = m_options.stderr_path.empty() ? NULL : m_options.stderr_path.c_str();
28830fdc8d8SChris Lattner             }
28930fdc8d8SChris Lattner 
290a7015092SGreg Clayton             if (stdin_path == NULL)
291a7015092SGreg Clayton                 stdin_path = "/dev/null";
292a7015092SGreg Clayton             if (stdout_path == NULL)
293a7015092SGreg Clayton                 stdout_path = "/dev/null";
294a7015092SGreg Clayton             if (stderr_path == NULL)
295a7015092SGreg Clayton                 stderr_path = "/dev/null";
296a7015092SGreg Clayton 
29719388cfcSGreg Clayton             error = process->Launch (inferior_argv,
29819388cfcSGreg Clayton                                      inferior_envp,
299f681b94fSGreg Clayton                                      launch_flags,
30030fdc8d8SChris Lattner                                      stdin_path,
30130fdc8d8SChris Lattner                                      stdout_path,
30219388cfcSGreg Clayton                                      stderr_path);
30319388cfcSGreg Clayton         }
30430fdc8d8SChris Lattner 
30530fdc8d8SChris Lattner         if (error.Success())
30630fdc8d8SChris Lattner         {
30719388cfcSGreg Clayton             const char *archname = exe_module->GetArchitecture().AsCString();
30819388cfcSGreg Clayton 
30919388cfcSGreg Clayton             result.AppendMessageWithFormat ("Process %i launched: '%s' (%s)\n", process->GetID(), filename, archname);
31005faeb71SGreg Clayton             result.SetDidChangeProcessState (true);
31130fdc8d8SChris Lattner             if (m_options.stop_at_entry == false)
31230fdc8d8SChris Lattner             {
31305faeb71SGreg Clayton                 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
31430fdc8d8SChris Lattner                 StateType state = process->WaitForProcessToStop (NULL);
31530fdc8d8SChris Lattner 
31630fdc8d8SChris Lattner                 if (state == eStateStopped)
31730fdc8d8SChris Lattner                 {
31805faeb71SGreg Clayton                     error = process->Resume();
31905faeb71SGreg Clayton                     if (error.Success())
32005faeb71SGreg Clayton                     {
32105faeb71SGreg Clayton                         bool synchronous_execution = m_interpreter.GetSynchronous ();
32230fdc8d8SChris Lattner                         if (synchronous_execution)
32330fdc8d8SChris Lattner                         {
32405faeb71SGreg Clayton                             state = process->WaitForProcessToStop (NULL);
32530fdc8d8SChris Lattner                             result.SetDidChangeProcessState (true);
32605faeb71SGreg Clayton                             result.SetStatus (eReturnStatusSuccessFinishResult);
32705faeb71SGreg Clayton                         }
32805faeb71SGreg Clayton                         else
32905faeb71SGreg Clayton                         {
33005faeb71SGreg Clayton                             result.SetStatus (eReturnStatusSuccessContinuingNoResult);
33105faeb71SGreg Clayton                         }
33205faeb71SGreg Clayton                     }
33330fdc8d8SChris Lattner                 }
33430fdc8d8SChris Lattner             }
33530fdc8d8SChris Lattner         }
33630fdc8d8SChris Lattner 
33730fdc8d8SChris Lattner         return result.Succeeded();
33830fdc8d8SChris Lattner     }
33930fdc8d8SChris Lattner 
340ebc09c36SJim Ingham     virtual const char *GetRepeatCommand (Args &current_command_args, uint32_t index)
341ebc09c36SJim Ingham     {
342ebc09c36SJim Ingham         // No repeat for "process launch"...
343ebc09c36SJim Ingham         return "";
344ebc09c36SJim Ingham     }
345ebc09c36SJim Ingham 
34630fdc8d8SChris Lattner protected:
34730fdc8d8SChris Lattner 
34830fdc8d8SChris Lattner     CommandOptions m_options;
34930fdc8d8SChris Lattner };
35030fdc8d8SChris Lattner 
35130fdc8d8SChris Lattner 
35219388cfcSGreg Clayton #define SET1 LLDB_OPT_SET_1
35319388cfcSGreg Clayton #define SET2 LLDB_OPT_SET_2
354f8da8631SCaroline Tice #define SET3 LLDB_OPT_SET_3
35519388cfcSGreg Clayton 
35630fdc8d8SChris Lattner lldb::OptionDefinition
35730fdc8d8SChris Lattner CommandObjectProcessLaunch::CommandOptions::g_option_table[] =
35830fdc8d8SChris Lattner {
359f8da8631SCaroline Tice { SET1 | SET2 | SET3, false, "stop-at-entry", 's', no_argument,       NULL, 0, eArgTypeNone,    "Stop at the entry point of the program when launching a process."},
36019388cfcSGreg Clayton { SET1              , false, "stdin",         'i', required_argument, NULL, 0, eArgTypePath,    "Redirect stdin for the process to <path>."},
36119388cfcSGreg Clayton { SET1              , false, "stdout",        'o', required_argument, NULL, 0, eArgTypePath,    "Redirect stdout for the process to <path>."},
36219388cfcSGreg Clayton { SET1              , false, "stderr",        'e', required_argument, NULL, 0, eArgTypePath,    "Redirect stderr for the process to <path>."},
363f8da8631SCaroline Tice { SET1 | SET2 | SET3, false, "plugin",        'p', required_argument, NULL, 0, eArgTypePlugin,  "Name of the process plugin you want to use."},
364913c4fa1SGreg 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."},
365f8da8631SCaroline Tice {               SET3, false, "no-stdio",      'n', no_argument,       NULL, 0, eArgTypeNone,    "Do not set up for terminal I/O to go to running process."},
366deaab222SCaroline Tice { 0,                  false, NULL,             0,  0,                 NULL, 0, eArgTypeNone,    NULL }
36730fdc8d8SChris Lattner };
36830fdc8d8SChris Lattner 
36919388cfcSGreg Clayton #undef SET1
37019388cfcSGreg Clayton #undef SET2
371f8da8631SCaroline Tice #undef SET3
37230fdc8d8SChris Lattner 
37330fdc8d8SChris Lattner //-------------------------------------------------------------------------
37430fdc8d8SChris Lattner // CommandObjectProcessAttach
37530fdc8d8SChris Lattner //-------------------------------------------------------------------------
376*bb9caf73SJim Ingham #pragma mark CommandObjectProcessAttach
37730fdc8d8SChris Lattner class CommandObjectProcessAttach : public CommandObject
37830fdc8d8SChris Lattner {
37930fdc8d8SChris Lattner public:
38030fdc8d8SChris Lattner 
38130fdc8d8SChris Lattner     class CommandOptions : public Options
38230fdc8d8SChris Lattner     {
38330fdc8d8SChris Lattner     public:
38430fdc8d8SChris Lattner 
38530fdc8d8SChris Lattner         CommandOptions () :
38630fdc8d8SChris Lattner             Options()
38730fdc8d8SChris Lattner         {
38830fdc8d8SChris Lattner             // Keep default values of all options in one place: ResetOptionValues ()
38930fdc8d8SChris Lattner             ResetOptionValues ();
39030fdc8d8SChris Lattner         }
39130fdc8d8SChris Lattner 
39230fdc8d8SChris Lattner         ~CommandOptions ()
39330fdc8d8SChris Lattner         {
39430fdc8d8SChris Lattner         }
39530fdc8d8SChris Lattner 
39630fdc8d8SChris Lattner         Error
39730fdc8d8SChris Lattner         SetOptionValue (int option_idx, const char *option_arg)
39830fdc8d8SChris Lattner         {
39930fdc8d8SChris Lattner             Error error;
40030fdc8d8SChris Lattner             char short_option = (char) m_getopt_table[option_idx].val;
40130fdc8d8SChris Lattner             bool success = false;
40230fdc8d8SChris Lattner             switch (short_option)
40330fdc8d8SChris Lattner             {
40430fdc8d8SChris Lattner                 case 'p':
40530fdc8d8SChris Lattner                     pid = Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success);
40630fdc8d8SChris Lattner                     if (!success || pid == LLDB_INVALID_PROCESS_ID)
40730fdc8d8SChris Lattner                     {
40830fdc8d8SChris Lattner                         error.SetErrorStringWithFormat("Invalid process ID '%s'.\n", option_arg);
40930fdc8d8SChris Lattner                     }
41030fdc8d8SChris Lattner                     break;
41130fdc8d8SChris Lattner 
41230fdc8d8SChris Lattner                 case 'P':
41330fdc8d8SChris Lattner                     plugin_name = option_arg;
41430fdc8d8SChris Lattner                     break;
41530fdc8d8SChris Lattner 
41630fdc8d8SChris Lattner                 case 'n':
41730fdc8d8SChris Lattner                     name.assign(option_arg);
41830fdc8d8SChris Lattner                     break;
41930fdc8d8SChris Lattner 
42030fdc8d8SChris Lattner                 case 'w':
42130fdc8d8SChris Lattner                     waitfor = true;
42230fdc8d8SChris Lattner                     break;
42330fdc8d8SChris Lattner 
42430fdc8d8SChris Lattner                 default:
42530fdc8d8SChris Lattner                     error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
42630fdc8d8SChris Lattner                     break;
42730fdc8d8SChris Lattner             }
42830fdc8d8SChris Lattner             return error;
42930fdc8d8SChris Lattner         }
43030fdc8d8SChris Lattner 
43130fdc8d8SChris Lattner         void
43230fdc8d8SChris Lattner         ResetOptionValues ()
43330fdc8d8SChris Lattner         {
43430fdc8d8SChris Lattner             Options::ResetOptionValues();
43530fdc8d8SChris Lattner             pid = LLDB_INVALID_PROCESS_ID;
43630fdc8d8SChris Lattner             name.clear();
43730fdc8d8SChris Lattner             waitfor = false;
43830fdc8d8SChris Lattner         }
43930fdc8d8SChris Lattner 
44030fdc8d8SChris Lattner         const lldb::OptionDefinition*
44130fdc8d8SChris Lattner         GetDefinitions ()
44230fdc8d8SChris Lattner         {
44330fdc8d8SChris Lattner             return g_option_table;
44430fdc8d8SChris Lattner         }
44530fdc8d8SChris Lattner 
4465aee162fSJim Ingham         virtual bool
447a7015092SGreg Clayton         HandleOptionArgumentCompletion (CommandInterpreter &interpeter,
4485aee162fSJim Ingham                                         Args &input,
4495aee162fSJim Ingham                                         int cursor_index,
4505aee162fSJim Ingham                                         int char_pos,
4515aee162fSJim Ingham                                         OptionElementVector &opt_element_vector,
4525aee162fSJim Ingham                                         int opt_element_index,
4535aee162fSJim Ingham                                         int match_start_point,
4545aee162fSJim Ingham                                         int max_return_elements,
4555aee162fSJim Ingham                                         bool &word_complete,
4565aee162fSJim Ingham                                         StringList &matches)
4575aee162fSJim Ingham         {
4585aee162fSJim Ingham             int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
4595aee162fSJim Ingham             int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
4605aee162fSJim Ingham 
4615aee162fSJim Ingham             // We are only completing the name option for now...
4625aee162fSJim Ingham 
4635aee162fSJim Ingham             const lldb::OptionDefinition *opt_defs = GetDefinitions();
4645aee162fSJim Ingham             if (opt_defs[opt_defs_index].short_option == 'n')
4655aee162fSJim Ingham             {
4665aee162fSJim Ingham                 // Are we in the name?
4675aee162fSJim Ingham 
4685aee162fSJim Ingham                 // Look to see if there is a -P argument provided, and if so use that plugin, otherwise
4695aee162fSJim Ingham                 // use the default plugin.
470a7015092SGreg Clayton                 Process *process = interpeter.GetDebugger().GetExecutionContext().process;
4715aee162fSJim Ingham                 bool need_to_delete_process = false;
4725aee162fSJim Ingham 
4735aee162fSJim Ingham                 const char *partial_name = NULL;
4745aee162fSJim Ingham                 partial_name = input.GetArgumentAtIndex(opt_arg_pos);
4755aee162fSJim Ingham 
4765aee162fSJim Ingham                 if (process && process->IsAlive())
4775aee162fSJim Ingham                     return true;
4785aee162fSJim Ingham 
479a7015092SGreg Clayton                 Target *target = interpeter.GetDebugger().GetSelectedTarget().get();
4805aee162fSJim Ingham                 if (target == NULL)
4815aee162fSJim Ingham                 {
4825aee162fSJim Ingham                     // No target has been set yet, for now do host completion.  Otherwise I don't know how we would
4835aee162fSJim Ingham                     // figure out what the right target to use is...
4845aee162fSJim Ingham                     std::vector<lldb::pid_t> pids;
4855aee162fSJim Ingham                     Host::ListProcessesMatchingName (partial_name, matches, pids);
4865aee162fSJim Ingham                     return true;
4875aee162fSJim Ingham                 }
4885aee162fSJim Ingham                 if (!process)
4895aee162fSJim Ingham                 {
490a7015092SGreg Clayton                     process = target->CreateProcess (interpeter.GetDebugger().GetListener(), partial_name).get();
4915aee162fSJim Ingham                     need_to_delete_process = true;
4925aee162fSJim Ingham                 }
4935aee162fSJim Ingham 
4945aee162fSJim Ingham                 if (process)
4955aee162fSJim Ingham                 {
4965aee162fSJim Ingham                     matches.Clear();
4975aee162fSJim Ingham                     std::vector<lldb::pid_t> pids;
4985aee162fSJim Ingham                     process->ListProcessesMatchingName (NULL, matches, pids);
4995aee162fSJim Ingham                     if (need_to_delete_process)
5005aee162fSJim Ingham                         target->DeleteCurrentProcess();
5015aee162fSJim Ingham                     return true;
5025aee162fSJim Ingham                 }
5035aee162fSJim Ingham             }
5045aee162fSJim Ingham 
5055aee162fSJim Ingham             return false;
5065aee162fSJim Ingham         }
5075aee162fSJim Ingham 
50830fdc8d8SChris Lattner         // Options table: Required for subclasses of Options.
50930fdc8d8SChris Lattner 
51030fdc8d8SChris Lattner         static lldb::OptionDefinition g_option_table[];
51130fdc8d8SChris Lattner 
51230fdc8d8SChris Lattner         // Instance variables to hold the values for command options.
51330fdc8d8SChris Lattner 
51430fdc8d8SChris Lattner         lldb::pid_t pid;
51530fdc8d8SChris Lattner         std::string plugin_name;
51630fdc8d8SChris Lattner         std::string name;
51730fdc8d8SChris Lattner         bool waitfor;
51830fdc8d8SChris Lattner     };
51930fdc8d8SChris Lattner 
520a7015092SGreg Clayton     CommandObjectProcessAttach (CommandInterpreter &interpreter) :
521a7015092SGreg Clayton         CommandObject (interpreter,
522a7015092SGreg Clayton                        "process attach",
523e3d26315SCaroline Tice                        "Attach to a process.",
5245aee162fSJim Ingham                        "process attach <cmd-options>")
5255aee162fSJim Ingham     {
5265aee162fSJim Ingham     }
5275aee162fSJim Ingham 
5285aee162fSJim Ingham     ~CommandObjectProcessAttach ()
5295aee162fSJim Ingham     {
5305aee162fSJim Ingham     }
5315aee162fSJim Ingham 
5325aee162fSJim Ingham     bool
533a7015092SGreg Clayton     Execute (Args& command,
5345aee162fSJim Ingham              CommandReturnObject &result)
5355aee162fSJim Ingham     {
536a7015092SGreg Clayton         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
5375aee162fSJim Ingham 
538a7015092SGreg Clayton         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
5395aee162fSJim Ingham         if (process)
5405aee162fSJim Ingham         {
5415aee162fSJim Ingham             if (process->IsAlive())
5425aee162fSJim Ingham             {
5435aee162fSJim Ingham                 result.AppendErrorWithFormat ("Process %u is currently being debugged, kill the process before attaching.\n",
5445aee162fSJim Ingham                                               process->GetID());
5455aee162fSJim Ingham                 result.SetStatus (eReturnStatusFailed);
5465aee162fSJim Ingham                 return false;
5475aee162fSJim Ingham             }
5485aee162fSJim Ingham         }
5495aee162fSJim Ingham 
5505aee162fSJim Ingham         if (target == NULL)
5515aee162fSJim Ingham         {
5525aee162fSJim Ingham             // If there isn't a current target create one.
5535aee162fSJim Ingham             TargetSP new_target_sp;
5545aee162fSJim Ingham             FileSpec emptyFileSpec;
5555aee162fSJim Ingham             ArchSpec emptyArchSpec;
5565aee162fSJim Ingham             Error error;
5575aee162fSJim Ingham 
558a7015092SGreg Clayton             error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(),
5595aee162fSJim Ingham                                                                               emptyFileSpec,
5605aee162fSJim Ingham                                                                               emptyArchSpec,
5615aee162fSJim Ingham                                                                               NULL,
5625aee162fSJim Ingham                                                                               false,
5635aee162fSJim Ingham                                                                               new_target_sp);
5645aee162fSJim Ingham             target = new_target_sp.get();
5655aee162fSJim Ingham             if (target == NULL || error.Fail())
5665aee162fSJim Ingham             {
5675aee162fSJim Ingham                 result.AppendError(error.AsCString("Error creating empty target"));
5685aee162fSJim Ingham                 return false;
5695aee162fSJim Ingham             }
570a7015092SGreg Clayton             m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target);
5715aee162fSJim Ingham         }
5725aee162fSJim Ingham 
5735aee162fSJim Ingham         // Record the old executable module, we want to issue a warning if the process of attaching changed the
5745aee162fSJim Ingham         // current executable (like somebody said "file foo" then attached to a PID whose executable was bar.)
5755aee162fSJim Ingham 
5765aee162fSJim Ingham         ModuleSP old_exec_module_sp = target->GetExecutableModule();
5775aee162fSJim Ingham         ArchSpec old_arch_spec = target->GetArchitecture();
5785aee162fSJim Ingham 
5795aee162fSJim Ingham         if (command.GetArgumentCount())
5805aee162fSJim Ingham         {
5815aee162fSJim Ingham             result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: \n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
5825aee162fSJim Ingham             result.SetStatus (eReturnStatusFailed);
5835aee162fSJim Ingham         }
5845aee162fSJim Ingham         else
5855aee162fSJim Ingham         {
5865aee162fSJim Ingham             const char *plugin_name = NULL;
5875aee162fSJim Ingham 
5885aee162fSJim Ingham             if (!m_options.plugin_name.empty())
5895aee162fSJim Ingham                 plugin_name = m_options.plugin_name.c_str();
5905aee162fSJim Ingham 
591a7015092SGreg Clayton             process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name).get();
5925aee162fSJim Ingham 
5935aee162fSJim Ingham             if (process)
5945aee162fSJim Ingham             {
5955aee162fSJim Ingham                 Error error;
5965aee162fSJim Ingham                 int attach_pid = m_options.pid;
5975aee162fSJim Ingham 
5983a0b9cdfSJim Ingham                 const char *wait_name = NULL;
5993a0b9cdfSJim Ingham 
6005aee162fSJim Ingham                 if (m_options.name.empty())
6015aee162fSJim Ingham                 {
6023a0b9cdfSJim Ingham                     if (old_exec_module_sp)
6033a0b9cdfSJim Ingham                     {
6043a0b9cdfSJim Ingham                         wait_name = old_exec_module_sp->GetFileSpec().GetFilename().AsCString();
6053a0b9cdfSJim Ingham                     }
6065aee162fSJim Ingham                 }
6075aee162fSJim Ingham                 else
6085aee162fSJim Ingham                 {
6093a0b9cdfSJim Ingham                     wait_name = m_options.name.c_str();
6103a0b9cdfSJim Ingham                 }
6113a0b9cdfSJim Ingham 
6123a0b9cdfSJim Ingham                 // If we are waiting for a process with this name to show up, do that first.
6133a0b9cdfSJim Ingham                 if (m_options.waitfor)
6143a0b9cdfSJim Ingham                 {
6153a0b9cdfSJim Ingham 
6163a0b9cdfSJim Ingham                     if (wait_name == NULL)
6173a0b9cdfSJim Ingham                     {
6183a0b9cdfSJim Ingham                         result.AppendError("Invalid arguments: must have a file loaded or supply a process name with the waitfor option.\n");
6193a0b9cdfSJim Ingham                         result.SetStatus (eReturnStatusFailed);
6203a0b9cdfSJim Ingham                         return false;
6213a0b9cdfSJim Ingham                     }
6223a0b9cdfSJim Ingham 
623a7015092SGreg Clayton                     m_interpreter.GetDebugger().GetOutputStream().Printf("Waiting to attach to a process named \"%s\".\n", wait_name);
6243a0b9cdfSJim Ingham                     error = process->Attach (wait_name, m_options.waitfor);
6255aee162fSJim Ingham                     if (error.Success())
6265aee162fSJim Ingham                     {
6275aee162fSJim Ingham                         result.SetStatus (eReturnStatusSuccessContinuingNoResult);
6285aee162fSJim Ingham                     }
6295aee162fSJim Ingham                     else
6305aee162fSJim Ingham                     {
6315aee162fSJim Ingham                         result.AppendErrorWithFormat ("Waiting for a process to launch named '%s': %s\n",
6323a0b9cdfSJim Ingham                                                          wait_name,
6335aee162fSJim Ingham                                                          error.AsCString());
6345aee162fSJim Ingham                         result.SetStatus (eReturnStatusFailed);
6355aee162fSJim Ingham                         return false;
6365aee162fSJim Ingham                     }
6375aee162fSJim Ingham                 }
6385aee162fSJim Ingham                 else
6395aee162fSJim Ingham                 {
6405aee162fSJim Ingham                     // If the process was specified by name look it up, so we can warn if there are multiple
6415aee162fSJim Ingham                     // processes with this pid.
6425aee162fSJim Ingham 
6433a0b9cdfSJim Ingham                     if (attach_pid == LLDB_INVALID_PROCESS_ID && wait_name != NULL)
6445aee162fSJim Ingham                     {
6455aee162fSJim Ingham                         std::vector<lldb::pid_t> pids;
6465aee162fSJim Ingham                         StringList matches;
6475aee162fSJim Ingham 
6483a0b9cdfSJim Ingham                         process->ListProcessesMatchingName(wait_name, matches, pids);
6495aee162fSJim Ingham                         if (matches.GetSize() > 1)
6505aee162fSJim Ingham                         {
6513a0b9cdfSJim Ingham                             result.AppendErrorWithFormat("More than one process named %s\n", wait_name);
6525aee162fSJim Ingham                             result.SetStatus (eReturnStatusFailed);
6535aee162fSJim Ingham                             return false;
6545aee162fSJim Ingham                         }
6555aee162fSJim Ingham                         else if (matches.GetSize() == 0)
6565aee162fSJim Ingham                         {
6573a0b9cdfSJim Ingham                             result.AppendErrorWithFormat("Could not find a process named %s\n", wait_name);
6585aee162fSJim Ingham                             result.SetStatus (eReturnStatusFailed);
6595aee162fSJim Ingham                             return false;
6605aee162fSJim Ingham                         }
6615aee162fSJim Ingham                         else
6625aee162fSJim Ingham                         {
6635aee162fSJim Ingham                             attach_pid = pids[0];
6645aee162fSJim Ingham                         }
6655aee162fSJim Ingham 
6665aee162fSJim Ingham                     }
6675aee162fSJim Ingham 
6685aee162fSJim Ingham                     if (attach_pid != LLDB_INVALID_PROCESS_ID)
6695aee162fSJim Ingham                     {
6705aee162fSJim Ingham                         error = process->Attach (attach_pid);
6715aee162fSJim Ingham                         if (error.Success())
6725aee162fSJim Ingham                         {
6735aee162fSJim Ingham                             result.SetStatus (eReturnStatusSuccessContinuingNoResult);
6745aee162fSJim Ingham                         }
6755aee162fSJim Ingham                         else
6765aee162fSJim Ingham                         {
6775aee162fSJim Ingham                             result.AppendErrorWithFormat ("Attaching to process %i failed: %s.\n",
6785aee162fSJim Ingham                                                          attach_pid,
6795aee162fSJim Ingham                                                          error.AsCString());
6805aee162fSJim Ingham                             result.SetStatus (eReturnStatusFailed);
6815aee162fSJim Ingham                         }
6825aee162fSJim Ingham                     }
6835aee162fSJim Ingham                     else
6845aee162fSJim Ingham                     {
6855aee162fSJim Ingham                         result.AppendErrorWithFormat ("No PID specified for attach\n",
6865aee162fSJim Ingham                                                          attach_pid,
6875aee162fSJim Ingham                                                          error.AsCString());
6885aee162fSJim Ingham                         result.SetStatus (eReturnStatusFailed);
6895aee162fSJim Ingham 
6905aee162fSJim Ingham                     }
6915aee162fSJim Ingham                 }
6925aee162fSJim Ingham             }
6935aee162fSJim Ingham         }
6945aee162fSJim Ingham 
6955aee162fSJim Ingham         if (result.Succeeded())
6965aee162fSJim Ingham         {
6975aee162fSJim Ingham             // Okay, we're done.  Last step is to warn if the executable module has changed:
6985aee162fSJim Ingham             if (!old_exec_module_sp)
6995aee162fSJim Ingham             {
7005aee162fSJim Ingham                 char new_path[PATH_MAX + 1];
7015aee162fSJim Ingham                 target->GetExecutableModule()->GetFileSpec().GetPath(new_path, PATH_MAX);
7025aee162fSJim Ingham 
7035aee162fSJim Ingham                 result.AppendMessageWithFormat("Executable module set to \"%s\".\n",
7045aee162fSJim Ingham                     new_path);
7055aee162fSJim Ingham             }
7065aee162fSJim Ingham             else if (old_exec_module_sp->GetFileSpec() != target->GetExecutableModule()->GetFileSpec())
7075aee162fSJim Ingham             {
7085aee162fSJim Ingham                 char old_path[PATH_MAX + 1];
7095aee162fSJim Ingham                 char new_path[PATH_MAX + 1];
7105aee162fSJim Ingham 
7115aee162fSJim Ingham                 old_exec_module_sp->GetFileSpec().GetPath(old_path, PATH_MAX);
7125aee162fSJim Ingham                 target->GetExecutableModule()->GetFileSpec().GetPath (new_path, PATH_MAX);
7135aee162fSJim Ingham 
7145aee162fSJim Ingham                 result.AppendWarningWithFormat("Executable module changed from \"%s\" to \"%s\".\n",
7155aee162fSJim Ingham                                                     old_path, new_path);
7165aee162fSJim Ingham             }
7175aee162fSJim Ingham 
7185aee162fSJim Ingham             if (!old_arch_spec.IsValid())
7195aee162fSJim Ingham             {
7205aee162fSJim Ingham                 result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().AsCString());
7215aee162fSJim Ingham             }
7225aee162fSJim Ingham             else if (old_arch_spec != target->GetArchitecture())
7235aee162fSJim Ingham             {
7245aee162fSJim Ingham                 result.AppendWarningWithFormat("Architecture changed from %s to %s.\n",
7255aee162fSJim Ingham                                                 old_arch_spec.AsCString(), target->GetArchitecture().AsCString());
7265aee162fSJim Ingham             }
7275aee162fSJim Ingham         }
7285aee162fSJim Ingham         return result.Succeeded();
7295aee162fSJim Ingham     }
7305aee162fSJim Ingham 
7315aee162fSJim Ingham     Options *
7325aee162fSJim Ingham     GetOptions ()
7335aee162fSJim Ingham     {
7345aee162fSJim Ingham         return &m_options;
7355aee162fSJim Ingham     }
7365aee162fSJim Ingham 
73730fdc8d8SChris Lattner protected:
73830fdc8d8SChris Lattner 
73930fdc8d8SChris Lattner     CommandOptions m_options;
74030fdc8d8SChris Lattner };
74130fdc8d8SChris Lattner 
74230fdc8d8SChris Lattner 
74330fdc8d8SChris Lattner lldb::OptionDefinition
74430fdc8d8SChris Lattner CommandObjectProcessAttach::CommandOptions::g_option_table[] =
74530fdc8d8SChris Lattner {
746deaab222SCaroline Tice { LLDB_OPT_SET_ALL, false, "plugin", 'P', required_argument, NULL, 0, eArgTypePlugin,        "Name of the process plugin you want to use."},
747deaab222SCaroline Tice { LLDB_OPT_SET_1,   false, "pid",    'p', required_argument, NULL, 0, eArgTypePid,           "The process ID of an existing process to attach to."},
748deaab222SCaroline Tice { LLDB_OPT_SET_2,   false, "name",   'n', required_argument, NULL, 0, eArgTypeProcessName,  "The name of the process to attach to."},
749deaab222SCaroline Tice { LLDB_OPT_SET_2,   false, "waitfor",'w', no_argument,       NULL, 0, eArgTypeNone,              "Wait for the the process with <process-name> to launch."},
750deaab222SCaroline Tice { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
75130fdc8d8SChris Lattner };
75230fdc8d8SChris Lattner 
75330fdc8d8SChris Lattner //-------------------------------------------------------------------------
75430fdc8d8SChris Lattner // CommandObjectProcessContinue
75530fdc8d8SChris Lattner //-------------------------------------------------------------------------
756*bb9caf73SJim Ingham #pragma mark CommandObjectProcessContinue
75730fdc8d8SChris Lattner 
75830fdc8d8SChris Lattner class CommandObjectProcessContinue : public CommandObject
75930fdc8d8SChris Lattner {
76030fdc8d8SChris Lattner public:
76130fdc8d8SChris Lattner 
762a7015092SGreg Clayton     CommandObjectProcessContinue (CommandInterpreter &interpreter) :
763a7015092SGreg Clayton         CommandObject (interpreter,
764a7015092SGreg Clayton                        "process continue",
765e3d26315SCaroline Tice                        "Continue execution of all threads in the current process.",
76630fdc8d8SChris Lattner                        "process continue",
76730fdc8d8SChris Lattner                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
76830fdc8d8SChris Lattner     {
76930fdc8d8SChris Lattner     }
77030fdc8d8SChris Lattner 
77130fdc8d8SChris Lattner 
77230fdc8d8SChris Lattner     ~CommandObjectProcessContinue ()
77330fdc8d8SChris Lattner     {
77430fdc8d8SChris Lattner     }
77530fdc8d8SChris Lattner 
77630fdc8d8SChris Lattner     bool
777a7015092SGreg Clayton     Execute (Args& command,
77830fdc8d8SChris Lattner              CommandReturnObject &result)
77930fdc8d8SChris Lattner     {
780a7015092SGreg Clayton         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
781a7015092SGreg Clayton         bool synchronous_execution = m_interpreter.GetSynchronous ();
78230fdc8d8SChris Lattner 
78330fdc8d8SChris Lattner         if (process == NULL)
78430fdc8d8SChris Lattner         {
78530fdc8d8SChris Lattner             result.AppendError ("no process to continue");
78630fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
78730fdc8d8SChris Lattner             return false;
78830fdc8d8SChris Lattner          }
78930fdc8d8SChris Lattner 
79030fdc8d8SChris Lattner         StateType state = process->GetState();
79130fdc8d8SChris Lattner         if (state == eStateStopped)
79230fdc8d8SChris Lattner         {
79330fdc8d8SChris Lattner             if (command.GetArgumentCount() != 0)
79430fdc8d8SChris Lattner             {
79530fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("The '%s' command does not take any arguments.\n", m_cmd_name.c_str());
79630fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
79730fdc8d8SChris Lattner                 return false;
79830fdc8d8SChris Lattner             }
79930fdc8d8SChris Lattner 
80030fdc8d8SChris Lattner             const uint32_t num_threads = process->GetThreadList().GetSize();
80130fdc8d8SChris Lattner 
80230fdc8d8SChris Lattner             // Set the actions that the threads should each take when resuming
80330fdc8d8SChris Lattner             for (uint32_t idx=0; idx<num_threads; ++idx)
80430fdc8d8SChris Lattner             {
80530fdc8d8SChris Lattner                 process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState (eStateRunning);
80630fdc8d8SChris Lattner             }
80730fdc8d8SChris Lattner 
80830fdc8d8SChris Lattner             Error error(process->Resume());
80930fdc8d8SChris Lattner             if (error.Success())
81030fdc8d8SChris Lattner             {
81119388cfcSGreg Clayton                 result.AppendMessageWithFormat ("Process %i resuming\n", process->GetID());
81230fdc8d8SChris Lattner                 if (synchronous_execution)
81330fdc8d8SChris Lattner                 {
814b132097bSGreg Clayton                     state = process->WaitForProcessToStop (NULL);
81530fdc8d8SChris Lattner 
81630fdc8d8SChris Lattner                     result.SetDidChangeProcessState (true);
81730fdc8d8SChris Lattner                     result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state));
81830fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
81930fdc8d8SChris Lattner                 }
82030fdc8d8SChris Lattner                 else
82130fdc8d8SChris Lattner                 {
82230fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusSuccessContinuingNoResult);
82330fdc8d8SChris Lattner                 }
82430fdc8d8SChris Lattner             }
82530fdc8d8SChris Lattner             else
82630fdc8d8SChris Lattner             {
82730fdc8d8SChris Lattner                 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
82830fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
82930fdc8d8SChris Lattner             }
83030fdc8d8SChris Lattner         }
83130fdc8d8SChris Lattner         else
83230fdc8d8SChris Lattner         {
83330fdc8d8SChris Lattner             result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
83430fdc8d8SChris Lattner                                          StateAsCString(state));
83530fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
83630fdc8d8SChris Lattner         }
83730fdc8d8SChris Lattner         return result.Succeeded();
83830fdc8d8SChris Lattner     }
83930fdc8d8SChris Lattner };
84030fdc8d8SChris Lattner 
84130fdc8d8SChris Lattner //-------------------------------------------------------------------------
84230fdc8d8SChris Lattner // CommandObjectProcessDetach
84330fdc8d8SChris Lattner //-------------------------------------------------------------------------
844*bb9caf73SJim Ingham #pragma mark CommandObjectProcessDetach
84530fdc8d8SChris Lattner 
84630fdc8d8SChris Lattner class CommandObjectProcessDetach : public CommandObject
84730fdc8d8SChris Lattner {
84830fdc8d8SChris Lattner public:
84930fdc8d8SChris Lattner 
850a7015092SGreg Clayton     CommandObjectProcessDetach (CommandInterpreter &interpreter) :
851a7015092SGreg Clayton         CommandObject (interpreter,
852a7015092SGreg Clayton                        "process detach",
853e3d26315SCaroline Tice                        "Detach from the current process being debugged.",
85430fdc8d8SChris Lattner                        "process detach",
85530fdc8d8SChris Lattner                        eFlagProcessMustBeLaunched)
85630fdc8d8SChris Lattner     {
85730fdc8d8SChris Lattner     }
85830fdc8d8SChris Lattner 
85930fdc8d8SChris Lattner     ~CommandObjectProcessDetach ()
86030fdc8d8SChris Lattner     {
86130fdc8d8SChris Lattner     }
86230fdc8d8SChris Lattner 
86330fdc8d8SChris Lattner     bool
864a7015092SGreg Clayton     Execute (Args& command,
86530fdc8d8SChris Lattner              CommandReturnObject &result)
86630fdc8d8SChris Lattner     {
867a7015092SGreg Clayton         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
86830fdc8d8SChris Lattner         if (process == NULL)
86930fdc8d8SChris Lattner         {
87030fdc8d8SChris Lattner             result.AppendError ("must have a valid process in order to detach");
87130fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
87230fdc8d8SChris Lattner             return false;
87330fdc8d8SChris Lattner         }
87430fdc8d8SChris Lattner 
8755d7be2e6SCaroline Tice         result.AppendMessageWithFormat ("Detaching from process %i\n", process->GetID());
87630fdc8d8SChris Lattner         Error error (process->Detach());
87730fdc8d8SChris Lattner         if (error.Success())
87830fdc8d8SChris Lattner         {
87930fdc8d8SChris Lattner             result.SetStatus (eReturnStatusSuccessFinishResult);
88030fdc8d8SChris Lattner         }
88130fdc8d8SChris Lattner         else
88230fdc8d8SChris Lattner         {
88330fdc8d8SChris Lattner             result.AppendErrorWithFormat ("Detach failed: %s\n", error.AsCString());
88430fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
88530fdc8d8SChris Lattner             return false;
88630fdc8d8SChris Lattner         }
88730fdc8d8SChris Lattner         return result.Succeeded();
88830fdc8d8SChris Lattner     }
88930fdc8d8SChris Lattner };
89030fdc8d8SChris Lattner 
89130fdc8d8SChris Lattner //-------------------------------------------------------------------------
8928f343b09SGreg Clayton // CommandObjectProcessLoad
8938f343b09SGreg Clayton //-------------------------------------------------------------------------
894*bb9caf73SJim Ingham #pragma mark CommandObjectProcessLoad
8958f343b09SGreg Clayton 
8968f343b09SGreg Clayton class CommandObjectProcessLoad : public CommandObject
8978f343b09SGreg Clayton {
8988f343b09SGreg Clayton public:
8998f343b09SGreg Clayton 
9008f343b09SGreg Clayton     CommandObjectProcessLoad (CommandInterpreter &interpreter) :
9018f343b09SGreg Clayton         CommandObject (interpreter,
9028f343b09SGreg Clayton                        "process load",
9038f343b09SGreg Clayton                        "Load a shared library into the current process.",
9048f343b09SGreg Clayton                        "process load <filename> [<filename> ...]",
9058f343b09SGreg Clayton                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
9068f343b09SGreg Clayton     {
9078f343b09SGreg Clayton     }
9088f343b09SGreg Clayton 
9098f343b09SGreg Clayton     ~CommandObjectProcessLoad ()
9108f343b09SGreg Clayton     {
9118f343b09SGreg Clayton     }
9128f343b09SGreg Clayton 
9138f343b09SGreg Clayton     bool
9148f343b09SGreg Clayton     Execute (Args& command,
9158f343b09SGreg Clayton              CommandReturnObject &result)
9168f343b09SGreg Clayton     {
9178f343b09SGreg Clayton         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
9188f343b09SGreg Clayton         if (process == NULL)
9198f343b09SGreg Clayton         {
9208f343b09SGreg Clayton             result.AppendError ("must have a valid process in order to load a shared library");
9218f343b09SGreg Clayton             result.SetStatus (eReturnStatusFailed);
9228f343b09SGreg Clayton             return false;
9238f343b09SGreg Clayton         }
9248f343b09SGreg Clayton 
9258f343b09SGreg Clayton         const uint32_t argc = command.GetArgumentCount();
9268f343b09SGreg Clayton 
9278f343b09SGreg Clayton         for (uint32_t i=0; i<argc; ++i)
9288f343b09SGreg Clayton         {
9298f343b09SGreg Clayton             Error error;
9308f343b09SGreg Clayton             const char *image_path = command.GetArgumentAtIndex(i);
9318f343b09SGreg Clayton             FileSpec image_spec (image_path, false);
9328f343b09SGreg Clayton             uint32_t image_token = process->LoadImage(image_spec, error);
9338f343b09SGreg Clayton             if (image_token != LLDB_INVALID_IMAGE_TOKEN)
9348f343b09SGreg Clayton             {
9358f343b09SGreg Clayton                 result.AppendMessageWithFormat ("Loading \"%s\"...ok\nImage %u loaded.\n", image_path, image_token);
9368f343b09SGreg Clayton                 result.SetStatus (eReturnStatusSuccessFinishResult);
9378f343b09SGreg Clayton             }
9388f343b09SGreg Clayton             else
9398f343b09SGreg Clayton             {
9408f343b09SGreg Clayton                 result.AppendErrorWithFormat ("failed to load '%s': %s", image_path, error.AsCString());
9418f343b09SGreg Clayton                 result.SetStatus (eReturnStatusFailed);
9428f343b09SGreg Clayton             }
9438f343b09SGreg Clayton         }
9448f343b09SGreg Clayton         return result.Succeeded();
9458f343b09SGreg Clayton     }
9468f343b09SGreg Clayton };
9478f343b09SGreg Clayton 
9488f343b09SGreg Clayton 
9498f343b09SGreg Clayton //-------------------------------------------------------------------------
9508f343b09SGreg Clayton // CommandObjectProcessUnload
9518f343b09SGreg Clayton //-------------------------------------------------------------------------
952*bb9caf73SJim Ingham #pragma mark CommandObjectProcessUnload
9538f343b09SGreg Clayton 
9548f343b09SGreg Clayton class CommandObjectProcessUnload : public CommandObject
9558f343b09SGreg Clayton {
9568f343b09SGreg Clayton public:
9578f343b09SGreg Clayton 
9588f343b09SGreg Clayton     CommandObjectProcessUnload (CommandInterpreter &interpreter) :
9598f343b09SGreg Clayton         CommandObject (interpreter,
9608f343b09SGreg Clayton                        "process unload",
9618f343b09SGreg Clayton                        "Unload a shared library from the current process using the index returned by a previous call to \"process load\".",
9628f343b09SGreg Clayton                        "process unload <index>",
9638f343b09SGreg Clayton                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
9648f343b09SGreg Clayton     {
9658f343b09SGreg Clayton     }
9668f343b09SGreg Clayton 
9678f343b09SGreg Clayton     ~CommandObjectProcessUnload ()
9688f343b09SGreg Clayton     {
9698f343b09SGreg Clayton     }
9708f343b09SGreg Clayton 
9718f343b09SGreg Clayton     bool
9728f343b09SGreg Clayton     Execute (Args& command,
9738f343b09SGreg Clayton              CommandReturnObject &result)
9748f343b09SGreg Clayton     {
9758f343b09SGreg Clayton         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
9768f343b09SGreg Clayton         if (process == NULL)
9778f343b09SGreg Clayton         {
9788f343b09SGreg Clayton             result.AppendError ("must have a valid process in order to load a shared library");
9798f343b09SGreg Clayton             result.SetStatus (eReturnStatusFailed);
9808f343b09SGreg Clayton             return false;
9818f343b09SGreg Clayton         }
9828f343b09SGreg Clayton 
9838f343b09SGreg Clayton         const uint32_t argc = command.GetArgumentCount();
9848f343b09SGreg Clayton 
9858f343b09SGreg Clayton         for (uint32_t i=0; i<argc; ++i)
9868f343b09SGreg Clayton         {
9878f343b09SGreg Clayton             const char *image_token_cstr = command.GetArgumentAtIndex(i);
9888f343b09SGreg Clayton             uint32_t image_token = Args::StringToUInt32(image_token_cstr, LLDB_INVALID_IMAGE_TOKEN, 0);
9898f343b09SGreg Clayton             if (image_token == LLDB_INVALID_IMAGE_TOKEN)
9908f343b09SGreg Clayton             {
9918f343b09SGreg Clayton                 result.AppendErrorWithFormat ("invalid image index argument '%s'", image_token_cstr);
9928f343b09SGreg Clayton                 result.SetStatus (eReturnStatusFailed);
9938f343b09SGreg Clayton                 break;
9948f343b09SGreg Clayton             }
9958f343b09SGreg Clayton             else
9968f343b09SGreg Clayton             {
9978f343b09SGreg Clayton                 Error error (process->UnloadImage(image_token));
9988f343b09SGreg Clayton                 if (error.Success())
9998f343b09SGreg Clayton                 {
10008f343b09SGreg Clayton                     result.AppendMessageWithFormat ("Unloading shared library with index %u...ok\n", image_token);
10018f343b09SGreg Clayton                     result.SetStatus (eReturnStatusSuccessFinishResult);
10028f343b09SGreg Clayton                 }
10038f343b09SGreg Clayton                 else
10048f343b09SGreg Clayton                 {
10058f343b09SGreg Clayton                     result.AppendErrorWithFormat ("failed to unload image: %s", error.AsCString());
10068f343b09SGreg Clayton                     result.SetStatus (eReturnStatusFailed);
10078f343b09SGreg Clayton                     break;
10088f343b09SGreg Clayton                 }
10098f343b09SGreg Clayton             }
10108f343b09SGreg Clayton         }
10118f343b09SGreg Clayton         return result.Succeeded();
10128f343b09SGreg Clayton     }
10138f343b09SGreg Clayton };
10148f343b09SGreg Clayton 
10158f343b09SGreg Clayton //-------------------------------------------------------------------------
101630fdc8d8SChris Lattner // CommandObjectProcessSignal
101730fdc8d8SChris Lattner //-------------------------------------------------------------------------
1018*bb9caf73SJim Ingham #pragma mark CommandObjectProcessSignal
101930fdc8d8SChris Lattner 
102030fdc8d8SChris Lattner class CommandObjectProcessSignal : public CommandObject
102130fdc8d8SChris Lattner {
102230fdc8d8SChris Lattner public:
102330fdc8d8SChris Lattner 
1024a7015092SGreg Clayton     CommandObjectProcessSignal (CommandInterpreter &interpreter) :
1025a7015092SGreg Clayton         CommandObject (interpreter,
1026a7015092SGreg Clayton                        "process signal",
1027e3d26315SCaroline Tice                        "Send a UNIX signal to the current process being debugged.",
1028405fe67fSCaroline Tice                        NULL)
102930fdc8d8SChris Lattner     {
1030405fe67fSCaroline Tice         CommandArgumentEntry arg;
1031405fe67fSCaroline Tice         CommandArgumentData signal_arg;
1032405fe67fSCaroline Tice 
1033405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
1034c0dbdfb6SCaroline Tice         signal_arg.arg_type = eArgTypeUnixSignal;
1035405fe67fSCaroline Tice         signal_arg.arg_repetition = eArgRepeatPlain;
1036405fe67fSCaroline Tice 
1037405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
1038405fe67fSCaroline Tice         arg.push_back (signal_arg);
1039405fe67fSCaroline Tice 
1040405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
1041405fe67fSCaroline Tice         m_arguments.push_back (arg);
104230fdc8d8SChris Lattner     }
104330fdc8d8SChris Lattner 
104430fdc8d8SChris Lattner     ~CommandObjectProcessSignal ()
104530fdc8d8SChris Lattner     {
104630fdc8d8SChris Lattner     }
104730fdc8d8SChris Lattner 
104830fdc8d8SChris Lattner     bool
1049a7015092SGreg Clayton     Execute (Args& command,
105030fdc8d8SChris Lattner              CommandReturnObject &result)
105130fdc8d8SChris Lattner     {
1052a7015092SGreg Clayton         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
105330fdc8d8SChris Lattner         if (process == NULL)
105430fdc8d8SChris Lattner         {
105530fdc8d8SChris Lattner             result.AppendError ("no process to signal");
105630fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
105730fdc8d8SChris Lattner             return false;
105830fdc8d8SChris Lattner         }
105930fdc8d8SChris Lattner 
106030fdc8d8SChris Lattner         if (command.GetArgumentCount() == 1)
106130fdc8d8SChris Lattner         {
1062237cd906SGreg Clayton             int signo = LLDB_INVALID_SIGNAL_NUMBER;
1063237cd906SGreg Clayton 
1064237cd906SGreg Clayton             const char *signal_name = command.GetArgumentAtIndex(0);
1065237cd906SGreg Clayton             if (::isxdigit (signal_name[0]))
1066237cd906SGreg Clayton                 signo = Args::StringToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0);
1067237cd906SGreg Clayton             else
1068237cd906SGreg Clayton                 signo = process->GetUnixSignals().GetSignalNumberFromName (signal_name);
1069237cd906SGreg Clayton 
1070237cd906SGreg Clayton             if (signo == LLDB_INVALID_SIGNAL_NUMBER)
107130fdc8d8SChris Lattner             {
107230fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("Invalid signal argument '%s'.\n", command.GetArgumentAtIndex(0));
107330fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
107430fdc8d8SChris Lattner             }
107530fdc8d8SChris Lattner             else
107630fdc8d8SChris Lattner             {
107730fdc8d8SChris Lattner                 Error error (process->Signal (signo));
107830fdc8d8SChris Lattner                 if (error.Success())
107930fdc8d8SChris Lattner                 {
108030fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusSuccessFinishResult);
108130fdc8d8SChris Lattner                 }
108230fdc8d8SChris Lattner                 else
108330fdc8d8SChris Lattner                 {
108430fdc8d8SChris Lattner                     result.AppendErrorWithFormat ("Failed to send signal %i: %s\n", signo, error.AsCString());
108530fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
108630fdc8d8SChris Lattner                 }
108730fdc8d8SChris Lattner             }
108830fdc8d8SChris Lattner         }
108930fdc8d8SChris Lattner         else
109030fdc8d8SChris Lattner         {
109130fdc8d8SChris Lattner             result.AppendErrorWithFormat("'%s' takes exactly one signal number argument:\nUsage: \n", m_cmd_name.c_str(),
109230fdc8d8SChris Lattner                                         m_cmd_syntax.c_str());
109330fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
109430fdc8d8SChris Lattner         }
109530fdc8d8SChris Lattner         return result.Succeeded();
109630fdc8d8SChris Lattner     }
109730fdc8d8SChris Lattner };
109830fdc8d8SChris Lattner 
109930fdc8d8SChris Lattner 
110030fdc8d8SChris Lattner //-------------------------------------------------------------------------
110130fdc8d8SChris Lattner // CommandObjectProcessInterrupt
110230fdc8d8SChris Lattner //-------------------------------------------------------------------------
1103*bb9caf73SJim Ingham #pragma mark CommandObjectProcessInterrupt
110430fdc8d8SChris Lattner 
110530fdc8d8SChris Lattner class CommandObjectProcessInterrupt : public CommandObject
110630fdc8d8SChris Lattner {
110730fdc8d8SChris Lattner public:
110830fdc8d8SChris Lattner 
110930fdc8d8SChris Lattner 
1110a7015092SGreg Clayton     CommandObjectProcessInterrupt (CommandInterpreter &interpreter) :
1111a7015092SGreg Clayton     CommandObject (interpreter,
1112a7015092SGreg Clayton                    "process interrupt",
1113e3d26315SCaroline Tice                    "Interrupt the current process being debugged.",
111430fdc8d8SChris Lattner                    "process interrupt",
111530fdc8d8SChris Lattner                    eFlagProcessMustBeLaunched)
111630fdc8d8SChris Lattner     {
111730fdc8d8SChris Lattner     }
111830fdc8d8SChris Lattner 
111930fdc8d8SChris Lattner     ~CommandObjectProcessInterrupt ()
112030fdc8d8SChris Lattner     {
112130fdc8d8SChris Lattner     }
112230fdc8d8SChris Lattner 
112330fdc8d8SChris Lattner     bool
1124a7015092SGreg Clayton     Execute (Args& command,
112530fdc8d8SChris Lattner              CommandReturnObject &result)
112630fdc8d8SChris Lattner     {
1127a7015092SGreg Clayton         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
112830fdc8d8SChris Lattner         if (process == NULL)
112930fdc8d8SChris Lattner         {
113030fdc8d8SChris Lattner             result.AppendError ("no process to halt");
113130fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
113230fdc8d8SChris Lattner             return false;
113330fdc8d8SChris Lattner         }
113430fdc8d8SChris Lattner 
113530fdc8d8SChris Lattner         if (command.GetArgumentCount() == 0)
113630fdc8d8SChris Lattner         {
113730fdc8d8SChris Lattner             Error error(process->Halt ());
113830fdc8d8SChris Lattner             if (error.Success())
113930fdc8d8SChris Lattner             {
114030fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusSuccessFinishResult);
114130fdc8d8SChris Lattner 
114230fdc8d8SChris Lattner                 // Maybe we should add a "SuspendThreadPlans so we
114330fdc8d8SChris Lattner                 // can halt, and keep in place all the current thread plans.
114430fdc8d8SChris Lattner                 process->GetThreadList().DiscardThreadPlans();
114530fdc8d8SChris Lattner             }
114630fdc8d8SChris Lattner             else
114730fdc8d8SChris Lattner             {
114830fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("Failed to halt process: %s\n", error.AsCString());
114930fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
115030fdc8d8SChris Lattner             }
115130fdc8d8SChris Lattner         }
115230fdc8d8SChris Lattner         else
115330fdc8d8SChris Lattner         {
115430fdc8d8SChris Lattner             result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: \n",
115530fdc8d8SChris Lattner                                         m_cmd_name.c_str(),
115630fdc8d8SChris Lattner                                         m_cmd_syntax.c_str());
115730fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
115830fdc8d8SChris Lattner         }
115930fdc8d8SChris Lattner         return result.Succeeded();
116030fdc8d8SChris Lattner     }
116130fdc8d8SChris Lattner };
116230fdc8d8SChris Lattner 
116330fdc8d8SChris Lattner //-------------------------------------------------------------------------
116430fdc8d8SChris Lattner // CommandObjectProcessKill
116530fdc8d8SChris Lattner //-------------------------------------------------------------------------
1166*bb9caf73SJim Ingham #pragma mark CommandObjectProcessKill
116730fdc8d8SChris Lattner 
116830fdc8d8SChris Lattner class CommandObjectProcessKill : public CommandObject
116930fdc8d8SChris Lattner {
117030fdc8d8SChris Lattner public:
117130fdc8d8SChris Lattner 
1172a7015092SGreg Clayton     CommandObjectProcessKill (CommandInterpreter &interpreter) :
1173a7015092SGreg Clayton     CommandObject (interpreter,
1174a7015092SGreg Clayton                    "process kill",
1175e3d26315SCaroline Tice                    "Terminate the current process being debugged.",
117630fdc8d8SChris Lattner                    "process kill",
117730fdc8d8SChris Lattner                    eFlagProcessMustBeLaunched)
117830fdc8d8SChris Lattner     {
117930fdc8d8SChris Lattner     }
118030fdc8d8SChris Lattner 
118130fdc8d8SChris Lattner     ~CommandObjectProcessKill ()
118230fdc8d8SChris Lattner     {
118330fdc8d8SChris Lattner     }
118430fdc8d8SChris Lattner 
118530fdc8d8SChris Lattner     bool
1186a7015092SGreg Clayton     Execute (Args& command,
118730fdc8d8SChris Lattner              CommandReturnObject &result)
118830fdc8d8SChris Lattner     {
1189a7015092SGreg Clayton         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
119030fdc8d8SChris Lattner         if (process == NULL)
119130fdc8d8SChris Lattner         {
119230fdc8d8SChris Lattner             result.AppendError ("no process to kill");
119330fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
119430fdc8d8SChris Lattner             return false;
119530fdc8d8SChris Lattner         }
119630fdc8d8SChris Lattner 
119730fdc8d8SChris Lattner         if (command.GetArgumentCount() == 0)
119830fdc8d8SChris Lattner         {
119930fdc8d8SChris Lattner             Error error (process->Destroy());
120030fdc8d8SChris Lattner             if (error.Success())
120130fdc8d8SChris Lattner             {
120230fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusSuccessFinishResult);
120330fdc8d8SChris Lattner             }
120430fdc8d8SChris Lattner             else
120530fdc8d8SChris Lattner             {
120630fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString());
120730fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
120830fdc8d8SChris Lattner             }
120930fdc8d8SChris Lattner         }
121030fdc8d8SChris Lattner         else
121130fdc8d8SChris Lattner         {
121230fdc8d8SChris Lattner             result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: \n",
121330fdc8d8SChris Lattner                                         m_cmd_name.c_str(),
121430fdc8d8SChris Lattner                                         m_cmd_syntax.c_str());
121530fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
121630fdc8d8SChris Lattner         }
121730fdc8d8SChris Lattner         return result.Succeeded();
121830fdc8d8SChris Lattner     }
121930fdc8d8SChris Lattner };
122030fdc8d8SChris Lattner 
122130fdc8d8SChris Lattner //-------------------------------------------------------------------------
12224b9bea87SJim Ingham // CommandObjectProcessStatus
12234b9bea87SJim Ingham //-------------------------------------------------------------------------
1224*bb9caf73SJim Ingham #pragma mark CommandObjectProcessStatus
1225*bb9caf73SJim Ingham 
12264b9bea87SJim Ingham class CommandObjectProcessStatus : public CommandObject
12274b9bea87SJim Ingham {
12284b9bea87SJim Ingham public:
1229a7015092SGreg Clayton     CommandObjectProcessStatus (CommandInterpreter &interpreter) :
1230a7015092SGreg Clayton     CommandObject (interpreter,
1231a7015092SGreg Clayton                    "process status",
1232e3d26315SCaroline Tice                    "Show the current status and location of executing process.",
1233e3d26315SCaroline Tice                    "process status",
12344b9bea87SJim Ingham                    0)
12354b9bea87SJim Ingham     {
12364b9bea87SJim Ingham     }
12374b9bea87SJim Ingham 
12384b9bea87SJim Ingham     ~CommandObjectProcessStatus()
12394b9bea87SJim Ingham     {
12404b9bea87SJim Ingham     }
12414b9bea87SJim Ingham 
12424b9bea87SJim Ingham 
12434b9bea87SJim Ingham     bool
12444b9bea87SJim Ingham     Execute
12454b9bea87SJim Ingham     (
12464b9bea87SJim Ingham         Args& command,
12474b9bea87SJim Ingham         CommandReturnObject &result
12484b9bea87SJim Ingham     )
12494b9bea87SJim Ingham     {
12504b9bea87SJim Ingham         StreamString &output_stream = result.GetOutputStream();
12514b9bea87SJim Ingham         result.SetStatus (eReturnStatusSuccessFinishNoResult);
1252a7015092SGreg Clayton         ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext());
12534b9bea87SJim Ingham         if (exe_ctx.process)
12544b9bea87SJim Ingham         {
12554b9bea87SJim Ingham             const StateType state = exe_ctx.process->GetState();
12564b9bea87SJim Ingham             if (StateIsStoppedState(state))
12574b9bea87SJim Ingham             {
12584b9bea87SJim Ingham                 if (state == eStateExited)
12594b9bea87SJim Ingham                 {
12604b9bea87SJim Ingham                     int exit_status = exe_ctx.process->GetExitStatus();
12614b9bea87SJim Ingham                     const char *exit_description = exe_ctx.process->GetExitDescription();
12624b9bea87SJim Ingham                     output_stream.Printf ("Process %d exited with status = %i (0x%8.8x) %s\n",
12634b9bea87SJim Ingham                                           exe_ctx.process->GetID(),
12644b9bea87SJim Ingham                                           exit_status,
12654b9bea87SJim Ingham                                           exit_status,
12664b9bea87SJim Ingham                                           exit_description ? exit_description : "");
12674b9bea87SJim Ingham                 }
12684b9bea87SJim Ingham                 else
12694b9bea87SJim Ingham                 {
12704b9bea87SJim Ingham                     output_stream.Printf ("Process %d %s\n", exe_ctx.process->GetID(), StateAsCString (state));
12714b9bea87SJim Ingham                     if (exe_ctx.thread == NULL)
12724b9bea87SJim Ingham                         exe_ctx.thread = exe_ctx.process->GetThreadList().GetThreadAtIndex(0).get();
12734b9bea87SJim Ingham                     if (exe_ctx.thread != NULL)
12744b9bea87SJim Ingham                     {
1275a7015092SGreg Clayton                         DisplayThreadsInfo (m_interpreter, &exe_ctx, result, true, true);
12764b9bea87SJim Ingham                     }
12774b9bea87SJim Ingham                     else
12784b9bea87SJim Ingham                     {
12794b9bea87SJim Ingham                         result.AppendError ("No valid thread found in current process.");
12804b9bea87SJim Ingham                         result.SetStatus (eReturnStatusFailed);
12814b9bea87SJim Ingham                     }
12824b9bea87SJim Ingham                 }
12834b9bea87SJim Ingham             }
12844b9bea87SJim Ingham             else
12854b9bea87SJim Ingham             {
12864b9bea87SJim Ingham                 output_stream.Printf ("Process %d is running.\n",
12874b9bea87SJim Ingham                                           exe_ctx.process->GetID());
12884b9bea87SJim Ingham             }
12894b9bea87SJim Ingham         }
12904b9bea87SJim Ingham         else
12914b9bea87SJim Ingham         {
12924b9bea87SJim Ingham             result.AppendError ("No current location or status available.");
12934b9bea87SJim Ingham             result.SetStatus (eReturnStatusFailed);
12944b9bea87SJim Ingham         }
12954b9bea87SJim Ingham         return result.Succeeded();
12964b9bea87SJim Ingham     }
12974b9bea87SJim Ingham };
12984b9bea87SJim Ingham 
12994b9bea87SJim Ingham //-------------------------------------------------------------------------
130035731357SCaroline Tice // CommandObjectProcessHandle
130135731357SCaroline Tice //-------------------------------------------------------------------------
1302*bb9caf73SJim Ingham #pragma mark CommandObjectProcessHandle
130335731357SCaroline Tice 
130435731357SCaroline Tice class CommandObjectProcessHandle : public CommandObject
130535731357SCaroline Tice {
130635731357SCaroline Tice public:
130735731357SCaroline Tice 
130835731357SCaroline Tice     class CommandOptions : public Options
130935731357SCaroline Tice     {
131035731357SCaroline Tice     public:
131135731357SCaroline Tice 
131235731357SCaroline Tice         CommandOptions () :
131335731357SCaroline Tice             Options ()
131435731357SCaroline Tice         {
131535731357SCaroline Tice             ResetOptionValues ();
131635731357SCaroline Tice         }
131735731357SCaroline Tice 
131835731357SCaroline Tice         ~CommandOptions ()
131935731357SCaroline Tice         {
132035731357SCaroline Tice         }
132135731357SCaroline Tice 
132235731357SCaroline Tice         Error
132335731357SCaroline Tice         SetOptionValue (int option_idx, const char *option_arg)
132435731357SCaroline Tice         {
132535731357SCaroline Tice             Error error;
132635731357SCaroline Tice             char short_option = (char) m_getopt_table[option_idx].val;
132735731357SCaroline Tice 
132835731357SCaroline Tice             switch (short_option)
132935731357SCaroline Tice             {
133035731357SCaroline Tice                 case 's':
133135731357SCaroline Tice                     stop = option_arg;
133235731357SCaroline Tice                     break;
133335731357SCaroline Tice                 case 'n':
133435731357SCaroline Tice                     notify = option_arg;
133535731357SCaroline Tice                     break;
133635731357SCaroline Tice                 case 'p':
133735731357SCaroline Tice                     pass = option_arg;
133835731357SCaroline Tice                     break;
133935731357SCaroline Tice                 default:
134035731357SCaroline Tice                     error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
134135731357SCaroline Tice                     break;
134235731357SCaroline Tice             }
134335731357SCaroline Tice             return error;
134435731357SCaroline Tice         }
134535731357SCaroline Tice 
134635731357SCaroline Tice         void
134735731357SCaroline Tice         ResetOptionValues ()
134835731357SCaroline Tice         {
134935731357SCaroline Tice             Options::ResetOptionValues();
135035731357SCaroline Tice             stop.clear();
135135731357SCaroline Tice             notify.clear();
135235731357SCaroline Tice             pass.clear();
135335731357SCaroline Tice         }
135435731357SCaroline Tice 
135535731357SCaroline Tice         const lldb::OptionDefinition*
135635731357SCaroline Tice         GetDefinitions ()
135735731357SCaroline Tice         {
135835731357SCaroline Tice             return g_option_table;
135935731357SCaroline Tice         }
136035731357SCaroline Tice 
136135731357SCaroline Tice         // Options table: Required for subclasses of Options.
136235731357SCaroline Tice 
136335731357SCaroline Tice         static lldb::OptionDefinition g_option_table[];
136435731357SCaroline Tice 
136535731357SCaroline Tice         // Instance variables to hold the values for command options.
136635731357SCaroline Tice 
136735731357SCaroline Tice         std::string stop;
136835731357SCaroline Tice         std::string notify;
136935731357SCaroline Tice         std::string pass;
137035731357SCaroline Tice     };
137135731357SCaroline Tice 
137235731357SCaroline Tice 
137335731357SCaroline Tice     CommandObjectProcessHandle (CommandInterpreter &interpreter) :
137435731357SCaroline Tice         CommandObject (interpreter,
137535731357SCaroline Tice                        "process handle",
137610ad7993SCaroline Tice                        "Show or update what the process and debugger should do with various signals received from the OS.",
137735731357SCaroline Tice                        NULL)
137835731357SCaroline Tice     {
137910ad7993SCaroline Tice         SetHelpLong ("If no signals are specified, update them all.  If no update option is specified, list the current values.\n");
138035731357SCaroline Tice         CommandArgumentEntry arg;
1381c0dbdfb6SCaroline Tice         CommandArgumentData signal_arg;
138235731357SCaroline Tice 
1383c0dbdfb6SCaroline Tice         signal_arg.arg_type = eArgTypeUnixSignal;
1384c0dbdfb6SCaroline Tice         signal_arg.arg_repetition = eArgRepeatStar;
138535731357SCaroline Tice 
1386c0dbdfb6SCaroline Tice         arg.push_back (signal_arg);
138735731357SCaroline Tice 
138835731357SCaroline Tice         m_arguments.push_back (arg);
138935731357SCaroline Tice     }
139035731357SCaroline Tice 
139135731357SCaroline Tice     ~CommandObjectProcessHandle ()
139235731357SCaroline Tice     {
139335731357SCaroline Tice     }
139435731357SCaroline Tice 
139535731357SCaroline Tice     Options *
139635731357SCaroline Tice     GetOptions ()
139735731357SCaroline Tice     {
139835731357SCaroline Tice         return &m_options;
139935731357SCaroline Tice     }
140035731357SCaroline Tice 
140135731357SCaroline Tice     bool
140210ad7993SCaroline Tice     VerifyCommandOptionValue (const std::string &option, int &real_value)
140335731357SCaroline Tice     {
140435731357SCaroline Tice         bool okay = true;
140535731357SCaroline Tice 
140610ad7993SCaroline Tice         bool success = false;
140710ad7993SCaroline Tice         bool tmp_value = Args::StringToBoolean (option.c_str(), false, &success);
140810ad7993SCaroline Tice 
140910ad7993SCaroline Tice         if (success && tmp_value)
141010ad7993SCaroline Tice             real_value = 1;
141110ad7993SCaroline Tice         else if (success && !tmp_value)
141210ad7993SCaroline Tice             real_value = 0;
141335731357SCaroline Tice         else
141435731357SCaroline Tice         {
141535731357SCaroline Tice             // If the value isn't 'true' or 'false', it had better be 0 or 1.
141610ad7993SCaroline Tice             real_value = Args::StringToUInt32 (option.c_str(), 3);
141710ad7993SCaroline Tice             if (real_value != 0 && real_value != 1)
141835731357SCaroline Tice                 okay = false;
141935731357SCaroline Tice         }
142035731357SCaroline Tice 
142135731357SCaroline Tice         return okay;
142235731357SCaroline Tice     }
142335731357SCaroline Tice 
142410ad7993SCaroline Tice     void
142510ad7993SCaroline Tice     PrintSignalHeader (Stream &str)
142610ad7993SCaroline Tice     {
142710ad7993SCaroline Tice         str.Printf ("NAME        PASS   STOP   NOTIFY\n");
142810ad7993SCaroline Tice         str.Printf ("==========  =====  =====  ======\n");
142910ad7993SCaroline Tice     }
143010ad7993SCaroline Tice 
143110ad7993SCaroline Tice     void
143210ad7993SCaroline Tice     PrintSignal (Stream &str, int32_t signo, const char *sig_name, UnixSignals &signals)
143310ad7993SCaroline Tice     {
143410ad7993SCaroline Tice         bool stop;
143510ad7993SCaroline Tice         bool suppress;
143610ad7993SCaroline Tice         bool notify;
143710ad7993SCaroline Tice 
143810ad7993SCaroline Tice         str.Printf ("%-10s  ", sig_name);
143910ad7993SCaroline Tice         if (signals.GetSignalInfo (signo, suppress, stop, notify))
144010ad7993SCaroline Tice         {
144110ad7993SCaroline Tice             bool pass = !suppress;
144210ad7993SCaroline Tice             str.Printf ("%s  %s  %s",
144310ad7993SCaroline Tice                         (pass ? "true " : "false"),
144410ad7993SCaroline Tice                         (stop ? "true " : "false"),
144510ad7993SCaroline Tice                         (notify ? "true " : "false"));
144610ad7993SCaroline Tice         }
144710ad7993SCaroline Tice         str.Printf ("\n");
144810ad7993SCaroline Tice     }
144910ad7993SCaroline Tice 
145010ad7993SCaroline Tice     void
145110ad7993SCaroline Tice     PrintSignalInformation (Stream &str, Args &signal_args, int num_valid_signals, UnixSignals &signals)
145210ad7993SCaroline Tice     {
145310ad7993SCaroline Tice         PrintSignalHeader (str);
145410ad7993SCaroline Tice 
145510ad7993SCaroline Tice         if (num_valid_signals > 0)
145610ad7993SCaroline Tice         {
145710ad7993SCaroline Tice             size_t num_args = signal_args.GetArgumentCount();
145810ad7993SCaroline Tice             for (size_t i = 0; i < num_args; ++i)
145910ad7993SCaroline Tice             {
146010ad7993SCaroline Tice                 int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i));
146110ad7993SCaroline Tice                 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
146210ad7993SCaroline Tice                     PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals);
146310ad7993SCaroline Tice             }
146410ad7993SCaroline Tice         }
146510ad7993SCaroline Tice         else // Print info for ALL signals
146610ad7993SCaroline Tice         {
146710ad7993SCaroline Tice             int32_t signo = signals.GetFirstSignalNumber();
146810ad7993SCaroline Tice             while (signo != LLDB_INVALID_SIGNAL_NUMBER)
146910ad7993SCaroline Tice             {
147010ad7993SCaroline Tice                 PrintSignal (str, signo, signals.GetSignalAsCString (signo), signals);
147110ad7993SCaroline Tice                 signo = signals.GetNextSignalNumber (signo);
147210ad7993SCaroline Tice             }
147310ad7993SCaroline Tice         }
147410ad7993SCaroline Tice     }
147510ad7993SCaroline Tice 
147635731357SCaroline Tice     bool
147735731357SCaroline Tice     Execute (Args &signal_args, CommandReturnObject &result)
147835731357SCaroline Tice     {
147935731357SCaroline Tice         TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
148035731357SCaroline Tice 
148135731357SCaroline Tice         if (!target_sp)
148235731357SCaroline Tice         {
148335731357SCaroline Tice             result.AppendError ("No current target;"
148435731357SCaroline Tice                                 " cannot handle signals until you have a valid target and process.\n");
148535731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
148635731357SCaroline Tice             return false;
148735731357SCaroline Tice         }
148835731357SCaroline Tice 
148935731357SCaroline Tice         ProcessSP process_sp = target_sp->GetProcessSP();
149035731357SCaroline Tice 
149135731357SCaroline Tice         if (!process_sp)
149235731357SCaroline Tice         {
149335731357SCaroline Tice             result.AppendError ("No current process; cannot handle signals until you have a valid process.\n");
149435731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
149535731357SCaroline Tice             return false;
149635731357SCaroline Tice         }
149735731357SCaroline Tice 
149835731357SCaroline Tice         int stop_action = -1;   // -1 means leave the current setting alone
149935731357SCaroline Tice         int pass_action = -1;   // -1 means leave the current setting alone
150035731357SCaroline Tice         int notify_action = -1; // -1 means leave the current setting alone
150135731357SCaroline Tice 
150235731357SCaroline Tice         if (! m_options.stop.empty()
150310ad7993SCaroline Tice             && ! VerifyCommandOptionValue (m_options.stop, stop_action))
150435731357SCaroline Tice         {
150535731357SCaroline Tice             result.AppendError ("Invalid argument for command option --stop; must be true or false.\n");
150635731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
150735731357SCaroline Tice             return false;
150835731357SCaroline Tice         }
150935731357SCaroline Tice 
151035731357SCaroline Tice         if (! m_options.notify.empty()
151110ad7993SCaroline Tice             && ! VerifyCommandOptionValue (m_options.notify, notify_action))
151235731357SCaroline Tice         {
151335731357SCaroline Tice             result.AppendError ("Invalid argument for command option --notify; must be true or false.\n");
151435731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
151535731357SCaroline Tice             return false;
151635731357SCaroline Tice         }
151735731357SCaroline Tice 
151835731357SCaroline Tice         if (! m_options.pass.empty()
151910ad7993SCaroline Tice             && ! VerifyCommandOptionValue (m_options.pass, pass_action))
152035731357SCaroline Tice         {
152135731357SCaroline Tice             result.AppendError ("Invalid argument for command option --pass; must be true or false.\n");
152235731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
152335731357SCaroline Tice             return false;
152435731357SCaroline Tice         }
152535731357SCaroline Tice 
152635731357SCaroline Tice         size_t num_args = signal_args.GetArgumentCount();
152735731357SCaroline Tice         UnixSignals &signals = process_sp->GetUnixSignals();
152835731357SCaroline Tice         int num_signals_set = 0;
152935731357SCaroline Tice 
153010ad7993SCaroline Tice         if (num_args > 0)
153110ad7993SCaroline Tice         {
153235731357SCaroline Tice             for (size_t i = 0; i < num_args; ++i)
153335731357SCaroline Tice             {
153435731357SCaroline Tice                 int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i));
153535731357SCaroline Tice                 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
153635731357SCaroline Tice                 {
153710ad7993SCaroline Tice                     // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees
153835731357SCaroline Tice                     // the value is either 0 or 1.
153935731357SCaroline Tice                     if (stop_action != -1)
154035731357SCaroline Tice                         signals.SetShouldStop (signo, (bool) stop_action);
154135731357SCaroline Tice                     if (pass_action != -1)
154235731357SCaroline Tice                     {
154310ad7993SCaroline Tice                         bool suppress = ! ((bool) pass_action);
154410ad7993SCaroline Tice                         signals.SetShouldSuppress (signo, suppress);
154535731357SCaroline Tice                     }
154635731357SCaroline Tice                     if (notify_action != -1)
154735731357SCaroline Tice                         signals.SetShouldNotify (signo, (bool) notify_action);
154835731357SCaroline Tice                     ++num_signals_set;
154935731357SCaroline Tice                 }
155035731357SCaroline Tice                 else
155135731357SCaroline Tice                 {
155235731357SCaroline Tice                     result.AppendErrorWithFormat ("Invalid signal name '%s'\n", signal_args.GetArgumentAtIndex (i));
155335731357SCaroline Tice                 }
155435731357SCaroline Tice             }
155510ad7993SCaroline Tice         }
155610ad7993SCaroline Tice         else
155710ad7993SCaroline Tice         {
155810ad7993SCaroline Tice             // No signal specified, if any command options were specified, update ALL signals.
155910ad7993SCaroline Tice             if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1))
156010ad7993SCaroline Tice             {
156110ad7993SCaroline Tice                 if (m_interpreter.Confirm ("Do you really want to update all the signals?", false))
156210ad7993SCaroline Tice                 {
156310ad7993SCaroline Tice                     int32_t signo = signals.GetFirstSignalNumber();
156410ad7993SCaroline Tice                     while (signo != LLDB_INVALID_SIGNAL_NUMBER)
156510ad7993SCaroline Tice                     {
156610ad7993SCaroline Tice                         if (notify_action != -1)
156710ad7993SCaroline Tice                             signals.SetShouldNotify (signo, (bool) notify_action);
156810ad7993SCaroline Tice                         if (stop_action != -1)
156910ad7993SCaroline Tice                             signals.SetShouldStop (signo, (bool) stop_action);
157010ad7993SCaroline Tice                         if (pass_action != -1)
157110ad7993SCaroline Tice                         {
157210ad7993SCaroline Tice                             bool suppress = ! ((bool) pass_action);
157310ad7993SCaroline Tice                             signals.SetShouldSuppress (signo, suppress);
157410ad7993SCaroline Tice                         }
157510ad7993SCaroline Tice                         signo = signals.GetNextSignalNumber (signo);
157610ad7993SCaroline Tice                     }
157710ad7993SCaroline Tice                 }
157810ad7993SCaroline Tice             }
157910ad7993SCaroline Tice         }
158010ad7993SCaroline Tice 
158110ad7993SCaroline Tice         PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals);
158235731357SCaroline Tice 
158335731357SCaroline Tice         if (num_signals_set > 0)
158435731357SCaroline Tice             result.SetStatus (eReturnStatusSuccessFinishNoResult);
158535731357SCaroline Tice         else
158635731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
158735731357SCaroline Tice 
158835731357SCaroline Tice         return result.Succeeded();
158935731357SCaroline Tice     }
159035731357SCaroline Tice 
159135731357SCaroline Tice protected:
159235731357SCaroline Tice 
159335731357SCaroline Tice     CommandOptions m_options;
159435731357SCaroline Tice };
159535731357SCaroline Tice 
159635731357SCaroline Tice lldb::OptionDefinition
159735731357SCaroline Tice CommandObjectProcessHandle::CommandOptions::g_option_table[] =
159835731357SCaroline Tice {
159935731357SCaroline 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." },
160035731357SCaroline 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." },
160135731357SCaroline Tice { LLDB_OPT_SET_1, false, "pass",  'p', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." },
160235731357SCaroline Tice { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
160335731357SCaroline Tice };
160435731357SCaroline Tice 
160535731357SCaroline Tice //-------------------------------------------------------------------------
160630fdc8d8SChris Lattner // CommandObjectMultiwordProcess
160730fdc8d8SChris Lattner //-------------------------------------------------------------------------
160830fdc8d8SChris Lattner 
16096611103cSGreg Clayton CommandObjectMultiwordProcess::CommandObjectMultiwordProcess (CommandInterpreter &interpreter) :
1610a7015092SGreg Clayton     CommandObjectMultiword (interpreter,
1611a7015092SGreg Clayton                             "process",
161230fdc8d8SChris Lattner                             "A set of commands for operating on a process.",
161330fdc8d8SChris Lattner                             "process <subcommand> [<subcommand-options>]")
161430fdc8d8SChris Lattner {
1615a7015092SGreg Clayton     LoadSubCommand ("attach",      CommandObjectSP (new CommandObjectProcessAttach (interpreter)));
1616a7015092SGreg Clayton     LoadSubCommand ("launch",      CommandObjectSP (new CommandObjectProcessLaunch (interpreter)));
1617a7015092SGreg Clayton     LoadSubCommand ("continue",    CommandObjectSP (new CommandObjectProcessContinue (interpreter)));
1618a7015092SGreg Clayton     LoadSubCommand ("detach",      CommandObjectSP (new CommandObjectProcessDetach (interpreter)));
16198f343b09SGreg Clayton     LoadSubCommand ("load",        CommandObjectSP (new CommandObjectProcessLoad (interpreter)));
16208f343b09SGreg Clayton     LoadSubCommand ("unload",      CommandObjectSP (new CommandObjectProcessUnload (interpreter)));
1621a7015092SGreg Clayton     LoadSubCommand ("signal",      CommandObjectSP (new CommandObjectProcessSignal (interpreter)));
162235731357SCaroline Tice     LoadSubCommand ("handle",      CommandObjectSP (new CommandObjectProcessHandle (interpreter)));
1623a7015092SGreg Clayton     LoadSubCommand ("status",      CommandObjectSP (new CommandObjectProcessStatus (interpreter)));
1624a7015092SGreg Clayton     LoadSubCommand ("interrupt",   CommandObjectSP (new CommandObjectProcessInterrupt (interpreter)));
1625a7015092SGreg Clayton     LoadSubCommand ("kill",        CommandObjectSP (new CommandObjectProcessKill (interpreter)));
162630fdc8d8SChris Lattner }
162730fdc8d8SChris Lattner 
162830fdc8d8SChris Lattner CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess ()
162930fdc8d8SChris Lattner {
163030fdc8d8SChris Lattner }
163130fdc8d8SChris Lattner 
1632