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"
197260f620SGreg Clayton #include "lldb/Host/Host.h"
2030fdc8d8SChris Lattner #include "lldb/Interpreter/CommandInterpreter.h"
2130fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h"
22e996fd30SGreg Clayton #include "lldb/Target/Platform.h"
2330fdc8d8SChris Lattner #include "lldb/Target/Process.h"
2430fdc8d8SChris Lattner #include "lldb/Target/Target.h"
2530fdc8d8SChris Lattner #include "lldb/Target/Thread.h"
2630fdc8d8SChris Lattner 
2730fdc8d8SChris Lattner using namespace lldb;
2830fdc8d8SChris Lattner using namespace lldb_private;
2930fdc8d8SChris Lattner 
3030fdc8d8SChris Lattner //-------------------------------------------------------------------------
3130fdc8d8SChris Lattner // CommandObjectProcessLaunch
3230fdc8d8SChris Lattner //-------------------------------------------------------------------------
334bddaeb5SJim Ingham #pragma mark CommandObjectProcessLaunch
345a988416SJim Ingham class CommandObjectProcessLaunch : public CommandObjectParsed
3530fdc8d8SChris Lattner {
3630fdc8d8SChris Lattner public:
3730fdc8d8SChris Lattner 
38a7015092SGreg Clayton     CommandObjectProcessLaunch (CommandInterpreter &interpreter) :
395a988416SJim Ingham         CommandObjectParsed (interpreter,
40a7015092SGreg Clayton                              "process launch",
41e3d26315SCaroline Tice                              "Launch the executable in the debugger.",
42eb0103f2SGreg Clayton                              NULL),
43eb0103f2SGreg Clayton         m_options (interpreter)
4430fdc8d8SChris Lattner     {
45405fe67fSCaroline Tice         CommandArgumentEntry arg;
46405fe67fSCaroline Tice         CommandArgumentData run_args_arg;
47405fe67fSCaroline Tice 
48405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
49405fe67fSCaroline Tice         run_args_arg.arg_type = eArgTypeRunArgs;
50405fe67fSCaroline Tice         run_args_arg.arg_repetition = eArgRepeatOptional;
51405fe67fSCaroline Tice 
52405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
53405fe67fSCaroline Tice         arg.push_back (run_args_arg);
54405fe67fSCaroline Tice 
55405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
56405fe67fSCaroline Tice         m_arguments.push_back (arg);
5730fdc8d8SChris Lattner     }
5830fdc8d8SChris Lattner 
5930fdc8d8SChris Lattner 
6030fdc8d8SChris Lattner     ~CommandObjectProcessLaunch ()
6130fdc8d8SChris Lattner     {
6230fdc8d8SChris Lattner     }
6330fdc8d8SChris Lattner 
64*e9ce62b6SJim Ingham     int
65*e9ce62b6SJim Ingham     HandleArgumentCompletion (Args &input,
66*e9ce62b6SJim Ingham                               int &cursor_index,
67*e9ce62b6SJim Ingham                               int &cursor_char_position,
68*e9ce62b6SJim Ingham                               OptionElementVector &opt_element_vector,
69*e9ce62b6SJim Ingham                               int match_start_point,
70*e9ce62b6SJim Ingham                               int max_return_elements,
71*e9ce62b6SJim Ingham                               bool &word_complete,
72*e9ce62b6SJim Ingham                               StringList &matches)
73*e9ce62b6SJim Ingham     {
74*e9ce62b6SJim Ingham         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
75*e9ce62b6SJim Ingham         completion_str.erase (cursor_char_position);
76*e9ce62b6SJim Ingham 
77*e9ce62b6SJim Ingham         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
78*e9ce62b6SJim Ingham                                                              CommandCompletions::eDiskFileCompletion,
79*e9ce62b6SJim Ingham                                                              completion_str.c_str(),
80*e9ce62b6SJim Ingham                                                              match_start_point,
81*e9ce62b6SJim Ingham                                                              max_return_elements,
82*e9ce62b6SJim Ingham                                                              NULL,
83*e9ce62b6SJim Ingham                                                              word_complete,
84*e9ce62b6SJim Ingham                                                              matches);
85*e9ce62b6SJim Ingham         return matches.GetSize();
86*e9ce62b6SJim Ingham     }
87*e9ce62b6SJim Ingham 
8830fdc8d8SChris Lattner     Options *
8930fdc8d8SChris Lattner     GetOptions ()
9030fdc8d8SChris Lattner     {
9130fdc8d8SChris Lattner         return &m_options;
9230fdc8d8SChris Lattner     }
9330fdc8d8SChris Lattner 
945a988416SJim Ingham     virtual const char *GetRepeatCommand (Args &current_command_args, uint32_t index)
955a988416SJim Ingham     {
965a988416SJim Ingham         // No repeat for "process launch"...
975a988416SJim Ingham         return "";
985a988416SJim Ingham     }
995a988416SJim Ingham 
1005a988416SJim Ingham protected:
10130fdc8d8SChris Lattner     bool
1025a988416SJim Ingham     DoExecute (Args& launch_args, CommandReturnObject &result)
10330fdc8d8SChris Lattner     {
1041d885966SGreg Clayton         Debugger &debugger = m_interpreter.GetDebugger();
1051d885966SGreg Clayton         Target *target = debugger.GetSelectedTarget().get();
1061d885966SGreg Clayton         Error error;
10730fdc8d8SChris Lattner 
10830fdc8d8SChris Lattner         if (target == NULL)
10930fdc8d8SChris Lattner         {
110effe5c95SGreg Clayton             result.AppendError ("invalid target, create a debug target using the 'target create' command");
11130fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
11230fdc8d8SChris Lattner             return false;
11330fdc8d8SChris Lattner         }
11430fdc8d8SChris Lattner         // If our listener is NULL, users aren't allows to launch
11530fdc8d8SChris Lattner         char filename[PATH_MAX];
116aa149cbdSGreg Clayton         const Module *exe_module = target->GetExecutableModulePointer();
11771337622SGreg Clayton 
11871337622SGreg Clayton         if (exe_module == NULL)
11971337622SGreg Clayton         {
120effe5c95SGreg Clayton             result.AppendError ("no file in target, create a debug target using the 'target create' command");
12171337622SGreg Clayton             result.SetStatus (eReturnStatusFailed);
12271337622SGreg Clayton             return false;
12371337622SGreg Clayton         }
12471337622SGreg Clayton 
12530fdc8d8SChris Lattner         exe_module->GetFileSpec().GetPath (filename, sizeof(filename));
12630fdc8d8SChris Lattner 
127982c9762SGreg Clayton         const bool add_exe_file_as_first_arg = true;
128ad9e828cSGreg Clayton         m_options.launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), add_exe_file_as_first_arg);
129982c9762SGreg Clayton 
13071337622SGreg Clayton         StateType state = eStateInvalid;
131c14ee32dSGreg Clayton         Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
13271337622SGreg Clayton         if (process)
13371337622SGreg Clayton         {
13471337622SGreg Clayton             state = process->GetState();
13571337622SGreg Clayton 
13671337622SGreg Clayton             if (process->IsAlive() && state != eStateConnected)
13730fdc8d8SChris Lattner             {
138513c26ceSGreg Clayton                 char message[1024];
139513c26ceSGreg Clayton                 if (process->GetState() == eStateAttaching)
140513c26ceSGreg Clayton                     ::strncpy (message, "There is a pending attach, abort it and launch a new process?", sizeof(message));
141513c26ceSGreg Clayton                 else
142513c26ceSGreg Clayton                     ::strncpy (message, "There is a running process, kill it and restart?", sizeof(message));
143513c26ceSGreg Clayton 
144513c26ceSGreg Clayton                 if (!m_interpreter.Confirm (message, true))
145bb9caf73SJim Ingham                 {
14630fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
14730fdc8d8SChris Lattner                     return false;
14830fdc8d8SChris Lattner                 }
149bb9caf73SJim Ingham                 else
150bb9caf73SJim Ingham                 {
1511d885966SGreg Clayton                     Error destroy_error (process->Destroy());
1521d885966SGreg Clayton                     if (destroy_error.Success())
153bb9caf73SJim Ingham                     {
154bb9caf73SJim Ingham                         result.SetStatus (eReturnStatusSuccessFinishResult);
155bb9caf73SJim Ingham                     }
156bb9caf73SJim Ingham                     else
157bb9caf73SJim Ingham                     {
1581d885966SGreg Clayton                         result.AppendErrorWithFormat ("Failed to kill process: %s\n", destroy_error.AsCString());
159bb9caf73SJim Ingham                         result.SetStatus (eReturnStatusFailed);
160bb9caf73SJim Ingham                     }
161bb9caf73SJim Ingham                 }
162bb9caf73SJim Ingham             }
16371337622SGreg Clayton         }
16430fdc8d8SChris Lattner 
165144f3a9cSGreg Clayton         if (launch_args.GetArgumentCount() == 0)
166144f3a9cSGreg Clayton         {
167144f3a9cSGreg Clayton             const Args &process_args = target->GetRunArguments();
168144f3a9cSGreg Clayton             if (process_args.GetArgumentCount() > 0)
169144f3a9cSGreg Clayton                 m_options.launch_info.GetArguments().AppendArguments (process_args);
170144f3a9cSGreg Clayton         }
171144f3a9cSGreg Clayton         else
17230fdc8d8SChris Lattner         {
173162b597cSGreg Clayton             // Save the arguments for subsequent runs in the current target.
174162b597cSGreg Clayton             target->SetRunArguments (launch_args);
175162b597cSGreg Clayton 
176982c9762SGreg Clayton             m_options.launch_info.GetArguments().AppendArguments (launch_args);
177982c9762SGreg Clayton         }
1781d885966SGreg Clayton 
179144f3a9cSGreg Clayton         if (target->GetDisableASLR())
180144f3a9cSGreg Clayton             m_options.launch_info.GetFlags().Set (eLaunchFlagDisableASLR);
181144f3a9cSGreg Clayton 
182144f3a9cSGreg Clayton         if (target->GetDisableSTDIO())
183144f3a9cSGreg Clayton             m_options.launch_info.GetFlags().Set (eLaunchFlagDisableSTDIO);
184144f3a9cSGreg Clayton 
185144f3a9cSGreg Clayton         m_options.launch_info.GetFlags().Set (eLaunchFlagDebug);
186144f3a9cSGreg Clayton 
187144f3a9cSGreg Clayton         Args environment;
188144f3a9cSGreg Clayton         target->GetEnvironmentAsArgs (environment);
189144f3a9cSGreg Clayton         if (environment.GetArgumentCount() > 0)
190144f3a9cSGreg Clayton             m_options.launch_info.GetEnvironmentEntries ().AppendArguments (environment);
191144f3a9cSGreg Clayton 
192ee95ed50SGreg Clayton         // Finalize the file actions, and if none were given, default to opening
193ee95ed50SGreg Clayton         // up a pseudo terminal
194ee95ed50SGreg Clayton         const bool default_to_use_pty = true;
195ee95ed50SGreg Clayton         m_options.launch_info.FinalizeFileActions (target, default_to_use_pty);
1961d885966SGreg Clayton 
1971d885966SGreg Clayton         if (state == eStateConnected)
1981d885966SGreg Clayton         {
1991d885966SGreg Clayton             if (m_options.launch_info.GetFlags().Test (eLaunchFlagLaunchInTTY))
2001d885966SGreg Clayton             {
2011d885966SGreg Clayton                 result.AppendWarning("can't launch in tty when launching through a remote connection");
2021d885966SGreg Clayton                 m_options.launch_info.GetFlags().Clear (eLaunchFlagLaunchInTTY);
2031d885966SGreg Clayton             }
2041d885966SGreg Clayton         }
205982c9762SGreg Clayton         else
206982c9762SGreg Clayton         {
207144f3a9cSGreg Clayton             if (!m_options.launch_info.GetArchitecture().IsValid())
208c9ed478aSGreg Clayton                 m_options.launch_info.GetArchitecture() = target->GetArchitecture();
209c9ed478aSGreg Clayton 
210c982b3d6SGreg Clayton             PlatformSP platform_sp (target->GetPlatform());
211c982b3d6SGreg Clayton 
212c982b3d6SGreg Clayton             if (platform_sp && platform_sp->CanDebugProcess ())
213c982b3d6SGreg Clayton             {
2141d885966SGreg Clayton                 process = target->GetPlatform()->DebugProcess (m_options.launch_info,
2151d885966SGreg Clayton                                                                debugger,
2161d885966SGreg Clayton                                                                target,
2171d885966SGreg Clayton                                                                debugger.GetListener(),
2181d885966SGreg Clayton                                                                error).get();
219c982b3d6SGreg Clayton             }
220c982b3d6SGreg Clayton             else
221c982b3d6SGreg Clayton             {
222c982b3d6SGreg Clayton                 const char *plugin_name = m_options.launch_info.GetProcessPluginName();
223c3776bf2SGreg Clayton                 process = target->CreateProcess (debugger.GetListener(), plugin_name, NULL).get();
224c982b3d6SGreg Clayton                 if (process)
225c982b3d6SGreg Clayton                     error = process->Launch (m_options.launch_info);
226c982b3d6SGreg Clayton             }
2271d885966SGreg Clayton 
2281d885966SGreg Clayton             if (process == NULL)
2291d885966SGreg Clayton             {
230144f3a9cSGreg Clayton                 result.SetError (error, "failed to launch or debug process");
2311d885966SGreg Clayton                 return false;
2321d885966SGreg Clayton             }
2331d885966SGreg Clayton         }
23430fdc8d8SChris Lattner 
23530fdc8d8SChris Lattner         if (error.Success())
23630fdc8d8SChris Lattner         {
23764195a2cSGreg Clayton             const char *archname = exe_module->GetArchitecture().GetArchitectureName();
23819388cfcSGreg Clayton 
23981c22f61SGreg Clayton             result.AppendMessageWithFormat ("Process %llu launched: '%s' (%s)\n", process->GetID(), filename, archname);
24005faeb71SGreg Clayton             result.SetDidChangeProcessState (true);
241982c9762SGreg Clayton             if (m_options.launch_info.GetFlags().Test(eLaunchFlagStopAtEntry) == false)
24230fdc8d8SChris Lattner             {
24305faeb71SGreg Clayton                 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
24430fdc8d8SChris Lattner                 StateType state = process->WaitForProcessToStop (NULL);
24530fdc8d8SChris Lattner 
24630fdc8d8SChris Lattner                 if (state == eStateStopped)
24730fdc8d8SChris Lattner                 {
24805faeb71SGreg Clayton                     error = process->Resume();
24905faeb71SGreg Clayton                     if (error.Success())
25005faeb71SGreg Clayton                     {
25105faeb71SGreg Clayton                         bool synchronous_execution = m_interpreter.GetSynchronous ();
25230fdc8d8SChris Lattner                         if (synchronous_execution)
25330fdc8d8SChris Lattner                         {
25405faeb71SGreg Clayton                             state = process->WaitForProcessToStop (NULL);
2552637f825SGreg Clayton                             const bool must_be_alive = true;
2562637f825SGreg Clayton                             if (!StateIsStoppedState(state, must_be_alive))
257514487e8SGreg Clayton                             {
258144f3a9cSGreg Clayton                                 result.AppendErrorWithFormat ("process isn't stopped: %s", StateAsCString(state));
259514487e8SGreg Clayton                             }
26030fdc8d8SChris Lattner                             result.SetDidChangeProcessState (true);
26105faeb71SGreg Clayton                             result.SetStatus (eReturnStatusSuccessFinishResult);
26205faeb71SGreg Clayton                         }
26305faeb71SGreg Clayton                         else
26405faeb71SGreg Clayton                         {
26505faeb71SGreg Clayton                             result.SetStatus (eReturnStatusSuccessContinuingNoResult);
26605faeb71SGreg Clayton                         }
26705faeb71SGreg Clayton                     }
268514487e8SGreg Clayton                     else
269514487e8SGreg Clayton                     {
270144f3a9cSGreg Clayton                         result.AppendErrorWithFormat ("process resume at entry point failed: %s", error.AsCString());
271514487e8SGreg Clayton                         result.SetStatus (eReturnStatusFailed);
27230fdc8d8SChris Lattner                     }
27330fdc8d8SChris Lattner                 }
274514487e8SGreg Clayton                 else
275514487e8SGreg Clayton                 {
276144f3a9cSGreg Clayton                     result.AppendErrorWithFormat ("initial process state wasn't stopped: %s", StateAsCString(state));
277514487e8SGreg Clayton                     result.SetStatus (eReturnStatusFailed);
278514487e8SGreg Clayton                 }
279514487e8SGreg Clayton             }
280514487e8SGreg Clayton         }
281514487e8SGreg Clayton         else
282514487e8SGreg Clayton         {
283197bacffSGreg Clayton             result.AppendErrorWithFormat ("process launch failed: %s", error.AsCString());
284514487e8SGreg Clayton             result.SetStatus (eReturnStatusFailed);
28530fdc8d8SChris Lattner         }
28630fdc8d8SChris Lattner 
28730fdc8d8SChris Lattner         return result.Succeeded();
28830fdc8d8SChris Lattner     }
28930fdc8d8SChris Lattner 
29030fdc8d8SChris Lattner protected:
291982c9762SGreg Clayton     ProcessLaunchCommandOptions m_options;
29230fdc8d8SChris Lattner };
29330fdc8d8SChris Lattner 
29430fdc8d8SChris Lattner 
295982c9762SGreg Clayton //#define SET1 LLDB_OPT_SET_1
296982c9762SGreg Clayton //#define SET2 LLDB_OPT_SET_2
297982c9762SGreg Clayton //#define SET3 LLDB_OPT_SET_3
298982c9762SGreg Clayton //
299982c9762SGreg Clayton //OptionDefinition
300982c9762SGreg Clayton //CommandObjectProcessLaunch::CommandOptions::g_option_table[] =
301982c9762SGreg Clayton //{
302982c9762SGreg Clayton //{ 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."},
303982c9762SGreg Clayton //{ SET1              , false, "stdin",         'i', required_argument, NULL, 0, eArgTypePath,    "Redirect stdin for the process to <path>."},
304982c9762SGreg Clayton //{ SET1              , false, "stdout",        'o', required_argument, NULL, 0, eArgTypePath,    "Redirect stdout for the process to <path>."},
305982c9762SGreg Clayton //{ SET1              , false, "stderr",        'e', required_argument, NULL, 0, eArgTypePath,    "Redirect stderr for the process to <path>."},
306982c9762SGreg Clayton //{ SET1 | SET2 | SET3, false, "plugin",        'p', required_argument, NULL, 0, eArgTypePlugin,  "Name of the process plugin you want to use."},
307982c9762SGreg 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."},
308982c9762SGreg Clayton //{               SET3, false, "no-stdio",      'n', no_argument,       NULL, 0, eArgTypeNone,    "Do not set up for terminal I/O to go to running process."},
309982c9762SGreg Clayton //{ SET1 | SET2 | SET3, false, "working-dir",   'w', required_argument, NULL, 0, eArgTypePath,    "Set the current working directory to <path> when running the inferior."},
310982c9762SGreg Clayton //{ 0,                  false, NULL,             0,  0,                 NULL, 0, eArgTypeNone,    NULL }
311982c9762SGreg Clayton //};
312982c9762SGreg Clayton //
313982c9762SGreg Clayton //#undef SET1
314982c9762SGreg Clayton //#undef SET2
315982c9762SGreg Clayton //#undef SET3
31630fdc8d8SChris Lattner 
31730fdc8d8SChris Lattner //-------------------------------------------------------------------------
31830fdc8d8SChris Lattner // CommandObjectProcessAttach
31930fdc8d8SChris Lattner //-------------------------------------------------------------------------
320bb9caf73SJim Ingham #pragma mark CommandObjectProcessAttach
3215a988416SJim Ingham class CommandObjectProcessAttach : public CommandObjectParsed
32230fdc8d8SChris Lattner {
32330fdc8d8SChris Lattner public:
32430fdc8d8SChris Lattner 
32530fdc8d8SChris Lattner     class CommandOptions : public Options
32630fdc8d8SChris Lattner     {
32730fdc8d8SChris Lattner     public:
32830fdc8d8SChris Lattner 
329eb0103f2SGreg Clayton         CommandOptions (CommandInterpreter &interpreter) :
330eb0103f2SGreg Clayton             Options(interpreter)
33130fdc8d8SChris Lattner         {
332f6b8b581SGreg Clayton             // Keep default values of all options in one place: OptionParsingStarting ()
333f6b8b581SGreg Clayton             OptionParsingStarting ();
33430fdc8d8SChris Lattner         }
33530fdc8d8SChris Lattner 
33630fdc8d8SChris Lattner         ~CommandOptions ()
33730fdc8d8SChris Lattner         {
33830fdc8d8SChris Lattner         }
33930fdc8d8SChris Lattner 
34030fdc8d8SChris Lattner         Error
341f6b8b581SGreg Clayton         SetOptionValue (uint32_t option_idx, const char *option_arg)
34230fdc8d8SChris Lattner         {
34330fdc8d8SChris Lattner             Error error;
34430fdc8d8SChris Lattner             char short_option = (char) m_getopt_table[option_idx].val;
34530fdc8d8SChris Lattner             bool success = false;
34630fdc8d8SChris Lattner             switch (short_option)
34730fdc8d8SChris Lattner             {
348a95ce623SJohnny Chen                 case 'c':
349a95ce623SJohnny Chen                     attach_info.SetContinueOnceAttached(true);
350a95ce623SJohnny Chen                     break;
351a95ce623SJohnny Chen 
35230fdc8d8SChris Lattner                 case 'p':
353144f3a9cSGreg Clayton                     {
354144f3a9cSGreg Clayton                         lldb::pid_t pid = Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success);
35530fdc8d8SChris Lattner                         if (!success || pid == LLDB_INVALID_PROCESS_ID)
35630fdc8d8SChris Lattner                         {
35786edbf41SGreg Clayton                             error.SetErrorStringWithFormat("invalid process ID '%s'", option_arg);
35830fdc8d8SChris Lattner                         }
359144f3a9cSGreg Clayton                         else
360144f3a9cSGreg Clayton                         {
361144f3a9cSGreg Clayton                             attach_info.SetProcessID (pid);
362144f3a9cSGreg Clayton                         }
363144f3a9cSGreg Clayton                     }
36430fdc8d8SChris Lattner                     break;
36530fdc8d8SChris Lattner 
36630fdc8d8SChris Lattner                 case 'P':
367144f3a9cSGreg Clayton                     attach_info.SetProcessPluginName (option_arg);
36830fdc8d8SChris Lattner                     break;
36930fdc8d8SChris Lattner 
37030fdc8d8SChris Lattner                 case 'n':
371144f3a9cSGreg Clayton                     attach_info.GetExecutableFile().SetFile(option_arg, false);
37230fdc8d8SChris Lattner                     break;
37330fdc8d8SChris Lattner 
37430fdc8d8SChris Lattner                 case 'w':
375144f3a9cSGreg Clayton                     attach_info.SetWaitForLaunch(true);
37630fdc8d8SChris Lattner                     break;
37730fdc8d8SChris Lattner 
378cd16df91SJim Ingham                 case 'i':
379cd16df91SJim Ingham                     attach_info.SetIgnoreExisting(false);
380cd16df91SJim Ingham                     break;
381cd16df91SJim Ingham 
38230fdc8d8SChris Lattner                 default:
38386edbf41SGreg Clayton                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
38430fdc8d8SChris Lattner                     break;
38530fdc8d8SChris Lattner             }
38630fdc8d8SChris Lattner             return error;
38730fdc8d8SChris Lattner         }
38830fdc8d8SChris Lattner 
38930fdc8d8SChris Lattner         void
390f6b8b581SGreg Clayton         OptionParsingStarting ()
39130fdc8d8SChris Lattner         {
392144f3a9cSGreg Clayton             attach_info.Clear();
39330fdc8d8SChris Lattner         }
39430fdc8d8SChris Lattner 
395e0d378b3SGreg Clayton         const OptionDefinition*
39630fdc8d8SChris Lattner         GetDefinitions ()
39730fdc8d8SChris Lattner         {
39830fdc8d8SChris Lattner             return g_option_table;
39930fdc8d8SChris Lattner         }
40030fdc8d8SChris Lattner 
4015aee162fSJim Ingham         virtual bool
402eb0103f2SGreg Clayton         HandleOptionArgumentCompletion (Args &input,
4035aee162fSJim Ingham                                         int cursor_index,
4045aee162fSJim Ingham                                         int char_pos,
4055aee162fSJim Ingham                                         OptionElementVector &opt_element_vector,
4065aee162fSJim Ingham                                         int opt_element_index,
4075aee162fSJim Ingham                                         int match_start_point,
4085aee162fSJim Ingham                                         int max_return_elements,
4095aee162fSJim Ingham                                         bool &word_complete,
4105aee162fSJim Ingham                                         StringList &matches)
4115aee162fSJim Ingham         {
4125aee162fSJim Ingham             int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
4135aee162fSJim Ingham             int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
4145aee162fSJim Ingham 
4155aee162fSJim Ingham             // We are only completing the name option for now...
4165aee162fSJim Ingham 
417e0d378b3SGreg Clayton             const OptionDefinition *opt_defs = GetDefinitions();
4185aee162fSJim Ingham             if (opt_defs[opt_defs_index].short_option == 'n')
4195aee162fSJim Ingham             {
4205aee162fSJim Ingham                 // Are we in the name?
4215aee162fSJim Ingham 
4225aee162fSJim Ingham                 // Look to see if there is a -P argument provided, and if so use that plugin, otherwise
4235aee162fSJim Ingham                 // use the default plugin.
4245aee162fSJim Ingham 
4255aee162fSJim Ingham                 const char *partial_name = NULL;
4265aee162fSJim Ingham                 partial_name = input.GetArgumentAtIndex(opt_arg_pos);
4275aee162fSJim Ingham 
4288b82f087SGreg Clayton                 PlatformSP platform_sp (m_interpreter.GetPlatform (true));
429e996fd30SGreg Clayton                 if (platform_sp)
4305aee162fSJim Ingham                 {
4318b82f087SGreg Clayton                     ProcessInstanceInfoList process_infos;
4328b82f087SGreg Clayton                     ProcessInstanceInfoMatch match_info;
43332e0a750SGreg Clayton                     if (partial_name)
43432e0a750SGreg Clayton                     {
435144f3a9cSGreg Clayton                         match_info.GetProcessInfo().GetExecutableFile().SetFile(partial_name, false);
43632e0a750SGreg Clayton                         match_info.SetNameMatchType(eNameMatchStartsWith);
43732e0a750SGreg Clayton                     }
43832e0a750SGreg Clayton                     platform_sp->FindProcesses (match_info, process_infos);
439e996fd30SGreg Clayton                     const uint32_t num_matches = process_infos.GetSize();
440e996fd30SGreg Clayton                     if (num_matches > 0)
441e996fd30SGreg Clayton                     {
442e996fd30SGreg Clayton                         for (uint32_t i=0; i<num_matches; ++i)
443e996fd30SGreg Clayton                         {
444e996fd30SGreg Clayton                             matches.AppendString (process_infos.GetProcessNameAtIndex(i),
445e996fd30SGreg Clayton                                                   process_infos.GetProcessNameLengthAtIndex(i));
4465aee162fSJim Ingham                         }
4475aee162fSJim Ingham                     }
4485aee162fSJim Ingham                 }
4495aee162fSJim Ingham             }
4505aee162fSJim Ingham 
4515aee162fSJim Ingham             return false;
4525aee162fSJim Ingham         }
4535aee162fSJim Ingham 
45430fdc8d8SChris Lattner         // Options table: Required for subclasses of Options.
45530fdc8d8SChris Lattner 
456e0d378b3SGreg Clayton         static OptionDefinition g_option_table[];
45730fdc8d8SChris Lattner 
45830fdc8d8SChris Lattner         // Instance variables to hold the values for command options.
45930fdc8d8SChris Lattner 
460144f3a9cSGreg Clayton         ProcessAttachInfo attach_info;
46130fdc8d8SChris Lattner     };
46230fdc8d8SChris Lattner 
463a7015092SGreg Clayton     CommandObjectProcessAttach (CommandInterpreter &interpreter) :
4645a988416SJim Ingham         CommandObjectParsed (interpreter,
465a7015092SGreg Clayton                              "process attach",
466e3d26315SCaroline Tice                              "Attach to a process.",
467eb0103f2SGreg Clayton                              "process attach <cmd-options>"),
468eb0103f2SGreg Clayton         m_options (interpreter)
4695aee162fSJim Ingham     {
4705aee162fSJim Ingham     }
4715aee162fSJim Ingham 
4725aee162fSJim Ingham     ~CommandObjectProcessAttach ()
4735aee162fSJim Ingham     {
4745aee162fSJim Ingham     }
4755aee162fSJim Ingham 
4765a988416SJim Ingham     Options *
4775a988416SJim Ingham     GetOptions ()
4785a988416SJim Ingham     {
4795a988416SJim Ingham         return &m_options;
4805a988416SJim Ingham     }
4815a988416SJim Ingham 
4825a988416SJim Ingham protected:
4835aee162fSJim Ingham     bool
4845a988416SJim Ingham     DoExecute (Args& command,
4855aee162fSJim Ingham              CommandReturnObject &result)
4865aee162fSJim Ingham     {
487a7015092SGreg Clayton         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
48831412642SJim Ingham         // N.B. The attach should be synchronous.  It doesn't help much to get the prompt back between initiating the attach
48931412642SJim Ingham         // and the target actually stopping.  So even if the interpreter is set to be asynchronous, we wait for the stop
49031412642SJim Ingham         // ourselves here.
4915aee162fSJim Ingham 
492c14ee32dSGreg Clayton         Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
49371337622SGreg Clayton         StateType state = eStateInvalid;
4945aee162fSJim Ingham         if (process)
4955aee162fSJim Ingham         {
49671337622SGreg Clayton             state = process->GetState();
49771337622SGreg Clayton             if (process->IsAlive() && state != eStateConnected)
4985aee162fSJim Ingham             {
49981c22f61SGreg Clayton                 result.AppendErrorWithFormat ("Process %llu is currently being debugged, kill the process before attaching.\n",
5005aee162fSJim Ingham                                               process->GetID());
5015aee162fSJim Ingham                 result.SetStatus (eReturnStatusFailed);
5025aee162fSJim Ingham                 return false;
5035aee162fSJim Ingham             }
5045aee162fSJim Ingham         }
5055aee162fSJim Ingham 
5065aee162fSJim Ingham         if (target == NULL)
5075aee162fSJim Ingham         {
5085aee162fSJim Ingham             // If there isn't a current target create one.
5095aee162fSJim Ingham             TargetSP new_target_sp;
5105aee162fSJim Ingham             FileSpec emptyFileSpec;
5115aee162fSJim Ingham             Error error;
5125aee162fSJim Ingham 
513a7015092SGreg Clayton             error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(),
5145aee162fSJim Ingham                                                                               emptyFileSpec,
515cac9c5f9SGreg Clayton                                                                               NULL,
5165aee162fSJim Ingham                                                                               false,
517cac9c5f9SGreg Clayton                                                                               NULL, // No platform options
5185aee162fSJim Ingham                                                                               new_target_sp);
5195aee162fSJim Ingham             target = new_target_sp.get();
5205aee162fSJim Ingham             if (target == NULL || error.Fail())
5215aee162fSJim Ingham             {
522b766a73dSGreg Clayton                 result.AppendError(error.AsCString("Error creating target"));
5235aee162fSJim Ingham                 return false;
5245aee162fSJim Ingham             }
525a7015092SGreg Clayton             m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target);
5265aee162fSJim Ingham         }
5275aee162fSJim Ingham 
5285aee162fSJim Ingham         // Record the old executable module, we want to issue a warning if the process of attaching changed the
5295aee162fSJim Ingham         // current executable (like somebody said "file foo" then attached to a PID whose executable was bar.)
5305aee162fSJim Ingham 
5315aee162fSJim Ingham         ModuleSP old_exec_module_sp = target->GetExecutableModule();
5325aee162fSJim Ingham         ArchSpec old_arch_spec = target->GetArchitecture();
5335aee162fSJim Ingham 
5345aee162fSJim Ingham         if (command.GetArgumentCount())
5355aee162fSJim Ingham         {
536fd54b368SJason Molenda             result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
5375aee162fSJim Ingham             result.SetStatus (eReturnStatusFailed);
5385aee162fSJim Ingham         }
5395aee162fSJim Ingham         else
5405aee162fSJim Ingham         {
54171337622SGreg Clayton             if (state != eStateConnected)
54271337622SGreg Clayton             {
543144f3a9cSGreg Clayton                 const char *plugin_name = m_options.attach_info.GetProcessPluginName();
544c3776bf2SGreg Clayton                 process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name, NULL).get();
54571337622SGreg Clayton             }
5465aee162fSJim Ingham 
5475aee162fSJim Ingham             if (process)
5485aee162fSJim Ingham             {
5495aee162fSJim Ingham                 Error error;
550144f3a9cSGreg Clayton                 // If no process info was specified, then use the target executable
551144f3a9cSGreg Clayton                 // name as the process to attach to by default
552144f3a9cSGreg Clayton                 if (!m_options.attach_info.ProcessInfoSpecified ())
5535aee162fSJim Ingham                 {
5543a0b9cdfSJim Ingham                     if (old_exec_module_sp)
555ad9e828cSGreg Clayton                         m_options.attach_info.GetExecutableFile().GetFilename() = old_exec_module_sp->GetPlatformFileSpec().GetFilename();
556144f3a9cSGreg Clayton 
557144f3a9cSGreg Clayton                     if (!m_options.attach_info.ProcessInfoSpecified ())
5583a0b9cdfSJim Ingham                     {
559144f3a9cSGreg Clayton                         error.SetErrorString ("no process specified, create a target with a file, or specify the --pid or --name command option");
5603a0b9cdfSJim Ingham                     }
5615aee162fSJim Ingham                 }
5623a0b9cdfSJim Ingham 
563144f3a9cSGreg Clayton                 if (error.Success())
5643a0b9cdfSJim Ingham                 {
565144f3a9cSGreg Clayton                     error = process->Attach (m_options.attach_info);
5663a0b9cdfSJim Ingham 
5675aee162fSJim Ingham                     if (error.Success())
5685aee162fSJim Ingham                     {
5695aee162fSJim Ingham                         result.SetStatus (eReturnStatusSuccessContinuingNoResult);
5705aee162fSJim Ingham                     }
5715aee162fSJim Ingham                     else
5725aee162fSJim Ingham                     {
573144f3a9cSGreg Clayton                         result.AppendErrorWithFormat ("attach failed: %s\n", error.AsCString());
5745aee162fSJim Ingham                         result.SetStatus (eReturnStatusFailed);
5755aee162fSJim Ingham                         return false;
5765aee162fSJim Ingham                     }
577bb3a283bSJim Ingham                     // If we're synchronous, wait for the stopped event and report that.
578bb3a283bSJim Ingham                     // Otherwise just return.
579bb3a283bSJim Ingham                     // FIXME: in the async case it will now be possible to get to the command
580bb3a283bSJim Ingham                     // interpreter with a state eStateAttaching.  Make sure we handle that correctly.
581bb3a283bSJim Ingham                     StateType state = process->WaitForProcessToStop (NULL);
582bb3a283bSJim Ingham 
583bb3a283bSJim Ingham                     result.SetDidChangeProcessState (true);
584aa739093SJohnny Chen 
585aa739093SJohnny Chen                     if (state == eStateStopped)
586aa739093SJohnny Chen                     {
58781c22f61SGreg Clayton                         result.AppendMessageWithFormat ("Process %llu %s\n", process->GetID(), StateAsCString (state));
588bb3a283bSJim Ingham                         result.SetStatus (eReturnStatusSuccessFinishNoResult);
589bb3a283bSJim Ingham                     }
590aa739093SJohnny Chen                     else
591aa739093SJohnny Chen                     {
592aa739093SJohnny Chen                         result.AppendError ("attach failed: process did not stop (no such process or permission problem?)");
593cfc0935eSJim Ingham                         process->Destroy();
594aa739093SJohnny Chen                         result.SetStatus (eReturnStatusFailed);
595aa739093SJohnny Chen                         return false;
596aa739093SJohnny Chen                     }
597aa739093SJohnny Chen                 }
5985aee162fSJim Ingham             }
5995aee162fSJim Ingham         }
6005aee162fSJim Ingham 
6015aee162fSJim Ingham         if (result.Succeeded())
6025aee162fSJim Ingham         {
6035aee162fSJim Ingham             // Okay, we're done.  Last step is to warn if the executable module has changed:
604513c26ceSGreg Clayton             char new_path[PATH_MAX];
605aa149cbdSGreg Clayton             ModuleSP new_exec_module_sp (target->GetExecutableModule());
6065aee162fSJim Ingham             if (!old_exec_module_sp)
6075aee162fSJim Ingham             {
608513c26ceSGreg Clayton                 // We might not have a module if we attached to a raw pid...
609aa149cbdSGreg Clayton                 if (new_exec_module_sp)
610513c26ceSGreg Clayton                 {
611aa149cbdSGreg Clayton                     new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX);
612513c26ceSGreg Clayton                     result.AppendMessageWithFormat("Executable module set to \"%s\".\n", new_path);
613513c26ceSGreg Clayton                 }
6145aee162fSJim Ingham             }
615aa149cbdSGreg Clayton             else if (old_exec_module_sp->GetFileSpec() != new_exec_module_sp->GetFileSpec())
6165aee162fSJim Ingham             {
617513c26ceSGreg Clayton                 char old_path[PATH_MAX];
6185aee162fSJim Ingham 
6195aee162fSJim Ingham                 old_exec_module_sp->GetFileSpec().GetPath (old_path, PATH_MAX);
620aa149cbdSGreg Clayton                 new_exec_module_sp->GetFileSpec().GetPath (new_path, PATH_MAX);
6215aee162fSJim Ingham 
6225aee162fSJim Ingham                 result.AppendWarningWithFormat("Executable module changed from \"%s\" to \"%s\".\n",
6235aee162fSJim Ingham                                                     old_path, new_path);
6245aee162fSJim Ingham             }
6255aee162fSJim Ingham 
6265aee162fSJim Ingham             if (!old_arch_spec.IsValid())
6275aee162fSJim Ingham             {
62864195a2cSGreg Clayton                 result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().GetArchitectureName());
6295aee162fSJim Ingham             }
6305aee162fSJim Ingham             else if (old_arch_spec != target->GetArchitecture())
6315aee162fSJim Ingham             {
6325aee162fSJim Ingham                 result.AppendWarningWithFormat("Architecture changed from %s to %s.\n",
63364195a2cSGreg Clayton                                                 old_arch_spec.GetArchitectureName(), target->GetArchitecture().GetArchitectureName());
6345aee162fSJim Ingham             }
635a95ce623SJohnny Chen 
636a95ce623SJohnny Chen             // This supports the use-case scenario of immediately continuing the process once attached.
637a95ce623SJohnny Chen             if (m_options.attach_info.GetContinueOnceAttached())
6385bcaf583SSean Callanan                 m_interpreter.HandleCommand("process continue", eLazyBoolNo, result);
6395aee162fSJim Ingham         }
6405aee162fSJim Ingham         return result.Succeeded();
6415aee162fSJim Ingham     }
6425aee162fSJim Ingham 
64330fdc8d8SChris Lattner     CommandOptions m_options;
64430fdc8d8SChris Lattner };
64530fdc8d8SChris Lattner 
64630fdc8d8SChris Lattner 
647e0d378b3SGreg Clayton OptionDefinition
64830fdc8d8SChris Lattner CommandObjectProcessAttach::CommandOptions::g_option_table[] =
64930fdc8d8SChris Lattner {
650a95ce623SJohnny Chen { LLDB_OPT_SET_ALL, false, "continue",'c', no_argument,         NULL, 0, eArgTypeNone,         "Immediately continue the process once attached."},
651deaab222SCaroline Tice { LLDB_OPT_SET_ALL, false, "plugin",  'P', required_argument,   NULL, 0, eArgTypePlugin,       "Name of the process plugin you want to use."},
652deaab222SCaroline Tice { LLDB_OPT_SET_1,   false, "pid",     'p', required_argument,   NULL, 0, eArgTypePid,          "The process ID of an existing process to attach to."},
653deaab222SCaroline Tice { LLDB_OPT_SET_2,   false, "name",    'n', required_argument,   NULL, 0, eArgTypeProcessName,  "The name of the process to attach to."},
654cd16df91SJim Ingham { LLDB_OPT_SET_2,   false, "include-existing", 'i', no_argument, NULL, 0, eArgTypeNone,         "Include existing processes when doing attach -w."},
6554ce37abbSJohnny Chen { LLDB_OPT_SET_2,   false, "waitfor", 'w', no_argument,         NULL, 0, eArgTypeNone,         "Wait for the process with <process-name> to launch."},
656deaab222SCaroline Tice { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
65730fdc8d8SChris Lattner };
65830fdc8d8SChris Lattner 
65930fdc8d8SChris Lattner //-------------------------------------------------------------------------
66030fdc8d8SChris Lattner // CommandObjectProcessContinue
66130fdc8d8SChris Lattner //-------------------------------------------------------------------------
662bb9caf73SJim Ingham #pragma mark CommandObjectProcessContinue
66330fdc8d8SChris Lattner 
6645a988416SJim Ingham class CommandObjectProcessContinue : public CommandObjectParsed
66530fdc8d8SChris Lattner {
66630fdc8d8SChris Lattner public:
66730fdc8d8SChris Lattner 
668a7015092SGreg Clayton     CommandObjectProcessContinue (CommandInterpreter &interpreter) :
6695a988416SJim Ingham         CommandObjectParsed (interpreter,
670a7015092SGreg Clayton                              "process continue",
671e3d26315SCaroline Tice                              "Continue execution of all threads in the current process.",
67230fdc8d8SChris Lattner                              "process continue",
67330fdc8d8SChris Lattner                              eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
67430fdc8d8SChris Lattner     {
67530fdc8d8SChris Lattner     }
67630fdc8d8SChris Lattner 
67730fdc8d8SChris Lattner 
67830fdc8d8SChris Lattner     ~CommandObjectProcessContinue ()
67930fdc8d8SChris Lattner     {
68030fdc8d8SChris Lattner     }
68130fdc8d8SChris Lattner 
6825a988416SJim Ingham protected:
68330fdc8d8SChris Lattner     bool
6845a988416SJim Ingham     DoExecute (Args& command,
68530fdc8d8SChris Lattner              CommandReturnObject &result)
68630fdc8d8SChris Lattner     {
687c14ee32dSGreg Clayton         Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
688a7015092SGreg Clayton         bool synchronous_execution = m_interpreter.GetSynchronous ();
68930fdc8d8SChris Lattner 
69030fdc8d8SChris Lattner         if (process == NULL)
69130fdc8d8SChris Lattner         {
69230fdc8d8SChris Lattner             result.AppendError ("no process to continue");
69330fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
69430fdc8d8SChris Lattner             return false;
69530fdc8d8SChris Lattner          }
69630fdc8d8SChris Lattner 
69730fdc8d8SChris Lattner         StateType state = process->GetState();
69830fdc8d8SChris Lattner         if (state == eStateStopped)
69930fdc8d8SChris Lattner         {
70030fdc8d8SChris Lattner             if (command.GetArgumentCount() != 0)
70130fdc8d8SChris Lattner             {
70230fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("The '%s' command does not take any arguments.\n", m_cmd_name.c_str());
70330fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
70430fdc8d8SChris Lattner                 return false;
70530fdc8d8SChris Lattner             }
70630fdc8d8SChris Lattner 
70730fdc8d8SChris Lattner             const uint32_t num_threads = process->GetThreadList().GetSize();
70830fdc8d8SChris Lattner 
70930fdc8d8SChris Lattner             // Set the actions that the threads should each take when resuming
71030fdc8d8SChris Lattner             for (uint32_t idx=0; idx<num_threads; ++idx)
71130fdc8d8SChris Lattner             {
71230fdc8d8SChris Lattner                 process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState (eStateRunning);
71330fdc8d8SChris Lattner             }
71430fdc8d8SChris Lattner 
71530fdc8d8SChris Lattner             Error error(process->Resume());
71630fdc8d8SChris Lattner             if (error.Success())
71730fdc8d8SChris Lattner             {
71881c22f61SGreg Clayton                 result.AppendMessageWithFormat ("Process %llu resuming\n", process->GetID());
71930fdc8d8SChris Lattner                 if (synchronous_execution)
72030fdc8d8SChris Lattner                 {
721b132097bSGreg Clayton                     state = process->WaitForProcessToStop (NULL);
72230fdc8d8SChris Lattner 
72330fdc8d8SChris Lattner                     result.SetDidChangeProcessState (true);
72481c22f61SGreg Clayton                     result.AppendMessageWithFormat ("Process %llu %s\n", process->GetID(), StateAsCString (state));
72530fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
72630fdc8d8SChris Lattner                 }
72730fdc8d8SChris Lattner                 else
72830fdc8d8SChris Lattner                 {
72930fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusSuccessContinuingNoResult);
73030fdc8d8SChris Lattner                 }
73130fdc8d8SChris Lattner             }
73230fdc8d8SChris Lattner             else
73330fdc8d8SChris Lattner             {
73430fdc8d8SChris Lattner                 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
73530fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
73630fdc8d8SChris Lattner             }
73730fdc8d8SChris Lattner         }
73830fdc8d8SChris Lattner         else
73930fdc8d8SChris Lattner         {
74030fdc8d8SChris Lattner             result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
74130fdc8d8SChris Lattner                                          StateAsCString(state));
74230fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
74330fdc8d8SChris Lattner         }
74430fdc8d8SChris Lattner         return result.Succeeded();
74530fdc8d8SChris Lattner     }
74630fdc8d8SChris Lattner };
74730fdc8d8SChris Lattner 
74830fdc8d8SChris Lattner //-------------------------------------------------------------------------
74930fdc8d8SChris Lattner // CommandObjectProcessDetach
75030fdc8d8SChris Lattner //-------------------------------------------------------------------------
751bb9caf73SJim Ingham #pragma mark CommandObjectProcessDetach
75230fdc8d8SChris Lattner 
7535a988416SJim Ingham class CommandObjectProcessDetach : public CommandObjectParsed
75430fdc8d8SChris Lattner {
75530fdc8d8SChris Lattner public:
75630fdc8d8SChris Lattner 
757a7015092SGreg Clayton     CommandObjectProcessDetach (CommandInterpreter &interpreter) :
7585a988416SJim Ingham         CommandObjectParsed (interpreter,
759a7015092SGreg Clayton                              "process detach",
760e3d26315SCaroline Tice                              "Detach from the current process being debugged.",
76130fdc8d8SChris Lattner                              "process detach",
76230fdc8d8SChris Lattner                              eFlagProcessMustBeLaunched)
76330fdc8d8SChris Lattner     {
76430fdc8d8SChris Lattner     }
76530fdc8d8SChris Lattner 
76630fdc8d8SChris Lattner     ~CommandObjectProcessDetach ()
76730fdc8d8SChris Lattner     {
76830fdc8d8SChris Lattner     }
76930fdc8d8SChris Lattner 
7705a988416SJim Ingham protected:
77130fdc8d8SChris Lattner     bool
7725a988416SJim Ingham     DoExecute (Args& command,
77330fdc8d8SChris Lattner              CommandReturnObject &result)
77430fdc8d8SChris Lattner     {
775c14ee32dSGreg Clayton         Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
77630fdc8d8SChris Lattner         if (process == NULL)
77730fdc8d8SChris Lattner         {
77830fdc8d8SChris Lattner             result.AppendError ("must have a valid process in order to detach");
77930fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
78030fdc8d8SChris Lattner             return false;
78130fdc8d8SChris Lattner         }
78230fdc8d8SChris Lattner 
78381c22f61SGreg Clayton         result.AppendMessageWithFormat ("Detaching from process %llu\n", process->GetID());
78430fdc8d8SChris Lattner         Error error (process->Detach());
78530fdc8d8SChris Lattner         if (error.Success())
78630fdc8d8SChris Lattner         {
78730fdc8d8SChris Lattner             result.SetStatus (eReturnStatusSuccessFinishResult);
78830fdc8d8SChris Lattner         }
78930fdc8d8SChris Lattner         else
79030fdc8d8SChris Lattner         {
79130fdc8d8SChris Lattner             result.AppendErrorWithFormat ("Detach failed: %s\n", error.AsCString());
79230fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
79330fdc8d8SChris Lattner             return false;
79430fdc8d8SChris Lattner         }
79530fdc8d8SChris Lattner         return result.Succeeded();
79630fdc8d8SChris Lattner     }
79730fdc8d8SChris Lattner };
79830fdc8d8SChris Lattner 
79930fdc8d8SChris Lattner //-------------------------------------------------------------------------
800b766a73dSGreg Clayton // CommandObjectProcessConnect
801b766a73dSGreg Clayton //-------------------------------------------------------------------------
802b766a73dSGreg Clayton #pragma mark CommandObjectProcessConnect
803b766a73dSGreg Clayton 
8045a988416SJim Ingham class CommandObjectProcessConnect : public CommandObjectParsed
805b766a73dSGreg Clayton {
806b766a73dSGreg Clayton public:
807b766a73dSGreg Clayton 
808b766a73dSGreg Clayton     class CommandOptions : public Options
809b766a73dSGreg Clayton     {
810b766a73dSGreg Clayton     public:
811b766a73dSGreg Clayton 
812eb0103f2SGreg Clayton         CommandOptions (CommandInterpreter &interpreter) :
813eb0103f2SGreg Clayton             Options(interpreter)
814b766a73dSGreg Clayton         {
815f6b8b581SGreg Clayton             // Keep default values of all options in one place: OptionParsingStarting ()
816f6b8b581SGreg Clayton             OptionParsingStarting ();
817b766a73dSGreg Clayton         }
818b766a73dSGreg Clayton 
819b766a73dSGreg Clayton         ~CommandOptions ()
820b766a73dSGreg Clayton         {
821b766a73dSGreg Clayton         }
822b766a73dSGreg Clayton 
823b766a73dSGreg Clayton         Error
824f6b8b581SGreg Clayton         SetOptionValue (uint32_t option_idx, const char *option_arg)
825b766a73dSGreg Clayton         {
826b766a73dSGreg Clayton             Error error;
827b766a73dSGreg Clayton             char short_option = (char) m_getopt_table[option_idx].val;
828b766a73dSGreg Clayton 
829b766a73dSGreg Clayton             switch (short_option)
830b766a73dSGreg Clayton             {
831b766a73dSGreg Clayton             case 'p':
832b766a73dSGreg Clayton                 plugin_name.assign (option_arg);
833b766a73dSGreg Clayton                 break;
834b766a73dSGreg Clayton 
835b766a73dSGreg Clayton             default:
83686edbf41SGreg Clayton                 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
837b766a73dSGreg Clayton                 break;
838b766a73dSGreg Clayton             }
839b766a73dSGreg Clayton             return error;
840b766a73dSGreg Clayton         }
841b766a73dSGreg Clayton 
842b766a73dSGreg Clayton         void
843f6b8b581SGreg Clayton         OptionParsingStarting ()
844b766a73dSGreg Clayton         {
845b766a73dSGreg Clayton             plugin_name.clear();
846b766a73dSGreg Clayton         }
847b766a73dSGreg Clayton 
848e0d378b3SGreg Clayton         const OptionDefinition*
849b766a73dSGreg Clayton         GetDefinitions ()
850b766a73dSGreg Clayton         {
851b766a73dSGreg Clayton             return g_option_table;
852b766a73dSGreg Clayton         }
853b766a73dSGreg Clayton 
854b766a73dSGreg Clayton         // Options table: Required for subclasses of Options.
855b766a73dSGreg Clayton 
856e0d378b3SGreg Clayton         static OptionDefinition g_option_table[];
857b766a73dSGreg Clayton 
858b766a73dSGreg Clayton         // Instance variables to hold the values for command options.
859b766a73dSGreg Clayton 
860b766a73dSGreg Clayton         std::string plugin_name;
861b766a73dSGreg Clayton     };
862b766a73dSGreg Clayton 
863b766a73dSGreg Clayton     CommandObjectProcessConnect (CommandInterpreter &interpreter) :
8645a988416SJim Ingham         CommandObjectParsed (interpreter,
865b766a73dSGreg Clayton                              "process connect",
866b766a73dSGreg Clayton                              "Connect to a remote debug service.",
867b766a73dSGreg Clayton                              "process connect <remote-url>",
868eb0103f2SGreg Clayton                              0),
869eb0103f2SGreg Clayton         m_options (interpreter)
870b766a73dSGreg Clayton     {
871b766a73dSGreg Clayton     }
872b766a73dSGreg Clayton 
873b766a73dSGreg Clayton     ~CommandObjectProcessConnect ()
874b766a73dSGreg Clayton     {
875b766a73dSGreg Clayton     }
876b766a73dSGreg Clayton 
877b766a73dSGreg Clayton 
8785a988416SJim Ingham     Options *
8795a988416SJim Ingham     GetOptions ()
8805a988416SJim Ingham     {
8815a988416SJim Ingham         return &m_options;
8825a988416SJim Ingham     }
8835a988416SJim Ingham 
8845a988416SJim Ingham protected:
885b766a73dSGreg Clayton     bool
8865a988416SJim Ingham     DoExecute (Args& command,
887b766a73dSGreg Clayton              CommandReturnObject &result)
888b766a73dSGreg Clayton     {
889b766a73dSGreg Clayton 
890b766a73dSGreg Clayton         TargetSP target_sp (m_interpreter.GetDebugger().GetSelectedTarget());
891b766a73dSGreg Clayton         Error error;
892c14ee32dSGreg Clayton         Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
893b766a73dSGreg Clayton         if (process)
894b766a73dSGreg Clayton         {
895b766a73dSGreg Clayton             if (process->IsAlive())
896b766a73dSGreg Clayton             {
89781c22f61SGreg Clayton                 result.AppendErrorWithFormat ("Process %llu is currently being debugged, kill the process before connecting.\n",
898b766a73dSGreg Clayton                                               process->GetID());
899b766a73dSGreg Clayton                 result.SetStatus (eReturnStatusFailed);
900b766a73dSGreg Clayton                 return false;
901b766a73dSGreg Clayton             }
902b766a73dSGreg Clayton         }
903b766a73dSGreg Clayton 
904b766a73dSGreg Clayton         if (!target_sp)
905b766a73dSGreg Clayton         {
906b766a73dSGreg Clayton             // If there isn't a current target create one.
907b766a73dSGreg Clayton             FileSpec emptyFileSpec;
908b766a73dSGreg Clayton 
909b766a73dSGreg Clayton             error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(),
910b766a73dSGreg Clayton                                                                               emptyFileSpec,
911cac9c5f9SGreg Clayton                                                                               NULL,
912b766a73dSGreg Clayton                                                                               false,
913cac9c5f9SGreg Clayton                                                                               NULL, // No platform options
914b766a73dSGreg Clayton                                                                               target_sp);
915b766a73dSGreg Clayton             if (!target_sp || error.Fail())
916b766a73dSGreg Clayton             {
917b766a73dSGreg Clayton                 result.AppendError(error.AsCString("Error creating target"));
918b766a73dSGreg Clayton                 result.SetStatus (eReturnStatusFailed);
919b766a73dSGreg Clayton                 return false;
920b766a73dSGreg Clayton             }
921b766a73dSGreg Clayton             m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target_sp.get());
922b766a73dSGreg Clayton         }
923b766a73dSGreg Clayton 
924b766a73dSGreg Clayton         if (command.GetArgumentCount() == 1)
925b766a73dSGreg Clayton         {
926b766a73dSGreg Clayton             const char *plugin_name = NULL;
927b766a73dSGreg Clayton             if (!m_options.plugin_name.empty())
928b766a73dSGreg Clayton                 plugin_name = m_options.plugin_name.c_str();
929b766a73dSGreg Clayton 
930b766a73dSGreg Clayton             const char *remote_url = command.GetArgumentAtIndex(0);
931c3776bf2SGreg Clayton             process = target_sp->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name, NULL).get();
932b766a73dSGreg Clayton 
933b766a73dSGreg Clayton             if (process)
934b766a73dSGreg Clayton             {
935b766a73dSGreg Clayton                 error = process->ConnectRemote (remote_url);
936b766a73dSGreg Clayton 
937b766a73dSGreg Clayton                 if (error.Fail())
938b766a73dSGreg Clayton                 {
939b766a73dSGreg Clayton                     result.AppendError(error.AsCString("Remote connect failed"));
940b766a73dSGreg Clayton                     result.SetStatus (eReturnStatusFailed);
9411517dd33SGreg Clayton                     target_sp->DeleteCurrentProcess();
942b766a73dSGreg Clayton                     return false;
943b766a73dSGreg Clayton                 }
944b766a73dSGreg Clayton             }
945b766a73dSGreg Clayton             else
946b766a73dSGreg Clayton             {
947fd54b368SJason Molenda                 result.AppendErrorWithFormat ("Unable to find process plug-in for remote URL '%s'.\nPlease specify a process plug-in name with the --plugin option, or specify an object file using the \"file\" command.\n",
948fd54b368SJason Molenda                                               m_cmd_name.c_str());
949b766a73dSGreg Clayton                 result.SetStatus (eReturnStatusFailed);
950b766a73dSGreg Clayton             }
951b766a73dSGreg Clayton         }
952b766a73dSGreg Clayton         else
953b766a73dSGreg Clayton         {
954fd54b368SJason Molenda             result.AppendErrorWithFormat ("'%s' takes exactly one argument:\nUsage: %s\n",
955b766a73dSGreg Clayton                                           m_cmd_name.c_str(),
956b766a73dSGreg Clayton                                           m_cmd_syntax.c_str());
957b766a73dSGreg Clayton             result.SetStatus (eReturnStatusFailed);
958b766a73dSGreg Clayton         }
959b766a73dSGreg Clayton         return result.Succeeded();
960b766a73dSGreg Clayton     }
961b766a73dSGreg Clayton 
962b766a73dSGreg Clayton     CommandOptions m_options;
963b766a73dSGreg Clayton };
964b766a73dSGreg Clayton 
965b766a73dSGreg Clayton 
966e0d378b3SGreg Clayton OptionDefinition
967b766a73dSGreg Clayton CommandObjectProcessConnect::CommandOptions::g_option_table[] =
968b766a73dSGreg Clayton {
969b766a73dSGreg Clayton     { LLDB_OPT_SET_ALL, false, "plugin", 'p', required_argument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."},
970b766a73dSGreg Clayton     { 0,                false, NULL,      0 , 0,                 NULL, 0, eArgTypeNone,   NULL }
971b766a73dSGreg Clayton };
972b766a73dSGreg Clayton 
973b766a73dSGreg Clayton //-------------------------------------------------------------------------
9748f343b09SGreg Clayton // CommandObjectProcessLoad
9758f343b09SGreg Clayton //-------------------------------------------------------------------------
976bb9caf73SJim Ingham #pragma mark CommandObjectProcessLoad
9778f343b09SGreg Clayton 
9785a988416SJim Ingham class CommandObjectProcessLoad : public CommandObjectParsed
9798f343b09SGreg Clayton {
9808f343b09SGreg Clayton public:
9818f343b09SGreg Clayton 
9828f343b09SGreg Clayton     CommandObjectProcessLoad (CommandInterpreter &interpreter) :
9835a988416SJim Ingham         CommandObjectParsed (interpreter,
9848f343b09SGreg Clayton                              "process load",
9858f343b09SGreg Clayton                              "Load a shared library into the current process.",
9868f343b09SGreg Clayton                              "process load <filename> [<filename> ...]",
9878f343b09SGreg Clayton                              eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
9888f343b09SGreg Clayton     {
9898f343b09SGreg Clayton     }
9908f343b09SGreg Clayton 
9918f343b09SGreg Clayton     ~CommandObjectProcessLoad ()
9928f343b09SGreg Clayton     {
9938f343b09SGreg Clayton     }
9948f343b09SGreg Clayton 
9955a988416SJim Ingham protected:
9968f343b09SGreg Clayton     bool
9975a988416SJim Ingham     DoExecute (Args& command,
9988f343b09SGreg Clayton              CommandReturnObject &result)
9998f343b09SGreg Clayton     {
1000c14ee32dSGreg Clayton         Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
10018f343b09SGreg Clayton         if (process == NULL)
10028f343b09SGreg Clayton         {
10038f343b09SGreg Clayton             result.AppendError ("must have a valid process in order to load a shared library");
10048f343b09SGreg Clayton             result.SetStatus (eReturnStatusFailed);
10058f343b09SGreg Clayton             return false;
10068f343b09SGreg Clayton         }
10078f343b09SGreg Clayton 
10088f343b09SGreg Clayton         const uint32_t argc = command.GetArgumentCount();
10098f343b09SGreg Clayton 
10108f343b09SGreg Clayton         for (uint32_t i=0; i<argc; ++i)
10118f343b09SGreg Clayton         {
10128f343b09SGreg Clayton             Error error;
10138f343b09SGreg Clayton             const char *image_path = command.GetArgumentAtIndex(i);
10148f343b09SGreg Clayton             FileSpec image_spec (image_path, false);
1015aa516843SGreg Clayton             process->GetTarget().GetPlatform()->ResolveRemotePath(image_spec, image_spec);
10168f343b09SGreg Clayton             uint32_t image_token = process->LoadImage(image_spec, error);
10178f343b09SGreg Clayton             if (image_token != LLDB_INVALID_IMAGE_TOKEN)
10188f343b09SGreg Clayton             {
10198f343b09SGreg Clayton                 result.AppendMessageWithFormat ("Loading \"%s\"...ok\nImage %u loaded.\n", image_path, image_token);
10208f343b09SGreg Clayton                 result.SetStatus (eReturnStatusSuccessFinishResult);
10218f343b09SGreg Clayton             }
10228f343b09SGreg Clayton             else
10238f343b09SGreg Clayton             {
10248f343b09SGreg Clayton                 result.AppendErrorWithFormat ("failed to load '%s': %s", image_path, error.AsCString());
10258f343b09SGreg Clayton                 result.SetStatus (eReturnStatusFailed);
10268f343b09SGreg Clayton             }
10278f343b09SGreg Clayton         }
10288f343b09SGreg Clayton         return result.Succeeded();
10298f343b09SGreg Clayton     }
10308f343b09SGreg Clayton };
10318f343b09SGreg Clayton 
10328f343b09SGreg Clayton 
10338f343b09SGreg Clayton //-------------------------------------------------------------------------
10348f343b09SGreg Clayton // CommandObjectProcessUnload
10358f343b09SGreg Clayton //-------------------------------------------------------------------------
1036bb9caf73SJim Ingham #pragma mark CommandObjectProcessUnload
10378f343b09SGreg Clayton 
10385a988416SJim Ingham class CommandObjectProcessUnload : public CommandObjectParsed
10398f343b09SGreg Clayton {
10408f343b09SGreg Clayton public:
10418f343b09SGreg Clayton 
10428f343b09SGreg Clayton     CommandObjectProcessUnload (CommandInterpreter &interpreter) :
10435a988416SJim Ingham         CommandObjectParsed (interpreter,
10448f343b09SGreg Clayton                              "process unload",
10458f343b09SGreg Clayton                              "Unload a shared library from the current process using the index returned by a previous call to \"process load\".",
10468f343b09SGreg Clayton                              "process unload <index>",
10478f343b09SGreg Clayton                              eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
10488f343b09SGreg Clayton     {
10498f343b09SGreg Clayton     }
10508f343b09SGreg Clayton 
10518f343b09SGreg Clayton     ~CommandObjectProcessUnload ()
10528f343b09SGreg Clayton     {
10538f343b09SGreg Clayton     }
10548f343b09SGreg Clayton 
10555a988416SJim Ingham protected:
10568f343b09SGreg Clayton     bool
10575a988416SJim Ingham     DoExecute (Args& command,
10588f343b09SGreg Clayton              CommandReturnObject &result)
10598f343b09SGreg Clayton     {
1060c14ee32dSGreg Clayton         Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
10618f343b09SGreg Clayton         if (process == NULL)
10628f343b09SGreg Clayton         {
10638f343b09SGreg Clayton             result.AppendError ("must have a valid process in order to load a shared library");
10648f343b09SGreg Clayton             result.SetStatus (eReturnStatusFailed);
10658f343b09SGreg Clayton             return false;
10668f343b09SGreg Clayton         }
10678f343b09SGreg Clayton 
10688f343b09SGreg Clayton         const uint32_t argc = command.GetArgumentCount();
10698f343b09SGreg Clayton 
10708f343b09SGreg Clayton         for (uint32_t i=0; i<argc; ++i)
10718f343b09SGreg Clayton         {
10728f343b09SGreg Clayton             const char *image_token_cstr = command.GetArgumentAtIndex(i);
10738f343b09SGreg Clayton             uint32_t image_token = Args::StringToUInt32(image_token_cstr, LLDB_INVALID_IMAGE_TOKEN, 0);
10748f343b09SGreg Clayton             if (image_token == LLDB_INVALID_IMAGE_TOKEN)
10758f343b09SGreg Clayton             {
10768f343b09SGreg Clayton                 result.AppendErrorWithFormat ("invalid image index argument '%s'", image_token_cstr);
10778f343b09SGreg Clayton                 result.SetStatus (eReturnStatusFailed);
10788f343b09SGreg Clayton                 break;
10798f343b09SGreg Clayton             }
10808f343b09SGreg Clayton             else
10818f343b09SGreg Clayton             {
10828f343b09SGreg Clayton                 Error error (process->UnloadImage(image_token));
10838f343b09SGreg Clayton                 if (error.Success())
10848f343b09SGreg Clayton                 {
10858f343b09SGreg Clayton                     result.AppendMessageWithFormat ("Unloading shared library with index %u...ok\n", image_token);
10868f343b09SGreg Clayton                     result.SetStatus (eReturnStatusSuccessFinishResult);
10878f343b09SGreg Clayton                 }
10888f343b09SGreg Clayton                 else
10898f343b09SGreg Clayton                 {
10908f343b09SGreg Clayton                     result.AppendErrorWithFormat ("failed to unload image: %s", error.AsCString());
10918f343b09SGreg Clayton                     result.SetStatus (eReturnStatusFailed);
10928f343b09SGreg Clayton                     break;
10938f343b09SGreg Clayton                 }
10948f343b09SGreg Clayton             }
10958f343b09SGreg Clayton         }
10968f343b09SGreg Clayton         return result.Succeeded();
10978f343b09SGreg Clayton     }
10988f343b09SGreg Clayton };
10998f343b09SGreg Clayton 
11008f343b09SGreg Clayton //-------------------------------------------------------------------------
110130fdc8d8SChris Lattner // CommandObjectProcessSignal
110230fdc8d8SChris Lattner //-------------------------------------------------------------------------
1103bb9caf73SJim Ingham #pragma mark CommandObjectProcessSignal
110430fdc8d8SChris Lattner 
11055a988416SJim Ingham class CommandObjectProcessSignal : public CommandObjectParsed
110630fdc8d8SChris Lattner {
110730fdc8d8SChris Lattner public:
110830fdc8d8SChris Lattner 
1109a7015092SGreg Clayton     CommandObjectProcessSignal (CommandInterpreter &interpreter) :
11105a988416SJim Ingham         CommandObjectParsed (interpreter,
1111a7015092SGreg Clayton                              "process signal",
1112e3d26315SCaroline Tice                              "Send a UNIX signal to the current process being debugged.",
1113405fe67fSCaroline Tice                              NULL)
111430fdc8d8SChris Lattner     {
1115405fe67fSCaroline Tice         CommandArgumentEntry arg;
1116405fe67fSCaroline Tice         CommandArgumentData signal_arg;
1117405fe67fSCaroline Tice 
1118405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
1119c0dbdfb6SCaroline Tice         signal_arg.arg_type = eArgTypeUnixSignal;
1120405fe67fSCaroline Tice         signal_arg.arg_repetition = eArgRepeatPlain;
1121405fe67fSCaroline Tice 
1122405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
1123405fe67fSCaroline Tice         arg.push_back (signal_arg);
1124405fe67fSCaroline Tice 
1125405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
1126405fe67fSCaroline Tice         m_arguments.push_back (arg);
112730fdc8d8SChris Lattner     }
112830fdc8d8SChris Lattner 
112930fdc8d8SChris Lattner     ~CommandObjectProcessSignal ()
113030fdc8d8SChris Lattner     {
113130fdc8d8SChris Lattner     }
113230fdc8d8SChris Lattner 
11335a988416SJim Ingham protected:
113430fdc8d8SChris Lattner     bool
11355a988416SJim Ingham     DoExecute (Args& command,
113630fdc8d8SChris Lattner              CommandReturnObject &result)
113730fdc8d8SChris Lattner     {
1138c14ee32dSGreg Clayton         Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
113930fdc8d8SChris Lattner         if (process == NULL)
114030fdc8d8SChris Lattner         {
114130fdc8d8SChris Lattner             result.AppendError ("no process to signal");
114230fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
114330fdc8d8SChris Lattner             return false;
114430fdc8d8SChris Lattner         }
114530fdc8d8SChris Lattner 
114630fdc8d8SChris Lattner         if (command.GetArgumentCount() == 1)
114730fdc8d8SChris Lattner         {
1148237cd906SGreg Clayton             int signo = LLDB_INVALID_SIGNAL_NUMBER;
1149237cd906SGreg Clayton 
1150237cd906SGreg Clayton             const char *signal_name = command.GetArgumentAtIndex(0);
1151237cd906SGreg Clayton             if (::isxdigit (signal_name[0]))
1152237cd906SGreg Clayton                 signo = Args::StringToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0);
1153237cd906SGreg Clayton             else
1154237cd906SGreg Clayton                 signo = process->GetUnixSignals().GetSignalNumberFromName (signal_name);
1155237cd906SGreg Clayton 
1156237cd906SGreg Clayton             if (signo == LLDB_INVALID_SIGNAL_NUMBER)
115730fdc8d8SChris Lattner             {
115830fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("Invalid signal argument '%s'.\n", command.GetArgumentAtIndex(0));
115930fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
116030fdc8d8SChris Lattner             }
116130fdc8d8SChris Lattner             else
116230fdc8d8SChris Lattner             {
116330fdc8d8SChris Lattner                 Error error (process->Signal (signo));
116430fdc8d8SChris Lattner                 if (error.Success())
116530fdc8d8SChris Lattner                 {
116630fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusSuccessFinishResult);
116730fdc8d8SChris Lattner                 }
116830fdc8d8SChris Lattner                 else
116930fdc8d8SChris Lattner                 {
117030fdc8d8SChris Lattner                     result.AppendErrorWithFormat ("Failed to send signal %i: %s\n", signo, error.AsCString());
117130fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
117230fdc8d8SChris Lattner                 }
117330fdc8d8SChris Lattner             }
117430fdc8d8SChris Lattner         }
117530fdc8d8SChris Lattner         else
117630fdc8d8SChris Lattner         {
1177fd54b368SJason Molenda             result.AppendErrorWithFormat("'%s' takes exactly one signal number argument:\nUsage: %s\n", m_cmd_name.c_str(),
117830fdc8d8SChris Lattner                                         m_cmd_syntax.c_str());
117930fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
118030fdc8d8SChris Lattner         }
118130fdc8d8SChris Lattner         return result.Succeeded();
118230fdc8d8SChris Lattner     }
118330fdc8d8SChris Lattner };
118430fdc8d8SChris Lattner 
118530fdc8d8SChris Lattner 
118630fdc8d8SChris Lattner //-------------------------------------------------------------------------
118730fdc8d8SChris Lattner // CommandObjectProcessInterrupt
118830fdc8d8SChris Lattner //-------------------------------------------------------------------------
1189bb9caf73SJim Ingham #pragma mark CommandObjectProcessInterrupt
119030fdc8d8SChris Lattner 
11915a988416SJim Ingham class CommandObjectProcessInterrupt : public CommandObjectParsed
119230fdc8d8SChris Lattner {
119330fdc8d8SChris Lattner public:
119430fdc8d8SChris Lattner 
119530fdc8d8SChris Lattner 
1196a7015092SGreg Clayton     CommandObjectProcessInterrupt (CommandInterpreter &interpreter) :
11975a988416SJim Ingham         CommandObjectParsed (interpreter,
1198a7015092SGreg Clayton                              "process interrupt",
1199e3d26315SCaroline Tice                              "Interrupt the current process being debugged.",
120030fdc8d8SChris Lattner                              "process interrupt",
120130fdc8d8SChris Lattner                              eFlagProcessMustBeLaunched)
120230fdc8d8SChris Lattner     {
120330fdc8d8SChris Lattner     }
120430fdc8d8SChris Lattner 
120530fdc8d8SChris Lattner     ~CommandObjectProcessInterrupt ()
120630fdc8d8SChris Lattner     {
120730fdc8d8SChris Lattner     }
120830fdc8d8SChris Lattner 
12095a988416SJim Ingham protected:
121030fdc8d8SChris Lattner     bool
12115a988416SJim Ingham     DoExecute (Args& command,
121230fdc8d8SChris Lattner              CommandReturnObject &result)
121330fdc8d8SChris Lattner     {
1214c14ee32dSGreg Clayton         Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
121530fdc8d8SChris Lattner         if (process == NULL)
121630fdc8d8SChris Lattner         {
121730fdc8d8SChris Lattner             result.AppendError ("no process to halt");
121830fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
121930fdc8d8SChris Lattner             return false;
122030fdc8d8SChris Lattner         }
122130fdc8d8SChris Lattner 
122230fdc8d8SChris Lattner         if (command.GetArgumentCount() == 0)
122330fdc8d8SChris Lattner         {
122430fdc8d8SChris Lattner             Error error(process->Halt ());
122530fdc8d8SChris Lattner             if (error.Success())
122630fdc8d8SChris Lattner             {
122730fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusSuccessFinishResult);
122830fdc8d8SChris Lattner 
122930fdc8d8SChris Lattner                 // Maybe we should add a "SuspendThreadPlans so we
123030fdc8d8SChris Lattner                 // can halt, and keep in place all the current thread plans.
123130fdc8d8SChris Lattner                 process->GetThreadList().DiscardThreadPlans();
123230fdc8d8SChris Lattner             }
123330fdc8d8SChris Lattner             else
123430fdc8d8SChris Lattner             {
123530fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("Failed to halt process: %s\n", error.AsCString());
123630fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
123730fdc8d8SChris Lattner             }
123830fdc8d8SChris Lattner         }
123930fdc8d8SChris Lattner         else
124030fdc8d8SChris Lattner         {
1241fd54b368SJason Molenda             result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n",
124230fdc8d8SChris Lattner                                         m_cmd_name.c_str(),
124330fdc8d8SChris Lattner                                         m_cmd_syntax.c_str());
124430fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
124530fdc8d8SChris Lattner         }
124630fdc8d8SChris Lattner         return result.Succeeded();
124730fdc8d8SChris Lattner     }
124830fdc8d8SChris Lattner };
124930fdc8d8SChris Lattner 
125030fdc8d8SChris Lattner //-------------------------------------------------------------------------
125130fdc8d8SChris Lattner // CommandObjectProcessKill
125230fdc8d8SChris Lattner //-------------------------------------------------------------------------
1253bb9caf73SJim Ingham #pragma mark CommandObjectProcessKill
125430fdc8d8SChris Lattner 
12555a988416SJim Ingham class CommandObjectProcessKill : public CommandObjectParsed
125630fdc8d8SChris Lattner {
125730fdc8d8SChris Lattner public:
125830fdc8d8SChris Lattner 
1259a7015092SGreg Clayton     CommandObjectProcessKill (CommandInterpreter &interpreter) :
12605a988416SJim Ingham         CommandObjectParsed (interpreter,
1261a7015092SGreg Clayton                              "process kill",
1262e3d26315SCaroline Tice                              "Terminate the current process being debugged.",
126330fdc8d8SChris Lattner                              "process kill",
126430fdc8d8SChris Lattner                              eFlagProcessMustBeLaunched)
126530fdc8d8SChris Lattner     {
126630fdc8d8SChris Lattner     }
126730fdc8d8SChris Lattner 
126830fdc8d8SChris Lattner     ~CommandObjectProcessKill ()
126930fdc8d8SChris Lattner     {
127030fdc8d8SChris Lattner     }
127130fdc8d8SChris Lattner 
12725a988416SJim Ingham protected:
127330fdc8d8SChris Lattner     bool
12745a988416SJim Ingham     DoExecute (Args& command,
127530fdc8d8SChris Lattner              CommandReturnObject &result)
127630fdc8d8SChris Lattner     {
1277c14ee32dSGreg Clayton         Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
127830fdc8d8SChris Lattner         if (process == NULL)
127930fdc8d8SChris Lattner         {
128030fdc8d8SChris Lattner             result.AppendError ("no process to kill");
128130fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
128230fdc8d8SChris Lattner             return false;
128330fdc8d8SChris Lattner         }
128430fdc8d8SChris Lattner 
128530fdc8d8SChris Lattner         if (command.GetArgumentCount() == 0)
128630fdc8d8SChris Lattner         {
128730fdc8d8SChris Lattner             Error error (process->Destroy());
128830fdc8d8SChris Lattner             if (error.Success())
128930fdc8d8SChris Lattner             {
129030fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusSuccessFinishResult);
129130fdc8d8SChris Lattner             }
129230fdc8d8SChris Lattner             else
129330fdc8d8SChris Lattner             {
129430fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString());
129530fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
129630fdc8d8SChris Lattner             }
129730fdc8d8SChris Lattner         }
129830fdc8d8SChris Lattner         else
129930fdc8d8SChris Lattner         {
1300fd54b368SJason Molenda             result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n",
130130fdc8d8SChris Lattner                                         m_cmd_name.c_str(),
130230fdc8d8SChris Lattner                                         m_cmd_syntax.c_str());
130330fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
130430fdc8d8SChris Lattner         }
130530fdc8d8SChris Lattner         return result.Succeeded();
130630fdc8d8SChris Lattner     }
130730fdc8d8SChris Lattner };
130830fdc8d8SChris Lattner 
130930fdc8d8SChris Lattner //-------------------------------------------------------------------------
13104b9bea87SJim Ingham // CommandObjectProcessStatus
13114b9bea87SJim Ingham //-------------------------------------------------------------------------
1312bb9caf73SJim Ingham #pragma mark CommandObjectProcessStatus
1313bb9caf73SJim Ingham 
13145a988416SJim Ingham class CommandObjectProcessStatus : public CommandObjectParsed
13154b9bea87SJim Ingham {
13164b9bea87SJim Ingham public:
1317a7015092SGreg Clayton     CommandObjectProcessStatus (CommandInterpreter &interpreter) :
13185a988416SJim Ingham         CommandObjectParsed (interpreter,
1319a7015092SGreg Clayton                              "process status",
1320e3d26315SCaroline Tice                              "Show the current status and location of executing process.",
1321e3d26315SCaroline Tice                              "process status",
13224b9bea87SJim Ingham                              0)
13234b9bea87SJim Ingham     {
13244b9bea87SJim Ingham     }
13254b9bea87SJim Ingham 
13264b9bea87SJim Ingham     ~CommandObjectProcessStatus()
13274b9bea87SJim Ingham     {
13284b9bea87SJim Ingham     }
13294b9bea87SJim Ingham 
13304b9bea87SJim Ingham 
13314b9bea87SJim Ingham     bool
13325a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
13334b9bea87SJim Ingham     {
13347260f620SGreg Clayton         Stream &strm = result.GetOutputStream();
13354b9bea87SJim Ingham         result.SetStatus (eReturnStatusSuccessFinishNoResult);
13368b82f087SGreg Clayton         ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
1337c14ee32dSGreg Clayton         Process *process = exe_ctx.GetProcessPtr();
1338c14ee32dSGreg Clayton         if (process)
13394b9bea87SJim Ingham         {
13407260f620SGreg Clayton             const bool only_threads_with_stop_reason = true;
13417260f620SGreg Clayton             const uint32_t start_frame = 0;
13427260f620SGreg Clayton             const uint32_t num_frames = 1;
13437260f620SGreg Clayton             const uint32_t num_frames_with_source = 1;
1344c14ee32dSGreg Clayton             process->GetStatus(strm);
1345c14ee32dSGreg Clayton             process->GetThreadStatus (strm,
13467260f620SGreg Clayton                                       only_threads_with_stop_reason,
13477260f620SGreg Clayton                                       start_frame,
13487260f620SGreg Clayton                                       num_frames,
13497260f620SGreg Clayton                                       num_frames_with_source);
13507260f620SGreg Clayton 
13514b9bea87SJim Ingham         }
13524b9bea87SJim Ingham         else
13534b9bea87SJim Ingham         {
13547260f620SGreg Clayton             result.AppendError ("No process.");
13554b9bea87SJim Ingham             result.SetStatus (eReturnStatusFailed);
13564b9bea87SJim Ingham         }
13574b9bea87SJim Ingham         return result.Succeeded();
13584b9bea87SJim Ingham     }
13594b9bea87SJim Ingham };
13604b9bea87SJim Ingham 
13614b9bea87SJim Ingham //-------------------------------------------------------------------------
136235731357SCaroline Tice // CommandObjectProcessHandle
136335731357SCaroline Tice //-------------------------------------------------------------------------
1364bb9caf73SJim Ingham #pragma mark CommandObjectProcessHandle
136535731357SCaroline Tice 
13665a988416SJim Ingham class CommandObjectProcessHandle : public CommandObjectParsed
136735731357SCaroline Tice {
136835731357SCaroline Tice public:
136935731357SCaroline Tice 
137035731357SCaroline Tice     class CommandOptions : public Options
137135731357SCaroline Tice     {
137235731357SCaroline Tice     public:
137335731357SCaroline Tice 
1374eb0103f2SGreg Clayton         CommandOptions (CommandInterpreter &interpreter) :
1375eb0103f2SGreg Clayton             Options (interpreter)
137635731357SCaroline Tice         {
1377f6b8b581SGreg Clayton             OptionParsingStarting ();
137835731357SCaroline Tice         }
137935731357SCaroline Tice 
138035731357SCaroline Tice         ~CommandOptions ()
138135731357SCaroline Tice         {
138235731357SCaroline Tice         }
138335731357SCaroline Tice 
138435731357SCaroline Tice         Error
1385f6b8b581SGreg Clayton         SetOptionValue (uint32_t option_idx, const char *option_arg)
138635731357SCaroline Tice         {
138735731357SCaroline Tice             Error error;
138835731357SCaroline Tice             char short_option = (char) m_getopt_table[option_idx].val;
138935731357SCaroline Tice 
139035731357SCaroline Tice             switch (short_option)
139135731357SCaroline Tice             {
139235731357SCaroline Tice                 case 's':
139335731357SCaroline Tice                     stop = option_arg;
139435731357SCaroline Tice                     break;
139535731357SCaroline Tice                 case 'n':
139635731357SCaroline Tice                     notify = option_arg;
139735731357SCaroline Tice                     break;
139835731357SCaroline Tice                 case 'p':
139935731357SCaroline Tice                     pass = option_arg;
140035731357SCaroline Tice                     break;
140135731357SCaroline Tice                 default:
140286edbf41SGreg Clayton                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
140335731357SCaroline Tice                     break;
140435731357SCaroline Tice             }
140535731357SCaroline Tice             return error;
140635731357SCaroline Tice         }
140735731357SCaroline Tice 
140835731357SCaroline Tice         void
1409f6b8b581SGreg Clayton         OptionParsingStarting ()
141035731357SCaroline Tice         {
141135731357SCaroline Tice             stop.clear();
141235731357SCaroline Tice             notify.clear();
141335731357SCaroline Tice             pass.clear();
141435731357SCaroline Tice         }
141535731357SCaroline Tice 
1416e0d378b3SGreg Clayton         const OptionDefinition*
141735731357SCaroline Tice         GetDefinitions ()
141835731357SCaroline Tice         {
141935731357SCaroline Tice             return g_option_table;
142035731357SCaroline Tice         }
142135731357SCaroline Tice 
142235731357SCaroline Tice         // Options table: Required for subclasses of Options.
142335731357SCaroline Tice 
1424e0d378b3SGreg Clayton         static OptionDefinition g_option_table[];
142535731357SCaroline Tice 
142635731357SCaroline Tice         // Instance variables to hold the values for command options.
142735731357SCaroline Tice 
142835731357SCaroline Tice         std::string stop;
142935731357SCaroline Tice         std::string notify;
143035731357SCaroline Tice         std::string pass;
143135731357SCaroline Tice     };
143235731357SCaroline Tice 
143335731357SCaroline Tice 
143435731357SCaroline Tice     CommandObjectProcessHandle (CommandInterpreter &interpreter) :
14355a988416SJim Ingham         CommandObjectParsed (interpreter,
143635731357SCaroline Tice                              "process handle",
143710ad7993SCaroline Tice                              "Show or update what the process and debugger should do with various signals received from the OS.",
1438eb0103f2SGreg Clayton                              NULL),
1439eb0103f2SGreg Clayton         m_options (interpreter)
144035731357SCaroline Tice     {
144110ad7993SCaroline Tice         SetHelpLong ("If no signals are specified, update them all.  If no update option is specified, list the current values.\n");
144235731357SCaroline Tice         CommandArgumentEntry arg;
1443c0dbdfb6SCaroline Tice         CommandArgumentData signal_arg;
144435731357SCaroline Tice 
1445c0dbdfb6SCaroline Tice         signal_arg.arg_type = eArgTypeUnixSignal;
1446c0dbdfb6SCaroline Tice         signal_arg.arg_repetition = eArgRepeatStar;
144735731357SCaroline Tice 
1448c0dbdfb6SCaroline Tice         arg.push_back (signal_arg);
144935731357SCaroline Tice 
145035731357SCaroline Tice         m_arguments.push_back (arg);
145135731357SCaroline Tice     }
145235731357SCaroline Tice 
145335731357SCaroline Tice     ~CommandObjectProcessHandle ()
145435731357SCaroline Tice     {
145535731357SCaroline Tice     }
145635731357SCaroline Tice 
145735731357SCaroline Tice     Options *
145835731357SCaroline Tice     GetOptions ()
145935731357SCaroline Tice     {
146035731357SCaroline Tice         return &m_options;
146135731357SCaroline Tice     }
146235731357SCaroline Tice 
146335731357SCaroline Tice     bool
146410ad7993SCaroline Tice     VerifyCommandOptionValue (const std::string &option, int &real_value)
146535731357SCaroline Tice     {
146635731357SCaroline Tice         bool okay = true;
146735731357SCaroline Tice 
146810ad7993SCaroline Tice         bool success = false;
146910ad7993SCaroline Tice         bool tmp_value = Args::StringToBoolean (option.c_str(), false, &success);
147010ad7993SCaroline Tice 
147110ad7993SCaroline Tice         if (success && tmp_value)
147210ad7993SCaroline Tice             real_value = 1;
147310ad7993SCaroline Tice         else if (success && !tmp_value)
147410ad7993SCaroline Tice             real_value = 0;
147535731357SCaroline Tice         else
147635731357SCaroline Tice         {
147735731357SCaroline Tice             // If the value isn't 'true' or 'false', it had better be 0 or 1.
147810ad7993SCaroline Tice             real_value = Args::StringToUInt32 (option.c_str(), 3);
147910ad7993SCaroline Tice             if (real_value != 0 && real_value != 1)
148035731357SCaroline Tice                 okay = false;
148135731357SCaroline Tice         }
148235731357SCaroline Tice 
148335731357SCaroline Tice         return okay;
148435731357SCaroline Tice     }
148535731357SCaroline Tice 
148610ad7993SCaroline Tice     void
148710ad7993SCaroline Tice     PrintSignalHeader (Stream &str)
148810ad7993SCaroline Tice     {
148910ad7993SCaroline Tice         str.Printf ("NAME        PASS   STOP   NOTIFY\n");
149010ad7993SCaroline Tice         str.Printf ("==========  =====  =====  ======\n");
149110ad7993SCaroline Tice     }
149210ad7993SCaroline Tice 
149310ad7993SCaroline Tice     void
149410ad7993SCaroline Tice     PrintSignal (Stream &str, int32_t signo, const char *sig_name, UnixSignals &signals)
149510ad7993SCaroline Tice     {
149610ad7993SCaroline Tice         bool stop;
149710ad7993SCaroline Tice         bool suppress;
149810ad7993SCaroline Tice         bool notify;
149910ad7993SCaroline Tice 
150010ad7993SCaroline Tice         str.Printf ("%-10s  ", sig_name);
150110ad7993SCaroline Tice         if (signals.GetSignalInfo (signo, suppress, stop, notify))
150210ad7993SCaroline Tice         {
150310ad7993SCaroline Tice             bool pass = !suppress;
150410ad7993SCaroline Tice             str.Printf ("%s  %s  %s",
150510ad7993SCaroline Tice                         (pass ? "true " : "false"),
150610ad7993SCaroline Tice                         (stop ? "true " : "false"),
150710ad7993SCaroline Tice                         (notify ? "true " : "false"));
150810ad7993SCaroline Tice         }
150910ad7993SCaroline Tice         str.Printf ("\n");
151010ad7993SCaroline Tice     }
151110ad7993SCaroline Tice 
151210ad7993SCaroline Tice     void
151310ad7993SCaroline Tice     PrintSignalInformation (Stream &str, Args &signal_args, int num_valid_signals, UnixSignals &signals)
151410ad7993SCaroline Tice     {
151510ad7993SCaroline Tice         PrintSignalHeader (str);
151610ad7993SCaroline Tice 
151710ad7993SCaroline Tice         if (num_valid_signals > 0)
151810ad7993SCaroline Tice         {
151910ad7993SCaroline Tice             size_t num_args = signal_args.GetArgumentCount();
152010ad7993SCaroline Tice             for (size_t i = 0; i < num_args; ++i)
152110ad7993SCaroline Tice             {
152210ad7993SCaroline Tice                 int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i));
152310ad7993SCaroline Tice                 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
152410ad7993SCaroline Tice                     PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals);
152510ad7993SCaroline Tice             }
152610ad7993SCaroline Tice         }
152710ad7993SCaroline Tice         else // Print info for ALL signals
152810ad7993SCaroline Tice         {
152910ad7993SCaroline Tice             int32_t signo = signals.GetFirstSignalNumber();
153010ad7993SCaroline Tice             while (signo != LLDB_INVALID_SIGNAL_NUMBER)
153110ad7993SCaroline Tice             {
153210ad7993SCaroline Tice                 PrintSignal (str, signo, signals.GetSignalAsCString (signo), signals);
153310ad7993SCaroline Tice                 signo = signals.GetNextSignalNumber (signo);
153410ad7993SCaroline Tice             }
153510ad7993SCaroline Tice         }
153610ad7993SCaroline Tice     }
153710ad7993SCaroline Tice 
15385a988416SJim Ingham protected:
153935731357SCaroline Tice     bool
15405a988416SJim Ingham     DoExecute (Args &signal_args, CommandReturnObject &result)
154135731357SCaroline Tice     {
154235731357SCaroline Tice         TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
154335731357SCaroline Tice 
154435731357SCaroline Tice         if (!target_sp)
154535731357SCaroline Tice         {
154635731357SCaroline Tice             result.AppendError ("No current target;"
154735731357SCaroline Tice                                 " cannot handle signals until you have a valid target and process.\n");
154835731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
154935731357SCaroline Tice             return false;
155035731357SCaroline Tice         }
155135731357SCaroline Tice 
155235731357SCaroline Tice         ProcessSP process_sp = target_sp->GetProcessSP();
155335731357SCaroline Tice 
155435731357SCaroline Tice         if (!process_sp)
155535731357SCaroline Tice         {
155635731357SCaroline Tice             result.AppendError ("No current process; cannot handle signals until you have a valid process.\n");
155735731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
155835731357SCaroline Tice             return false;
155935731357SCaroline Tice         }
156035731357SCaroline Tice 
156135731357SCaroline Tice         int stop_action = -1;   // -1 means leave the current setting alone
156235731357SCaroline Tice         int pass_action = -1;   // -1 means leave the current setting alone
156335731357SCaroline Tice         int notify_action = -1; // -1 means leave the current setting alone
156435731357SCaroline Tice 
156535731357SCaroline Tice         if (! m_options.stop.empty()
156610ad7993SCaroline Tice             && ! VerifyCommandOptionValue (m_options.stop, stop_action))
156735731357SCaroline Tice         {
156835731357SCaroline Tice             result.AppendError ("Invalid argument for command option --stop; must be true or false.\n");
156935731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
157035731357SCaroline Tice             return false;
157135731357SCaroline Tice         }
157235731357SCaroline Tice 
157335731357SCaroline Tice         if (! m_options.notify.empty()
157410ad7993SCaroline Tice             && ! VerifyCommandOptionValue (m_options.notify, notify_action))
157535731357SCaroline Tice         {
157635731357SCaroline Tice             result.AppendError ("Invalid argument for command option --notify; must be true or false.\n");
157735731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
157835731357SCaroline Tice             return false;
157935731357SCaroline Tice         }
158035731357SCaroline Tice 
158135731357SCaroline Tice         if (! m_options.pass.empty()
158210ad7993SCaroline Tice             && ! VerifyCommandOptionValue (m_options.pass, pass_action))
158335731357SCaroline Tice         {
158435731357SCaroline Tice             result.AppendError ("Invalid argument for command option --pass; must be true or false.\n");
158535731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
158635731357SCaroline Tice             return false;
158735731357SCaroline Tice         }
158835731357SCaroline Tice 
158935731357SCaroline Tice         size_t num_args = signal_args.GetArgumentCount();
159035731357SCaroline Tice         UnixSignals &signals = process_sp->GetUnixSignals();
159135731357SCaroline Tice         int num_signals_set = 0;
159235731357SCaroline Tice 
159310ad7993SCaroline Tice         if (num_args > 0)
159410ad7993SCaroline Tice         {
159535731357SCaroline Tice             for (size_t i = 0; i < num_args; ++i)
159635731357SCaroline Tice             {
159735731357SCaroline Tice                 int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i));
159835731357SCaroline Tice                 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
159935731357SCaroline Tice                 {
160010ad7993SCaroline Tice                     // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees
160135731357SCaroline Tice                     // the value is either 0 or 1.
160235731357SCaroline Tice                     if (stop_action != -1)
160335731357SCaroline Tice                         signals.SetShouldStop (signo, (bool) stop_action);
160435731357SCaroline Tice                     if (pass_action != -1)
160535731357SCaroline Tice                     {
160610ad7993SCaroline Tice                         bool suppress = ! ((bool) pass_action);
160710ad7993SCaroline Tice                         signals.SetShouldSuppress (signo, suppress);
160835731357SCaroline Tice                     }
160935731357SCaroline Tice                     if (notify_action != -1)
161035731357SCaroline Tice                         signals.SetShouldNotify (signo, (bool) notify_action);
161135731357SCaroline Tice                     ++num_signals_set;
161235731357SCaroline Tice                 }
161335731357SCaroline Tice                 else
161435731357SCaroline Tice                 {
161535731357SCaroline Tice                     result.AppendErrorWithFormat ("Invalid signal name '%s'\n", signal_args.GetArgumentAtIndex (i));
161635731357SCaroline Tice                 }
161735731357SCaroline Tice             }
161810ad7993SCaroline Tice         }
161910ad7993SCaroline Tice         else
162010ad7993SCaroline Tice         {
162110ad7993SCaroline Tice             // No signal specified, if any command options were specified, update ALL signals.
162210ad7993SCaroline Tice             if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1))
162310ad7993SCaroline Tice             {
162410ad7993SCaroline Tice                 if (m_interpreter.Confirm ("Do you really want to update all the signals?", false))
162510ad7993SCaroline Tice                 {
162610ad7993SCaroline Tice                     int32_t signo = signals.GetFirstSignalNumber();
162710ad7993SCaroline Tice                     while (signo != LLDB_INVALID_SIGNAL_NUMBER)
162810ad7993SCaroline Tice                     {
162910ad7993SCaroline Tice                         if (notify_action != -1)
163010ad7993SCaroline Tice                             signals.SetShouldNotify (signo, (bool) notify_action);
163110ad7993SCaroline Tice                         if (stop_action != -1)
163210ad7993SCaroline Tice                             signals.SetShouldStop (signo, (bool) stop_action);
163310ad7993SCaroline Tice                         if (pass_action != -1)
163410ad7993SCaroline Tice                         {
163510ad7993SCaroline Tice                             bool suppress = ! ((bool) pass_action);
163610ad7993SCaroline Tice                             signals.SetShouldSuppress (signo, suppress);
163710ad7993SCaroline Tice                         }
163810ad7993SCaroline Tice                         signo = signals.GetNextSignalNumber (signo);
163910ad7993SCaroline Tice                     }
164010ad7993SCaroline Tice                 }
164110ad7993SCaroline Tice             }
164210ad7993SCaroline Tice         }
164310ad7993SCaroline Tice 
164410ad7993SCaroline Tice         PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals);
164535731357SCaroline Tice 
164635731357SCaroline Tice         if (num_signals_set > 0)
164735731357SCaroline Tice             result.SetStatus (eReturnStatusSuccessFinishNoResult);
164835731357SCaroline Tice         else
164935731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
165035731357SCaroline Tice 
165135731357SCaroline Tice         return result.Succeeded();
165235731357SCaroline Tice     }
165335731357SCaroline Tice 
165435731357SCaroline Tice     CommandOptions m_options;
165535731357SCaroline Tice };
165635731357SCaroline Tice 
1657e0d378b3SGreg Clayton OptionDefinition
165835731357SCaroline Tice CommandObjectProcessHandle::CommandOptions::g_option_table[] =
165935731357SCaroline Tice {
166035731357SCaroline 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." },
166135731357SCaroline 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." },
166235731357SCaroline Tice { LLDB_OPT_SET_1, false, "pass",  'p', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." },
166335731357SCaroline Tice { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
166435731357SCaroline Tice };
166535731357SCaroline Tice 
166635731357SCaroline Tice //-------------------------------------------------------------------------
166730fdc8d8SChris Lattner // CommandObjectMultiwordProcess
166830fdc8d8SChris Lattner //-------------------------------------------------------------------------
166930fdc8d8SChris Lattner 
16706611103cSGreg Clayton CommandObjectMultiwordProcess::CommandObjectMultiwordProcess (CommandInterpreter &interpreter) :
1671a7015092SGreg Clayton     CommandObjectMultiword (interpreter,
1672a7015092SGreg Clayton                             "process",
167330fdc8d8SChris Lattner                             "A set of commands for operating on a process.",
167430fdc8d8SChris Lattner                             "process <subcommand> [<subcommand-options>]")
167530fdc8d8SChris Lattner {
1676a7015092SGreg Clayton     LoadSubCommand ("attach",      CommandObjectSP (new CommandObjectProcessAttach    (interpreter)));
1677a7015092SGreg Clayton     LoadSubCommand ("launch",      CommandObjectSP (new CommandObjectProcessLaunch    (interpreter)));
1678a7015092SGreg Clayton     LoadSubCommand ("continue",    CommandObjectSP (new CommandObjectProcessContinue  (interpreter)));
1679b766a73dSGreg Clayton     LoadSubCommand ("connect",     CommandObjectSP (new CommandObjectProcessConnect   (interpreter)));
1680a7015092SGreg Clayton     LoadSubCommand ("detach",      CommandObjectSP (new CommandObjectProcessDetach    (interpreter)));
16818f343b09SGreg Clayton     LoadSubCommand ("load",        CommandObjectSP (new CommandObjectProcessLoad      (interpreter)));
16828f343b09SGreg Clayton     LoadSubCommand ("unload",      CommandObjectSP (new CommandObjectProcessUnload    (interpreter)));
1683a7015092SGreg Clayton     LoadSubCommand ("signal",      CommandObjectSP (new CommandObjectProcessSignal    (interpreter)));
168435731357SCaroline Tice     LoadSubCommand ("handle",      CommandObjectSP (new CommandObjectProcessHandle    (interpreter)));
1685a7015092SGreg Clayton     LoadSubCommand ("status",      CommandObjectSP (new CommandObjectProcessStatus    (interpreter)));
1686a7015092SGreg Clayton     LoadSubCommand ("interrupt",   CommandObjectSP (new CommandObjectProcessInterrupt (interpreter)));
1687a7015092SGreg Clayton     LoadSubCommand ("kill",        CommandObjectSP (new CommandObjectProcessKill      (interpreter)));
168830fdc8d8SChris Lattner }
168930fdc8d8SChris Lattner 
169030fdc8d8SChris Lattner CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess ()
169130fdc8d8SChris Lattner {
169230fdc8d8SChris Lattner }
169330fdc8d8SChris Lattner 
1694