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 
1093a64300SDaniel Malea #include "lldb/lldb-python.h"
1193a64300SDaniel Malea 
1230fdc8d8SChris Lattner #include "CommandObjectProcess.h"
1330fdc8d8SChris Lattner 
1430fdc8d8SChris Lattner // C Includes
1530fdc8d8SChris Lattner // C++ Includes
1630fdc8d8SChris Lattner // Other libraries and framework includes
1730fdc8d8SChris Lattner // Project includes
180e41084aSJim Ingham #include "lldb/Breakpoint/Breakpoint.h"
190e41084aSJim Ingham #include "lldb/Breakpoint/BreakpointLocation.h"
200e41084aSJim Ingham #include "lldb/Breakpoint/BreakpointSite.h"
2130fdc8d8SChris Lattner #include "lldb/Core/State.h"
221f746071SGreg Clayton #include "lldb/Core/Module.h"
237260f620SGreg Clayton #include "lldb/Host/Host.h"
240e41084aSJim Ingham #include "lldb/Interpreter/Args.h"
250e41084aSJim Ingham #include "lldb/Interpreter/Options.h"
2630fdc8d8SChris Lattner #include "lldb/Interpreter/CommandInterpreter.h"
2730fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h"
28e996fd30SGreg Clayton #include "lldb/Target/Platform.h"
2930fdc8d8SChris Lattner #include "lldb/Target/Process.h"
300e41084aSJim Ingham #include "lldb/Target/StopInfo.h"
3130fdc8d8SChris Lattner #include "lldb/Target/Target.h"
3230fdc8d8SChris Lattner #include "lldb/Target/Thread.h"
3330fdc8d8SChris Lattner 
3430fdc8d8SChris Lattner using namespace lldb;
3530fdc8d8SChris Lattner using namespace lldb_private;
3630fdc8d8SChris Lattner 
3730fdc8d8SChris Lattner //-------------------------------------------------------------------------
3830fdc8d8SChris Lattner // CommandObjectProcessLaunch
3930fdc8d8SChris Lattner //-------------------------------------------------------------------------
404bddaeb5SJim Ingham #pragma mark CommandObjectProcessLaunch
415a988416SJim Ingham class CommandObjectProcessLaunch : public CommandObjectParsed
4230fdc8d8SChris Lattner {
4330fdc8d8SChris Lattner public:
4430fdc8d8SChris Lattner 
45a7015092SGreg Clayton     CommandObjectProcessLaunch (CommandInterpreter &interpreter) :
465a988416SJim Ingham         CommandObjectParsed (interpreter,
47a7015092SGreg Clayton                              "process launch",
48e3d26315SCaroline Tice                              "Launch the executable in the debugger.",
49f9fc609fSGreg Clayton                              NULL,
50f9fc609fSGreg Clayton                              eFlagRequiresTarget),
51eb0103f2SGreg Clayton         m_options (interpreter)
5230fdc8d8SChris Lattner     {
53405fe67fSCaroline Tice         CommandArgumentEntry arg;
54405fe67fSCaroline Tice         CommandArgumentData run_args_arg;
55405fe67fSCaroline Tice 
56405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
57405fe67fSCaroline Tice         run_args_arg.arg_type = eArgTypeRunArgs;
58405fe67fSCaroline Tice         run_args_arg.arg_repetition = eArgRepeatOptional;
59405fe67fSCaroline Tice 
60405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
61405fe67fSCaroline Tice         arg.push_back (run_args_arg);
62405fe67fSCaroline Tice 
63405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
64405fe67fSCaroline Tice         m_arguments.push_back (arg);
6530fdc8d8SChris Lattner     }
6630fdc8d8SChris Lattner 
6730fdc8d8SChris Lattner 
6830fdc8d8SChris Lattner     ~CommandObjectProcessLaunch ()
6930fdc8d8SChris Lattner     {
7030fdc8d8SChris Lattner     }
7130fdc8d8SChris Lattner 
72c7bece56SGreg Clayton     virtual int
73e9ce62b6SJim Ingham     HandleArgumentCompletion (Args &input,
74e9ce62b6SJim Ingham                               int &cursor_index,
75e9ce62b6SJim Ingham                               int &cursor_char_position,
76e9ce62b6SJim Ingham                               OptionElementVector &opt_element_vector,
77e9ce62b6SJim Ingham                               int match_start_point,
78e9ce62b6SJim Ingham                               int max_return_elements,
79e9ce62b6SJim Ingham                               bool &word_complete,
80e9ce62b6SJim Ingham                               StringList &matches)
81e9ce62b6SJim Ingham     {
82e9ce62b6SJim Ingham         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
83e9ce62b6SJim Ingham         completion_str.erase (cursor_char_position);
84e9ce62b6SJim Ingham 
85e9ce62b6SJim Ingham         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
86e9ce62b6SJim Ingham                                                              CommandCompletions::eDiskFileCompletion,
87e9ce62b6SJim Ingham                                                              completion_str.c_str(),
88e9ce62b6SJim Ingham                                                              match_start_point,
89e9ce62b6SJim Ingham                                                              max_return_elements,
90e9ce62b6SJim Ingham                                                              NULL,
91e9ce62b6SJim Ingham                                                              word_complete,
92e9ce62b6SJim Ingham                                                              matches);
93e9ce62b6SJim Ingham         return matches.GetSize();
94e9ce62b6SJim Ingham     }
95e9ce62b6SJim Ingham 
9630fdc8d8SChris Lattner     Options *
9730fdc8d8SChris Lattner     GetOptions ()
9830fdc8d8SChris Lattner     {
9930fdc8d8SChris Lattner         return &m_options;
10030fdc8d8SChris Lattner     }
10130fdc8d8SChris Lattner 
1025a988416SJim Ingham     virtual const char *GetRepeatCommand (Args &current_command_args, uint32_t index)
1035a988416SJim Ingham     {
1045a988416SJim Ingham         // No repeat for "process launch"...
1055a988416SJim Ingham         return "";
1065a988416SJim Ingham     }
1075a988416SJim Ingham 
1085a988416SJim Ingham protected:
10930fdc8d8SChris Lattner     bool
1105a988416SJim Ingham     DoExecute (Args& launch_args, CommandReturnObject &result)
11130fdc8d8SChris Lattner     {
1121d885966SGreg Clayton         Debugger &debugger = m_interpreter.GetDebugger();
1131d885966SGreg Clayton         Target *target = debugger.GetSelectedTarget().get();
1141d885966SGreg Clayton         Error error;
11530fdc8d8SChris Lattner         // If our listener is NULL, users aren't allows to launch
11630fdc8d8SChris Lattner         char filename[PATH_MAX];
117aa149cbdSGreg Clayton         const Module *exe_module = target->GetExecutableModulePointer();
11871337622SGreg Clayton 
11971337622SGreg Clayton         if (exe_module == NULL)
12071337622SGreg Clayton         {
121effe5c95SGreg Clayton             result.AppendError ("no file in target, create a debug target using the 'target create' command");
12271337622SGreg Clayton             result.SetStatus (eReturnStatusFailed);
12371337622SGreg Clayton             return false;
12471337622SGreg Clayton         }
12571337622SGreg Clayton 
12671337622SGreg Clayton         StateType state = eStateInvalid;
127f9fc609fSGreg Clayton         Process *process = m_exe_ctx.GetProcessPtr();
12871337622SGreg Clayton         if (process)
12971337622SGreg Clayton         {
13071337622SGreg Clayton             state = process->GetState();
13171337622SGreg Clayton 
13271337622SGreg Clayton             if (process->IsAlive() && state != eStateConnected)
13330fdc8d8SChris Lattner             {
134513c26ceSGreg Clayton                 char message[1024];
135513c26ceSGreg Clayton                 if (process->GetState() == eStateAttaching)
136513c26ceSGreg Clayton                     ::strncpy (message, "There is a pending attach, abort it and launch a new process?", sizeof(message));
137513c26ceSGreg Clayton                 else
138513c26ceSGreg Clayton                     ::strncpy (message, "There is a running process, kill it and restart?", sizeof(message));
139513c26ceSGreg Clayton 
140513c26ceSGreg Clayton                 if (!m_interpreter.Confirm (message, true))
141bb9caf73SJim Ingham                 {
14230fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
14330fdc8d8SChris Lattner                     return false;
14430fdc8d8SChris Lattner                 }
145bb9caf73SJim Ingham                 else
146bb9caf73SJim Ingham                 {
1471d885966SGreg Clayton                     Error destroy_error (process->Destroy());
1481d885966SGreg Clayton                     if (destroy_error.Success())
149bb9caf73SJim Ingham                     {
150bb9caf73SJim Ingham                         result.SetStatus (eReturnStatusSuccessFinishResult);
151bb9caf73SJim Ingham                     }
152bb9caf73SJim Ingham                     else
153bb9caf73SJim Ingham                     {
1541d885966SGreg Clayton                         result.AppendErrorWithFormat ("Failed to kill process: %s\n", destroy_error.AsCString());
155bb9caf73SJim Ingham                         result.SetStatus (eReturnStatusFailed);
156bb9caf73SJim Ingham                     }
157bb9caf73SJim Ingham                 }
158bb9caf73SJim Ingham             }
15971337622SGreg Clayton         }
16030fdc8d8SChris Lattner 
16145392553SGreg Clayton         const char *target_settings_argv0 = target->GetArg0();
16245392553SGreg Clayton 
16345392553SGreg Clayton         exe_module->GetFileSpec().GetPath (filename, sizeof(filename));
16445392553SGreg Clayton 
16545392553SGreg Clayton         if (target_settings_argv0)
16645392553SGreg Clayton         {
16745392553SGreg Clayton             m_options.launch_info.GetArguments().AppendArgument (target_settings_argv0);
16845392553SGreg Clayton             m_options.launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), false);
16945392553SGreg Clayton         }
17045392553SGreg Clayton         else
17145392553SGreg Clayton         {
17245392553SGreg Clayton             m_options.launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), true);
17345392553SGreg Clayton         }
17445392553SGreg Clayton 
175144f3a9cSGreg Clayton         if (launch_args.GetArgumentCount() == 0)
176144f3a9cSGreg Clayton         {
17767cc0636SGreg Clayton             Args target_setting_args;
17845392553SGreg Clayton             if (target->GetRunArguments(target_setting_args))
17967cc0636SGreg Clayton                 m_options.launch_info.GetArguments().AppendArguments (target_setting_args);
180144f3a9cSGreg Clayton         }
181144f3a9cSGreg Clayton         else
18230fdc8d8SChris Lattner         {
18345392553SGreg Clayton             m_options.launch_info.GetArguments().AppendArguments (launch_args);
18445392553SGreg Clayton 
185162b597cSGreg Clayton             // Save the arguments for subsequent runs in the current target.
186162b597cSGreg Clayton             target->SetRunArguments (launch_args);
187982c9762SGreg Clayton         }
1881d885966SGreg Clayton 
189144f3a9cSGreg Clayton         if (target->GetDisableASLR())
190144f3a9cSGreg Clayton             m_options.launch_info.GetFlags().Set (eLaunchFlagDisableASLR);
191144f3a9cSGreg Clayton 
192144f3a9cSGreg Clayton         if (target->GetDisableSTDIO())
193144f3a9cSGreg Clayton             m_options.launch_info.GetFlags().Set (eLaunchFlagDisableSTDIO);
194144f3a9cSGreg Clayton 
195144f3a9cSGreg Clayton         m_options.launch_info.GetFlags().Set (eLaunchFlagDebug);
196144f3a9cSGreg Clayton 
197144f3a9cSGreg Clayton         Args environment;
198144f3a9cSGreg Clayton         target->GetEnvironmentAsArgs (environment);
199144f3a9cSGreg Clayton         if (environment.GetArgumentCount() > 0)
200144f3a9cSGreg Clayton             m_options.launch_info.GetEnvironmentEntries ().AppendArguments (environment);
201144f3a9cSGreg Clayton 
202*0161b49cSJim Ingham         // Get the value of synchronous execution here.  If you wait till after you have started to
203*0161b49cSJim Ingham         // run, then you could have hit a breakpoint, whose command might switch the value, and
204*0161b49cSJim Ingham         // then you'll pick up that incorrect value.
205*0161b49cSJim Ingham         bool synchronous_execution = m_interpreter.GetSynchronous ();
206*0161b49cSJim Ingham 
207ee95ed50SGreg Clayton         // Finalize the file actions, and if none were given, default to opening
208ee95ed50SGreg Clayton         // up a pseudo terminal
209ee95ed50SGreg Clayton         const bool default_to_use_pty = true;
210ee95ed50SGreg Clayton         m_options.launch_info.FinalizeFileActions (target, default_to_use_pty);
2111d885966SGreg Clayton 
2121d885966SGreg Clayton         if (state == eStateConnected)
2131d885966SGreg Clayton         {
2141d885966SGreg Clayton             if (m_options.launch_info.GetFlags().Test (eLaunchFlagLaunchInTTY))
2151d885966SGreg Clayton             {
2161d885966SGreg Clayton                 result.AppendWarning("can't launch in tty when launching through a remote connection");
2171d885966SGreg Clayton                 m_options.launch_info.GetFlags().Clear (eLaunchFlagLaunchInTTY);
2181d885966SGreg Clayton             }
2191d885966SGreg Clayton         }
220982c9762SGreg Clayton         else
221982c9762SGreg Clayton         {
222144f3a9cSGreg Clayton             if (!m_options.launch_info.GetArchitecture().IsValid())
223c9ed478aSGreg Clayton                 m_options.launch_info.GetArchitecture() = target->GetArchitecture();
224c9ed478aSGreg Clayton 
225c982b3d6SGreg Clayton             PlatformSP platform_sp (target->GetPlatform());
226c982b3d6SGreg Clayton 
227c982b3d6SGreg Clayton             if (platform_sp && platform_sp->CanDebugProcess ())
228c982b3d6SGreg Clayton             {
2291d885966SGreg Clayton                 process = target->GetPlatform()->DebugProcess (m_options.launch_info,
2301d885966SGreg Clayton                                                                debugger,
2311d885966SGreg Clayton                                                                target,
2321d885966SGreg Clayton                                                                debugger.GetListener(),
2331d885966SGreg Clayton                                                                error).get();
234c982b3d6SGreg Clayton             }
235c982b3d6SGreg Clayton             else
236c982b3d6SGreg Clayton             {
237c982b3d6SGreg Clayton                 const char *plugin_name = m_options.launch_info.GetProcessPluginName();
238c3776bf2SGreg Clayton                 process = target->CreateProcess (debugger.GetListener(), plugin_name, NULL).get();
239c982b3d6SGreg Clayton                 if (process)
240c982b3d6SGreg Clayton                     error = process->Launch (m_options.launch_info);
241c982b3d6SGreg Clayton             }
2421d885966SGreg Clayton 
2431d885966SGreg Clayton             if (process == NULL)
2441d885966SGreg Clayton             {
245144f3a9cSGreg Clayton                 result.SetError (error, "failed to launch or debug process");
2461d885966SGreg Clayton                 return false;
2471d885966SGreg Clayton             }
2481d885966SGreg Clayton         }
24930fdc8d8SChris Lattner 
25030fdc8d8SChris Lattner         if (error.Success())
25130fdc8d8SChris Lattner         {
25264195a2cSGreg Clayton             const char *archname = exe_module->GetArchitecture().GetArchitectureName();
25319388cfcSGreg Clayton 
254d01b2953SDaniel Malea             result.AppendMessageWithFormat ("Process %" PRIu64 " launched: '%s' (%s)\n", process->GetID(), filename, archname);
25505faeb71SGreg Clayton             result.SetDidChangeProcessState (true);
256982c9762SGreg Clayton             if (m_options.launch_info.GetFlags().Test(eLaunchFlagStopAtEntry) == false)
25730fdc8d8SChris Lattner             {
25805faeb71SGreg Clayton                 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
25930fdc8d8SChris Lattner                 StateType state = process->WaitForProcessToStop (NULL);
26030fdc8d8SChris Lattner 
26130fdc8d8SChris Lattner                 if (state == eStateStopped)
26230fdc8d8SChris Lattner                 {
26305faeb71SGreg Clayton                     error = process->Resume();
26405faeb71SGreg Clayton                     if (error.Success())
26505faeb71SGreg Clayton                     {
26630fdc8d8SChris Lattner                         if (synchronous_execution)
26730fdc8d8SChris Lattner                         {
26805faeb71SGreg Clayton                             state = process->WaitForProcessToStop (NULL);
2692637f825SGreg Clayton                             const bool must_be_alive = true;
2702637f825SGreg Clayton                             if (!StateIsStoppedState(state, must_be_alive))
271514487e8SGreg Clayton                             {
272144f3a9cSGreg Clayton                                 result.AppendErrorWithFormat ("process isn't stopped: %s", StateAsCString(state));
273514487e8SGreg Clayton                             }
27430fdc8d8SChris Lattner                             result.SetDidChangeProcessState (true);
27505faeb71SGreg Clayton                             result.SetStatus (eReturnStatusSuccessFinishResult);
27605faeb71SGreg Clayton                         }
27705faeb71SGreg Clayton                         else
27805faeb71SGreg Clayton                         {
27905faeb71SGreg Clayton                             result.SetStatus (eReturnStatusSuccessContinuingNoResult);
28005faeb71SGreg Clayton                         }
28105faeb71SGreg Clayton                     }
282514487e8SGreg Clayton                     else
283514487e8SGreg Clayton                     {
284144f3a9cSGreg Clayton                         result.AppendErrorWithFormat ("process resume at entry point failed: %s", error.AsCString());
285514487e8SGreg Clayton                         result.SetStatus (eReturnStatusFailed);
28630fdc8d8SChris Lattner                     }
28730fdc8d8SChris Lattner                 }
288514487e8SGreg Clayton                 else
289514487e8SGreg Clayton                 {
290144f3a9cSGreg Clayton                     result.AppendErrorWithFormat ("initial process state wasn't stopped: %s", StateAsCString(state));
291514487e8SGreg Clayton                     result.SetStatus (eReturnStatusFailed);
292514487e8SGreg Clayton                 }
293514487e8SGreg Clayton             }
294514487e8SGreg Clayton         }
295514487e8SGreg Clayton         else
296514487e8SGreg Clayton         {
297197bacffSGreg Clayton             result.AppendErrorWithFormat ("process launch failed: %s", error.AsCString());
298514487e8SGreg Clayton             result.SetStatus (eReturnStatusFailed);
29930fdc8d8SChris Lattner         }
30030fdc8d8SChris Lattner 
30130fdc8d8SChris Lattner         return result.Succeeded();
30230fdc8d8SChris Lattner     }
30330fdc8d8SChris Lattner 
30430fdc8d8SChris Lattner protected:
305982c9762SGreg Clayton     ProcessLaunchCommandOptions m_options;
30630fdc8d8SChris Lattner };
30730fdc8d8SChris Lattner 
30830fdc8d8SChris Lattner 
309982c9762SGreg Clayton //#define SET1 LLDB_OPT_SET_1
310982c9762SGreg Clayton //#define SET2 LLDB_OPT_SET_2
311982c9762SGreg Clayton //#define SET3 LLDB_OPT_SET_3
312982c9762SGreg Clayton //
313982c9762SGreg Clayton //OptionDefinition
314982c9762SGreg Clayton //CommandObjectProcessLaunch::CommandOptions::g_option_table[] =
315982c9762SGreg Clayton //{
316982c9762SGreg 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."},
3173154255fSSean Callanan //{ SET1              , false, "stdin",         'i', required_argument, NULL, 0, eArgTypeDirectoryName,    "Redirect stdin for the process to <path>."},
3183154255fSSean Callanan //{ SET1              , false, "stdout",        'o', required_argument, NULL, 0, eArgTypeDirectoryName,    "Redirect stdout for the process to <path>."},
3193154255fSSean Callanan //{ SET1              , false, "stderr",        'e', required_argument, NULL, 0, eArgTypeDirectoryName,    "Redirect stderr for the process to <path>."},
320982c9762SGreg Clayton //{ SET1 | SET2 | SET3, false, "plugin",        'p', required_argument, NULL, 0, eArgTypePlugin,  "Name of the process plugin you want to use."},
3213154255fSSean Callanan //{        SET2       , false, "tty",           't', optional_argument, NULL, 0, eArgTypeDirectoryName,    "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."},
322982c9762SGreg Clayton //{               SET3, false, "no-stdio",      'n', no_argument,       NULL, 0, eArgTypeNone,    "Do not set up for terminal I/O to go to running process."},
3233154255fSSean Callanan //{ SET1 | SET2 | SET3, false, "working-dir",   'w', required_argument, NULL, 0, eArgTypeDirectoryName,    "Set the current working directory to <path> when running the inferior."},
324982c9762SGreg Clayton //{ 0,                  false, NULL,             0,  0,                 NULL, 0, eArgTypeNone,    NULL }
325982c9762SGreg Clayton //};
326982c9762SGreg Clayton //
327982c9762SGreg Clayton //#undef SET1
328982c9762SGreg Clayton //#undef SET2
329982c9762SGreg Clayton //#undef SET3
33030fdc8d8SChris Lattner 
33130fdc8d8SChris Lattner //-------------------------------------------------------------------------
33230fdc8d8SChris Lattner // CommandObjectProcessAttach
33330fdc8d8SChris Lattner //-------------------------------------------------------------------------
334bb9caf73SJim Ingham #pragma mark CommandObjectProcessAttach
3355a988416SJim Ingham class CommandObjectProcessAttach : public CommandObjectParsed
33630fdc8d8SChris Lattner {
33730fdc8d8SChris Lattner public:
33830fdc8d8SChris Lattner 
33930fdc8d8SChris Lattner     class CommandOptions : public Options
34030fdc8d8SChris Lattner     {
34130fdc8d8SChris Lattner     public:
34230fdc8d8SChris Lattner 
343eb0103f2SGreg Clayton         CommandOptions (CommandInterpreter &interpreter) :
344eb0103f2SGreg Clayton             Options(interpreter)
34530fdc8d8SChris Lattner         {
346f6b8b581SGreg Clayton             // Keep default values of all options in one place: OptionParsingStarting ()
347f6b8b581SGreg Clayton             OptionParsingStarting ();
34830fdc8d8SChris Lattner         }
34930fdc8d8SChris Lattner 
35030fdc8d8SChris Lattner         ~CommandOptions ()
35130fdc8d8SChris Lattner         {
35230fdc8d8SChris Lattner         }
35330fdc8d8SChris Lattner 
35430fdc8d8SChris Lattner         Error
355f6b8b581SGreg Clayton         SetOptionValue (uint32_t option_idx, const char *option_arg)
35630fdc8d8SChris Lattner         {
35730fdc8d8SChris Lattner             Error error;
3583bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
35930fdc8d8SChris Lattner             bool success = false;
36030fdc8d8SChris Lattner             switch (short_option)
36130fdc8d8SChris Lattner             {
362a95ce623SJohnny Chen                 case 'c':
363a95ce623SJohnny Chen                     attach_info.SetContinueOnceAttached(true);
364a95ce623SJohnny Chen                     break;
365a95ce623SJohnny Chen 
36630fdc8d8SChris Lattner                 case 'p':
367144f3a9cSGreg Clayton                     {
368144f3a9cSGreg Clayton                         lldb::pid_t pid = Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success);
36930fdc8d8SChris Lattner                         if (!success || pid == LLDB_INVALID_PROCESS_ID)
37030fdc8d8SChris Lattner                         {
37186edbf41SGreg Clayton                             error.SetErrorStringWithFormat("invalid process ID '%s'", option_arg);
37230fdc8d8SChris Lattner                         }
373144f3a9cSGreg Clayton                         else
374144f3a9cSGreg Clayton                         {
375144f3a9cSGreg Clayton                             attach_info.SetProcessID (pid);
376144f3a9cSGreg Clayton                         }
377144f3a9cSGreg Clayton                     }
37830fdc8d8SChris Lattner                     break;
37930fdc8d8SChris Lattner 
38030fdc8d8SChris Lattner                 case 'P':
381144f3a9cSGreg Clayton                     attach_info.SetProcessPluginName (option_arg);
38230fdc8d8SChris Lattner                     break;
38330fdc8d8SChris Lattner 
38430fdc8d8SChris Lattner                 case 'n':
385144f3a9cSGreg Clayton                     attach_info.GetExecutableFile().SetFile(option_arg, false);
38630fdc8d8SChris Lattner                     break;
38730fdc8d8SChris Lattner 
38830fdc8d8SChris Lattner                 case 'w':
389144f3a9cSGreg Clayton                     attach_info.SetWaitForLaunch(true);
39030fdc8d8SChris Lattner                     break;
39130fdc8d8SChris Lattner 
392cd16df91SJim Ingham                 case 'i':
393cd16df91SJim Ingham                     attach_info.SetIgnoreExisting(false);
394cd16df91SJim Ingham                     break;
395cd16df91SJim Ingham 
39630fdc8d8SChris Lattner                 default:
39786edbf41SGreg Clayton                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
39830fdc8d8SChris Lattner                     break;
39930fdc8d8SChris Lattner             }
40030fdc8d8SChris Lattner             return error;
40130fdc8d8SChris Lattner         }
40230fdc8d8SChris Lattner 
40330fdc8d8SChris Lattner         void
404f6b8b581SGreg Clayton         OptionParsingStarting ()
40530fdc8d8SChris Lattner         {
406144f3a9cSGreg Clayton             attach_info.Clear();
40730fdc8d8SChris Lattner         }
40830fdc8d8SChris Lattner 
409e0d378b3SGreg Clayton         const OptionDefinition*
41030fdc8d8SChris Lattner         GetDefinitions ()
41130fdc8d8SChris Lattner         {
41230fdc8d8SChris Lattner             return g_option_table;
41330fdc8d8SChris Lattner         }
41430fdc8d8SChris Lattner 
4155aee162fSJim Ingham         virtual bool
416eb0103f2SGreg Clayton         HandleOptionArgumentCompletion (Args &input,
4175aee162fSJim Ingham                                         int cursor_index,
4185aee162fSJim Ingham                                         int char_pos,
4195aee162fSJim Ingham                                         OptionElementVector &opt_element_vector,
4205aee162fSJim Ingham                                         int opt_element_index,
4215aee162fSJim Ingham                                         int match_start_point,
4225aee162fSJim Ingham                                         int max_return_elements,
4235aee162fSJim Ingham                                         bool &word_complete,
4245aee162fSJim Ingham                                         StringList &matches)
4255aee162fSJim Ingham         {
4265aee162fSJim Ingham             int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
4275aee162fSJim Ingham             int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
4285aee162fSJim Ingham 
4295aee162fSJim Ingham             // We are only completing the name option for now...
4305aee162fSJim Ingham 
431e0d378b3SGreg Clayton             const OptionDefinition *opt_defs = GetDefinitions();
4325aee162fSJim Ingham             if (opt_defs[opt_defs_index].short_option == 'n')
4335aee162fSJim Ingham             {
4345aee162fSJim Ingham                 // Are we in the name?
4355aee162fSJim Ingham 
4365aee162fSJim Ingham                 // Look to see if there is a -P argument provided, and if so use that plugin, otherwise
4375aee162fSJim Ingham                 // use the default plugin.
4385aee162fSJim Ingham 
4395aee162fSJim Ingham                 const char *partial_name = NULL;
4405aee162fSJim Ingham                 partial_name = input.GetArgumentAtIndex(opt_arg_pos);
4415aee162fSJim Ingham 
4428b82f087SGreg Clayton                 PlatformSP platform_sp (m_interpreter.GetPlatform (true));
443e996fd30SGreg Clayton                 if (platform_sp)
4445aee162fSJim Ingham                 {
4458b82f087SGreg Clayton                     ProcessInstanceInfoList process_infos;
4468b82f087SGreg Clayton                     ProcessInstanceInfoMatch match_info;
44732e0a750SGreg Clayton                     if (partial_name)
44832e0a750SGreg Clayton                     {
449144f3a9cSGreg Clayton                         match_info.GetProcessInfo().GetExecutableFile().SetFile(partial_name, false);
45032e0a750SGreg Clayton                         match_info.SetNameMatchType(eNameMatchStartsWith);
45132e0a750SGreg Clayton                     }
45232e0a750SGreg Clayton                     platform_sp->FindProcesses (match_info, process_infos);
453c7bece56SGreg Clayton                     const size_t num_matches = process_infos.GetSize();
454e996fd30SGreg Clayton                     if (num_matches > 0)
455e996fd30SGreg Clayton                     {
456c7bece56SGreg Clayton                         for (size_t i=0; i<num_matches; ++i)
457e996fd30SGreg Clayton                         {
458e996fd30SGreg Clayton                             matches.AppendString (process_infos.GetProcessNameAtIndex(i),
459e996fd30SGreg Clayton                                                   process_infos.GetProcessNameLengthAtIndex(i));
4605aee162fSJim Ingham                         }
4615aee162fSJim Ingham                     }
4625aee162fSJim Ingham                 }
4635aee162fSJim Ingham             }
4645aee162fSJim Ingham 
4655aee162fSJim Ingham             return false;
4665aee162fSJim Ingham         }
4675aee162fSJim Ingham 
46830fdc8d8SChris Lattner         // Options table: Required for subclasses of Options.
46930fdc8d8SChris Lattner 
470e0d378b3SGreg Clayton         static OptionDefinition g_option_table[];
47130fdc8d8SChris Lattner 
47230fdc8d8SChris Lattner         // Instance variables to hold the values for command options.
47330fdc8d8SChris Lattner 
474144f3a9cSGreg Clayton         ProcessAttachInfo attach_info;
47530fdc8d8SChris Lattner     };
47630fdc8d8SChris Lattner 
477a7015092SGreg Clayton     CommandObjectProcessAttach (CommandInterpreter &interpreter) :
4785a988416SJim Ingham         CommandObjectParsed (interpreter,
479a7015092SGreg Clayton                              "process attach",
480e3d26315SCaroline Tice                              "Attach to a process.",
481eb0103f2SGreg Clayton                              "process attach <cmd-options>"),
482eb0103f2SGreg Clayton         m_options (interpreter)
4835aee162fSJim Ingham     {
4845aee162fSJim Ingham     }
4855aee162fSJim Ingham 
4865aee162fSJim Ingham     ~CommandObjectProcessAttach ()
4875aee162fSJim Ingham     {
4885aee162fSJim Ingham     }
4895aee162fSJim Ingham 
4905a988416SJim Ingham     Options *
4915a988416SJim Ingham     GetOptions ()
4925a988416SJim Ingham     {
4935a988416SJim Ingham         return &m_options;
4945a988416SJim Ingham     }
4955a988416SJim Ingham 
4965a988416SJim Ingham protected:
4975aee162fSJim Ingham     bool
4985a988416SJim Ingham     DoExecute (Args& command,
4995aee162fSJim Ingham              CommandReturnObject &result)
5005aee162fSJim Ingham     {
501a7015092SGreg Clayton         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
50231412642SJim Ingham         // N.B. The attach should be synchronous.  It doesn't help much to get the prompt back between initiating the attach
50331412642SJim Ingham         // and the target actually stopping.  So even if the interpreter is set to be asynchronous, we wait for the stop
50431412642SJim Ingham         // ourselves here.
5055aee162fSJim Ingham 
506f9fc609fSGreg Clayton         Process *process = m_exe_ctx.GetProcessPtr();
50771337622SGreg Clayton         StateType state = eStateInvalid;
5085aee162fSJim Ingham         if (process)
5095aee162fSJim Ingham         {
51071337622SGreg Clayton             state = process->GetState();
51171337622SGreg Clayton             if (process->IsAlive() && state != eStateConnected)
5125aee162fSJim Ingham             {
513d01b2953SDaniel Malea                 result.AppendErrorWithFormat ("Process %" PRIu64 " is currently being debugged, kill the process before attaching.\n",
5145aee162fSJim Ingham                                               process->GetID());
5155aee162fSJim Ingham                 result.SetStatus (eReturnStatusFailed);
5165aee162fSJim Ingham                 return false;
5175aee162fSJim Ingham             }
5185aee162fSJim Ingham         }
5195aee162fSJim Ingham 
5205aee162fSJim Ingham         if (target == NULL)
5215aee162fSJim Ingham         {
5225aee162fSJim Ingham             // If there isn't a current target create one.
5235aee162fSJim Ingham             TargetSP new_target_sp;
5245aee162fSJim Ingham             Error error;
5255aee162fSJim Ingham 
526a7015092SGreg Clayton             error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(),
527a0ca6601SGreg Clayton                                                                               NULL,
528cac9c5f9SGreg Clayton                                                                               NULL,
5295aee162fSJim Ingham                                                                               false,
530cac9c5f9SGreg Clayton                                                                               NULL, // No platform options
5315aee162fSJim Ingham                                                                               new_target_sp);
5325aee162fSJim Ingham             target = new_target_sp.get();
5335aee162fSJim Ingham             if (target == NULL || error.Fail())
5345aee162fSJim Ingham             {
535b766a73dSGreg Clayton                 result.AppendError(error.AsCString("Error creating target"));
5365aee162fSJim Ingham                 return false;
5375aee162fSJim Ingham             }
538a7015092SGreg Clayton             m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target);
5395aee162fSJim Ingham         }
5405aee162fSJim Ingham 
5415aee162fSJim Ingham         // Record the old executable module, we want to issue a warning if the process of attaching changed the
5425aee162fSJim Ingham         // current executable (like somebody said "file foo" then attached to a PID whose executable was bar.)
5435aee162fSJim Ingham 
5445aee162fSJim Ingham         ModuleSP old_exec_module_sp = target->GetExecutableModule();
5455aee162fSJim Ingham         ArchSpec old_arch_spec = target->GetArchitecture();
5465aee162fSJim Ingham 
5475aee162fSJim Ingham         if (command.GetArgumentCount())
5485aee162fSJim Ingham         {
549fd54b368SJason Molenda             result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
5505aee162fSJim Ingham             result.SetStatus (eReturnStatusFailed);
5515aee162fSJim Ingham         }
5525aee162fSJim Ingham         else
5535aee162fSJim Ingham         {
55471337622SGreg Clayton             if (state != eStateConnected)
55571337622SGreg Clayton             {
556144f3a9cSGreg Clayton                 const char *plugin_name = m_options.attach_info.GetProcessPluginName();
557c3776bf2SGreg Clayton                 process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name, NULL).get();
55871337622SGreg Clayton             }
5595aee162fSJim Ingham 
5605aee162fSJim Ingham             if (process)
5615aee162fSJim Ingham             {
5625aee162fSJim Ingham                 Error error;
563144f3a9cSGreg Clayton                 // If no process info was specified, then use the target executable
564144f3a9cSGreg Clayton                 // name as the process to attach to by default
565144f3a9cSGreg Clayton                 if (!m_options.attach_info.ProcessInfoSpecified ())
5665aee162fSJim Ingham                 {
5673a0b9cdfSJim Ingham                     if (old_exec_module_sp)
568ad9e828cSGreg Clayton                         m_options.attach_info.GetExecutableFile().GetFilename() = old_exec_module_sp->GetPlatformFileSpec().GetFilename();
569144f3a9cSGreg Clayton 
570144f3a9cSGreg Clayton                     if (!m_options.attach_info.ProcessInfoSpecified ())
5713a0b9cdfSJim Ingham                     {
572144f3a9cSGreg Clayton                         error.SetErrorString ("no process specified, create a target with a file, or specify the --pid or --name command option");
5733a0b9cdfSJim Ingham                     }
5745aee162fSJim Ingham                 }
5753a0b9cdfSJim Ingham 
576144f3a9cSGreg Clayton                 if (error.Success())
5773a0b9cdfSJim Ingham                 {
578144f3a9cSGreg Clayton                     error = process->Attach (m_options.attach_info);
5793a0b9cdfSJim Ingham 
5805aee162fSJim Ingham                     if (error.Success())
5815aee162fSJim Ingham                     {
5825aee162fSJim Ingham                         result.SetStatus (eReturnStatusSuccessContinuingNoResult);
5835aee162fSJim Ingham                     }
5845aee162fSJim Ingham                     else
5855aee162fSJim Ingham                     {
586144f3a9cSGreg Clayton                         result.AppendErrorWithFormat ("attach failed: %s\n", error.AsCString());
5875aee162fSJim Ingham                         result.SetStatus (eReturnStatusFailed);
5885aee162fSJim Ingham                         return false;
5895aee162fSJim Ingham                     }
590bb3a283bSJim Ingham                     // If we're synchronous, wait for the stopped event and report that.
591bb3a283bSJim Ingham                     // Otherwise just return.
592bb3a283bSJim Ingham                     // FIXME: in the async case it will now be possible to get to the command
593bb3a283bSJim Ingham                     // interpreter with a state eStateAttaching.  Make sure we handle that correctly.
594bb3a283bSJim Ingham                     StateType state = process->WaitForProcessToStop (NULL);
595bb3a283bSJim Ingham 
596bb3a283bSJim Ingham                     result.SetDidChangeProcessState (true);
597aa739093SJohnny Chen 
598aa739093SJohnny Chen                     if (state == eStateStopped)
599aa739093SJohnny Chen                     {
600d01b2953SDaniel Malea                         result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
601bb3a283bSJim Ingham                         result.SetStatus (eReturnStatusSuccessFinishNoResult);
602bb3a283bSJim Ingham                     }
603aa739093SJohnny Chen                     else
604aa739093SJohnny Chen                     {
605aa739093SJohnny Chen                         result.AppendError ("attach failed: process did not stop (no such process or permission problem?)");
606cfc0935eSJim Ingham                         process->Destroy();
607aa739093SJohnny Chen                         result.SetStatus (eReturnStatusFailed);
608aa739093SJohnny Chen                         return false;
609aa739093SJohnny Chen                     }
610aa739093SJohnny Chen                 }
6115aee162fSJim Ingham             }
6125aee162fSJim Ingham         }
6135aee162fSJim Ingham 
6145aee162fSJim Ingham         if (result.Succeeded())
6155aee162fSJim Ingham         {
6165aee162fSJim Ingham             // Okay, we're done.  Last step is to warn if the executable module has changed:
617513c26ceSGreg Clayton             char new_path[PATH_MAX];
618aa149cbdSGreg Clayton             ModuleSP new_exec_module_sp (target->GetExecutableModule());
6195aee162fSJim Ingham             if (!old_exec_module_sp)
6205aee162fSJim Ingham             {
621513c26ceSGreg Clayton                 // We might not have a module if we attached to a raw pid...
622aa149cbdSGreg Clayton                 if (new_exec_module_sp)
623513c26ceSGreg Clayton                 {
624aa149cbdSGreg Clayton                     new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX);
625513c26ceSGreg Clayton                     result.AppendMessageWithFormat("Executable module set to \"%s\".\n", new_path);
626513c26ceSGreg Clayton                 }
6275aee162fSJim Ingham             }
628aa149cbdSGreg Clayton             else if (old_exec_module_sp->GetFileSpec() != new_exec_module_sp->GetFileSpec())
6295aee162fSJim Ingham             {
630513c26ceSGreg Clayton                 char old_path[PATH_MAX];
6315aee162fSJim Ingham 
6325aee162fSJim Ingham                 old_exec_module_sp->GetFileSpec().GetPath (old_path, PATH_MAX);
633aa149cbdSGreg Clayton                 new_exec_module_sp->GetFileSpec().GetPath (new_path, PATH_MAX);
6345aee162fSJim Ingham 
6355aee162fSJim Ingham                 result.AppendWarningWithFormat("Executable module changed from \"%s\" to \"%s\".\n",
6365aee162fSJim Ingham                                                     old_path, new_path);
6375aee162fSJim Ingham             }
6385aee162fSJim Ingham 
6395aee162fSJim Ingham             if (!old_arch_spec.IsValid())
6405aee162fSJim Ingham             {
641c1b1f1eaSGreg Clayton                 result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().GetTriple().getTriple().c_str());
6425aee162fSJim Ingham             }
643bf4b7be6SSean Callanan             else if (!old_arch_spec.IsExactMatch(target->GetArchitecture()))
6445aee162fSJim Ingham             {
6455aee162fSJim Ingham                 result.AppendWarningWithFormat("Architecture changed from %s to %s.\n",
646c1b1f1eaSGreg Clayton                                                old_arch_spec.GetTriple().getTriple().c_str(),
647c1b1f1eaSGreg Clayton                                                target->GetArchitecture().GetTriple().getTriple().c_str());
6485aee162fSJim Ingham             }
649a95ce623SJohnny Chen 
650a95ce623SJohnny Chen             // This supports the use-case scenario of immediately continuing the process once attached.
651a95ce623SJohnny Chen             if (m_options.attach_info.GetContinueOnceAttached())
6525bcaf583SSean Callanan                 m_interpreter.HandleCommand("process continue", eLazyBoolNo, result);
6535aee162fSJim Ingham         }
6545aee162fSJim Ingham         return result.Succeeded();
6555aee162fSJim Ingham     }
6565aee162fSJim Ingham 
65730fdc8d8SChris Lattner     CommandOptions m_options;
65830fdc8d8SChris Lattner };
65930fdc8d8SChris Lattner 
66030fdc8d8SChris Lattner 
661e0d378b3SGreg Clayton OptionDefinition
66230fdc8d8SChris Lattner CommandObjectProcessAttach::CommandOptions::g_option_table[] =
66330fdc8d8SChris Lattner {
664a95ce623SJohnny Chen { LLDB_OPT_SET_ALL, false, "continue",'c', no_argument,         NULL, 0, eArgTypeNone,         "Immediately continue the process once attached."},
665deaab222SCaroline Tice { LLDB_OPT_SET_ALL, false, "plugin",  'P', required_argument,   NULL, 0, eArgTypePlugin,       "Name of the process plugin you want to use."},
666deaab222SCaroline Tice { LLDB_OPT_SET_1,   false, "pid",     'p', required_argument,   NULL, 0, eArgTypePid,          "The process ID of an existing process to attach to."},
667deaab222SCaroline Tice { LLDB_OPT_SET_2,   false, "name",    'n', required_argument,   NULL, 0, eArgTypeProcessName,  "The name of the process to attach to."},
668cd16df91SJim Ingham { LLDB_OPT_SET_2,   false, "include-existing", 'i', no_argument, NULL, 0, eArgTypeNone,         "Include existing processes when doing attach -w."},
6694ce37abbSJohnny Chen { LLDB_OPT_SET_2,   false, "waitfor", 'w', no_argument,         NULL, 0, eArgTypeNone,         "Wait for the process with <process-name> to launch."},
670deaab222SCaroline Tice { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
67130fdc8d8SChris Lattner };
67230fdc8d8SChris Lattner 
67330fdc8d8SChris Lattner //-------------------------------------------------------------------------
67430fdc8d8SChris Lattner // CommandObjectProcessContinue
67530fdc8d8SChris Lattner //-------------------------------------------------------------------------
676bb9caf73SJim Ingham #pragma mark CommandObjectProcessContinue
67730fdc8d8SChris Lattner 
6785a988416SJim Ingham class CommandObjectProcessContinue : public CommandObjectParsed
67930fdc8d8SChris Lattner {
68030fdc8d8SChris Lattner public:
68130fdc8d8SChris Lattner 
682a7015092SGreg Clayton     CommandObjectProcessContinue (CommandInterpreter &interpreter) :
6835a988416SJim Ingham         CommandObjectParsed (interpreter,
684a7015092SGreg Clayton                              "process continue",
685e3d26315SCaroline Tice                              "Continue execution of all threads in the current process.",
68630fdc8d8SChris Lattner                              "process continue",
687f9fc609fSGreg Clayton                              eFlagRequiresProcess       |
688f9fc609fSGreg Clayton                              eFlagTryTargetAPILock      |
689f9fc609fSGreg Clayton                              eFlagProcessMustBeLaunched |
690f9fc609fSGreg Clayton                              eFlagProcessMustBePaused   ),
6910e41084aSJim Ingham         m_options(interpreter)
69230fdc8d8SChris Lattner     {
69330fdc8d8SChris Lattner     }
69430fdc8d8SChris Lattner 
69530fdc8d8SChris Lattner 
69630fdc8d8SChris Lattner     ~CommandObjectProcessContinue ()
69730fdc8d8SChris Lattner     {
69830fdc8d8SChris Lattner     }
69930fdc8d8SChris Lattner 
7005a988416SJim Ingham protected:
7010e41084aSJim Ingham 
7020e41084aSJim Ingham     class CommandOptions : public Options
7030e41084aSJim Ingham     {
7040e41084aSJim Ingham     public:
7050e41084aSJim Ingham 
7060e41084aSJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
7070e41084aSJim Ingham             Options(interpreter)
7080e41084aSJim Ingham         {
7090e41084aSJim Ingham             // Keep default values of all options in one place: OptionParsingStarting ()
7100e41084aSJim Ingham             OptionParsingStarting ();
7110e41084aSJim Ingham         }
7120e41084aSJim Ingham 
7130e41084aSJim Ingham         ~CommandOptions ()
7140e41084aSJim Ingham         {
7150e41084aSJim Ingham         }
7160e41084aSJim Ingham 
7170e41084aSJim Ingham         Error
7180e41084aSJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
7190e41084aSJim Ingham         {
7200e41084aSJim Ingham             Error error;
7213bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
7220e41084aSJim Ingham             bool success = false;
7230e41084aSJim Ingham             switch (short_option)
7240e41084aSJim Ingham             {
7250e41084aSJim Ingham                 case 'i':
7260e41084aSJim Ingham                     m_ignore = Args::StringToUInt32 (option_arg, 0, 0, &success);
7270e41084aSJim Ingham                     if (!success)
7280e41084aSJim Ingham                         error.SetErrorStringWithFormat ("invalid value for ignore option: \"%s\", should be a number.", option_arg);
7290e41084aSJim Ingham                     break;
7300e41084aSJim Ingham 
7310e41084aSJim Ingham                 default:
7320e41084aSJim Ingham                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
7330e41084aSJim Ingham                     break;
7340e41084aSJim Ingham             }
7350e41084aSJim Ingham             return error;
7360e41084aSJim Ingham         }
7370e41084aSJim Ingham 
7380e41084aSJim Ingham         void
7390e41084aSJim Ingham         OptionParsingStarting ()
7400e41084aSJim Ingham         {
7410e41084aSJim Ingham             m_ignore = 0;
7420e41084aSJim Ingham         }
7430e41084aSJim Ingham 
7440e41084aSJim Ingham         const OptionDefinition*
7450e41084aSJim Ingham         GetDefinitions ()
7460e41084aSJim Ingham         {
7470e41084aSJim Ingham             return g_option_table;
7480e41084aSJim Ingham         }
7490e41084aSJim Ingham 
7500e41084aSJim Ingham         // Options table: Required for subclasses of Options.
7510e41084aSJim Ingham 
7520e41084aSJim Ingham         static OptionDefinition g_option_table[];
7530e41084aSJim Ingham 
7540e41084aSJim Ingham         uint32_t m_ignore;
7550e41084aSJim Ingham     };
7560e41084aSJim Ingham 
75730fdc8d8SChris Lattner     bool
758f9fc609fSGreg Clayton     DoExecute (Args& command, CommandReturnObject &result)
75930fdc8d8SChris Lattner     {
760f9fc609fSGreg Clayton         Process *process = m_exe_ctx.GetProcessPtr();
761a7015092SGreg Clayton         bool synchronous_execution = m_interpreter.GetSynchronous ();
76230fdc8d8SChris Lattner         StateType state = process->GetState();
76330fdc8d8SChris Lattner         if (state == eStateStopped)
76430fdc8d8SChris Lattner         {
76530fdc8d8SChris Lattner             if (command.GetArgumentCount() != 0)
76630fdc8d8SChris Lattner             {
76730fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("The '%s' command does not take any arguments.\n", m_cmd_name.c_str());
76830fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
76930fdc8d8SChris Lattner                 return false;
77030fdc8d8SChris Lattner             }
77130fdc8d8SChris Lattner 
7720e41084aSJim Ingham             if (m_options.m_ignore > 0)
7730e41084aSJim Ingham             {
7740e41084aSJim Ingham                 ThreadSP sel_thread_sp(process->GetThreadList().GetSelectedThread());
7750e41084aSJim Ingham                 if (sel_thread_sp)
7760e41084aSJim Ingham                 {
7770e41084aSJim Ingham                     StopInfoSP stop_info_sp = sel_thread_sp->GetStopInfo();
7780e41084aSJim Ingham                     if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonBreakpoint)
7790e41084aSJim Ingham                     {
780c7bece56SGreg Clayton                         lldb::break_id_t bp_site_id = (lldb::break_id_t)stop_info_sp->GetValue();
7810e41084aSJim Ingham                         BreakpointSiteSP bp_site_sp(process->GetBreakpointSiteList().FindByID(bp_site_id));
7820e41084aSJim Ingham                         if (bp_site_sp)
7830e41084aSJim Ingham                         {
784c7bece56SGreg Clayton                             const size_t num_owners = bp_site_sp->GetNumberOfOwners();
785c7bece56SGreg Clayton                             for (size_t i = 0; i < num_owners; i++)
7860e41084aSJim Ingham                             {
7870e41084aSJim Ingham                                 Breakpoint &bp_ref = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
7880e41084aSJim Ingham                                 if (!bp_ref.IsInternal())
7890e41084aSJim Ingham                                 {
7900e41084aSJim Ingham                                     bp_ref.SetIgnoreCount(m_options.m_ignore);
7910e41084aSJim Ingham                                 }
7920e41084aSJim Ingham                             }
7930e41084aSJim Ingham                         }
7940e41084aSJim Ingham                     }
7950e41084aSJim Ingham                 }
7960e41084aSJim Ingham             }
7970e41084aSJim Ingham 
79841f2b940SJim Ingham             {  // Scope for thread list mutex:
79941f2b940SJim Ingham                 Mutex::Locker locker (process->GetThreadList().GetMutex());
80030fdc8d8SChris Lattner                 const uint32_t num_threads = process->GetThreadList().GetSize();
80130fdc8d8SChris Lattner 
80230fdc8d8SChris Lattner                 // Set the actions that the threads should each take when resuming
80330fdc8d8SChris Lattner                 for (uint32_t idx=0; idx<num_threads; ++idx)
80430fdc8d8SChris Lattner                 {
80530fdc8d8SChris Lattner                     process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState (eStateRunning);
80630fdc8d8SChris Lattner                 }
80741f2b940SJim Ingham             }
80830fdc8d8SChris Lattner 
80930fdc8d8SChris Lattner             Error error(process->Resume());
81030fdc8d8SChris Lattner             if (error.Success())
81130fdc8d8SChris Lattner             {
812d01b2953SDaniel Malea                 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
81330fdc8d8SChris Lattner                 if (synchronous_execution)
81430fdc8d8SChris Lattner                 {
815b132097bSGreg Clayton                     state = process->WaitForProcessToStop (NULL);
81630fdc8d8SChris Lattner 
81730fdc8d8SChris Lattner                     result.SetDidChangeProcessState (true);
818d01b2953SDaniel Malea                     result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
81930fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
82030fdc8d8SChris Lattner                 }
82130fdc8d8SChris Lattner                 else
82230fdc8d8SChris Lattner                 {
82330fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusSuccessContinuingNoResult);
82430fdc8d8SChris Lattner                 }
82530fdc8d8SChris Lattner             }
82630fdc8d8SChris Lattner             else
82730fdc8d8SChris Lattner             {
82830fdc8d8SChris Lattner                 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
82930fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
83030fdc8d8SChris Lattner             }
83130fdc8d8SChris Lattner         }
83230fdc8d8SChris Lattner         else
83330fdc8d8SChris Lattner         {
83430fdc8d8SChris Lattner             result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
83530fdc8d8SChris Lattner                                          StateAsCString(state));
83630fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
83730fdc8d8SChris Lattner         }
83830fdc8d8SChris Lattner         return result.Succeeded();
83930fdc8d8SChris Lattner     }
8400e41084aSJim Ingham 
8410e41084aSJim Ingham     Options *
8420e41084aSJim Ingham     GetOptions ()
8430e41084aSJim Ingham     {
8440e41084aSJim Ingham         return &m_options;
8450e41084aSJim Ingham     }
8460e41084aSJim Ingham 
8470e41084aSJim Ingham     CommandOptions m_options;
8480e41084aSJim Ingham 
8490e41084aSJim Ingham };
8500e41084aSJim Ingham 
8510e41084aSJim Ingham OptionDefinition
8520e41084aSJim Ingham CommandObjectProcessContinue::CommandOptions::g_option_table[] =
8530e41084aSJim Ingham {
8540e41084aSJim Ingham { LLDB_OPT_SET_ALL, false, "ignore-count",'i', required_argument,         NULL, 0, eArgTypeUnsignedInteger,
8550e41084aSJim Ingham                            "Ignore <N> crossings of the breakpoint (if it exists) for the currently selected thread."},
8560e41084aSJim Ingham { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
85730fdc8d8SChris Lattner };
85830fdc8d8SChris Lattner 
85930fdc8d8SChris Lattner //-------------------------------------------------------------------------
86030fdc8d8SChris Lattner // CommandObjectProcessDetach
86130fdc8d8SChris Lattner //-------------------------------------------------------------------------
862bb9caf73SJim Ingham #pragma mark CommandObjectProcessDetach
86330fdc8d8SChris Lattner 
8645a988416SJim Ingham class CommandObjectProcessDetach : public CommandObjectParsed
86530fdc8d8SChris Lattner {
86630fdc8d8SChris Lattner public:
86730fdc8d8SChris Lattner 
868a7015092SGreg Clayton     CommandObjectProcessDetach (CommandInterpreter &interpreter) :
8695a988416SJim Ingham         CommandObjectParsed (interpreter,
870a7015092SGreg Clayton                              "process detach",
871e3d26315SCaroline Tice                              "Detach from the current process being debugged.",
87230fdc8d8SChris Lattner                              "process detach",
873f9fc609fSGreg Clayton                              eFlagRequiresProcess      |
874f9fc609fSGreg Clayton                              eFlagTryTargetAPILock     |
87530fdc8d8SChris Lattner                              eFlagProcessMustBeLaunched)
87630fdc8d8SChris Lattner     {
87730fdc8d8SChris Lattner     }
87830fdc8d8SChris Lattner 
87930fdc8d8SChris Lattner     ~CommandObjectProcessDetach ()
88030fdc8d8SChris Lattner     {
88130fdc8d8SChris Lattner     }
88230fdc8d8SChris Lattner 
8835a988416SJim Ingham protected:
88430fdc8d8SChris Lattner     bool
885f9fc609fSGreg Clayton     DoExecute (Args& command, CommandReturnObject &result)
88630fdc8d8SChris Lattner     {
887f9fc609fSGreg Clayton         Process *process = m_exe_ctx.GetProcessPtr();
888d01b2953SDaniel Malea         result.AppendMessageWithFormat ("Detaching from process %" PRIu64 "\n", process->GetID());
88930fdc8d8SChris Lattner         Error error (process->Detach());
89030fdc8d8SChris Lattner         if (error.Success())
89130fdc8d8SChris Lattner         {
89230fdc8d8SChris Lattner             result.SetStatus (eReturnStatusSuccessFinishResult);
89330fdc8d8SChris Lattner         }
89430fdc8d8SChris Lattner         else
89530fdc8d8SChris Lattner         {
89630fdc8d8SChris Lattner             result.AppendErrorWithFormat ("Detach failed: %s\n", error.AsCString());
89730fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
89830fdc8d8SChris Lattner             return false;
89930fdc8d8SChris Lattner         }
90030fdc8d8SChris Lattner         return result.Succeeded();
90130fdc8d8SChris Lattner     }
90230fdc8d8SChris Lattner };
90330fdc8d8SChris Lattner 
90430fdc8d8SChris Lattner //-------------------------------------------------------------------------
905b766a73dSGreg Clayton // CommandObjectProcessConnect
906b766a73dSGreg Clayton //-------------------------------------------------------------------------
907b766a73dSGreg Clayton #pragma mark CommandObjectProcessConnect
908b766a73dSGreg Clayton 
9095a988416SJim Ingham class CommandObjectProcessConnect : public CommandObjectParsed
910b766a73dSGreg Clayton {
911b766a73dSGreg Clayton public:
912b766a73dSGreg Clayton 
913b766a73dSGreg Clayton     class CommandOptions : public Options
914b766a73dSGreg Clayton     {
915b766a73dSGreg Clayton     public:
916b766a73dSGreg Clayton 
917eb0103f2SGreg Clayton         CommandOptions (CommandInterpreter &interpreter) :
918eb0103f2SGreg Clayton             Options(interpreter)
919b766a73dSGreg Clayton         {
920f6b8b581SGreg Clayton             // Keep default values of all options in one place: OptionParsingStarting ()
921f6b8b581SGreg Clayton             OptionParsingStarting ();
922b766a73dSGreg Clayton         }
923b766a73dSGreg Clayton 
924b766a73dSGreg Clayton         ~CommandOptions ()
925b766a73dSGreg Clayton         {
926b766a73dSGreg Clayton         }
927b766a73dSGreg Clayton 
928b766a73dSGreg Clayton         Error
929f6b8b581SGreg Clayton         SetOptionValue (uint32_t option_idx, const char *option_arg)
930b766a73dSGreg Clayton         {
931b766a73dSGreg Clayton             Error error;
9323bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
933b766a73dSGreg Clayton 
934b766a73dSGreg Clayton             switch (short_option)
935b766a73dSGreg Clayton             {
936b766a73dSGreg Clayton             case 'p':
937b766a73dSGreg Clayton                 plugin_name.assign (option_arg);
938b766a73dSGreg Clayton                 break;
939b766a73dSGreg Clayton 
940b766a73dSGreg Clayton             default:
94186edbf41SGreg Clayton                 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
942b766a73dSGreg Clayton                 break;
943b766a73dSGreg Clayton             }
944b766a73dSGreg Clayton             return error;
945b766a73dSGreg Clayton         }
946b766a73dSGreg Clayton 
947b766a73dSGreg Clayton         void
948f6b8b581SGreg Clayton         OptionParsingStarting ()
949b766a73dSGreg Clayton         {
950b766a73dSGreg Clayton             plugin_name.clear();
951b766a73dSGreg Clayton         }
952b766a73dSGreg Clayton 
953e0d378b3SGreg Clayton         const OptionDefinition*
954b766a73dSGreg Clayton         GetDefinitions ()
955b766a73dSGreg Clayton         {
956b766a73dSGreg Clayton             return g_option_table;
957b766a73dSGreg Clayton         }
958b766a73dSGreg Clayton 
959b766a73dSGreg Clayton         // Options table: Required for subclasses of Options.
960b766a73dSGreg Clayton 
961e0d378b3SGreg Clayton         static OptionDefinition g_option_table[];
962b766a73dSGreg Clayton 
963b766a73dSGreg Clayton         // Instance variables to hold the values for command options.
964b766a73dSGreg Clayton 
965b766a73dSGreg Clayton         std::string plugin_name;
966b766a73dSGreg Clayton     };
967b766a73dSGreg Clayton 
968b766a73dSGreg Clayton     CommandObjectProcessConnect (CommandInterpreter &interpreter) :
9695a988416SJim Ingham         CommandObjectParsed (interpreter,
970b766a73dSGreg Clayton                              "process connect",
971b766a73dSGreg Clayton                              "Connect to a remote debug service.",
972b766a73dSGreg Clayton                              "process connect <remote-url>",
973eb0103f2SGreg Clayton                              0),
974eb0103f2SGreg Clayton         m_options (interpreter)
975b766a73dSGreg Clayton     {
976b766a73dSGreg Clayton     }
977b766a73dSGreg Clayton 
978b766a73dSGreg Clayton     ~CommandObjectProcessConnect ()
979b766a73dSGreg Clayton     {
980b766a73dSGreg Clayton     }
981b766a73dSGreg Clayton 
982b766a73dSGreg Clayton 
9835a988416SJim Ingham     Options *
9845a988416SJim Ingham     GetOptions ()
9855a988416SJim Ingham     {
9865a988416SJim Ingham         return &m_options;
9875a988416SJim Ingham     }
9885a988416SJim Ingham 
9895a988416SJim Ingham protected:
990b766a73dSGreg Clayton     bool
9915a988416SJim Ingham     DoExecute (Args& command,
992b766a73dSGreg Clayton              CommandReturnObject &result)
993b766a73dSGreg Clayton     {
994b766a73dSGreg Clayton 
995b766a73dSGreg Clayton         TargetSP target_sp (m_interpreter.GetDebugger().GetSelectedTarget());
996b766a73dSGreg Clayton         Error error;
997f9fc609fSGreg Clayton         Process *process = m_exe_ctx.GetProcessPtr();
998b766a73dSGreg Clayton         if (process)
999b766a73dSGreg Clayton         {
1000b766a73dSGreg Clayton             if (process->IsAlive())
1001b766a73dSGreg Clayton             {
1002d01b2953SDaniel Malea                 result.AppendErrorWithFormat ("Process %" PRIu64 " is currently being debugged, kill the process before connecting.\n",
1003b766a73dSGreg Clayton                                               process->GetID());
1004b766a73dSGreg Clayton                 result.SetStatus (eReturnStatusFailed);
1005b766a73dSGreg Clayton                 return false;
1006b766a73dSGreg Clayton             }
1007b766a73dSGreg Clayton         }
1008b766a73dSGreg Clayton 
1009b766a73dSGreg Clayton         if (!target_sp)
1010b766a73dSGreg Clayton         {
1011b766a73dSGreg Clayton             // If there isn't a current target create one.
1012b766a73dSGreg Clayton 
1013b766a73dSGreg Clayton             error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(),
1014a0ca6601SGreg Clayton                                                                               NULL,
1015cac9c5f9SGreg Clayton                                                                               NULL,
1016b766a73dSGreg Clayton                                                                               false,
1017cac9c5f9SGreg Clayton                                                                               NULL, // No platform options
1018b766a73dSGreg Clayton                                                                               target_sp);
1019b766a73dSGreg Clayton             if (!target_sp || error.Fail())
1020b766a73dSGreg Clayton             {
1021b766a73dSGreg Clayton                 result.AppendError(error.AsCString("Error creating target"));
1022b766a73dSGreg Clayton                 result.SetStatus (eReturnStatusFailed);
1023b766a73dSGreg Clayton                 return false;
1024b766a73dSGreg Clayton             }
1025b766a73dSGreg Clayton             m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target_sp.get());
1026b766a73dSGreg Clayton         }
1027b766a73dSGreg Clayton 
1028b766a73dSGreg Clayton         if (command.GetArgumentCount() == 1)
1029b766a73dSGreg Clayton         {
1030b766a73dSGreg Clayton             const char *plugin_name = NULL;
1031b766a73dSGreg Clayton             if (!m_options.plugin_name.empty())
1032b766a73dSGreg Clayton                 plugin_name = m_options.plugin_name.c_str();
1033b766a73dSGreg Clayton 
1034b766a73dSGreg Clayton             const char *remote_url = command.GetArgumentAtIndex(0);
1035c3776bf2SGreg Clayton             process = target_sp->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name, NULL).get();
1036b766a73dSGreg Clayton 
1037b766a73dSGreg Clayton             if (process)
1038b766a73dSGreg Clayton             {
10394bd4e7e3SJason Molenda                 error = process->ConnectRemote (&process->GetTarget().GetDebugger().GetOutputStream(), remote_url);
1040b766a73dSGreg Clayton 
1041b766a73dSGreg Clayton                 if (error.Fail())
1042b766a73dSGreg Clayton                 {
1043b766a73dSGreg Clayton                     result.AppendError(error.AsCString("Remote connect failed"));
1044b766a73dSGreg Clayton                     result.SetStatus (eReturnStatusFailed);
10451517dd33SGreg Clayton                     target_sp->DeleteCurrentProcess();
1046b766a73dSGreg Clayton                     return false;
1047b766a73dSGreg Clayton                 }
1048b766a73dSGreg Clayton             }
1049b766a73dSGreg Clayton             else
1050b766a73dSGreg Clayton             {
1051fd54b368SJason 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",
1052f00b7511SDaniel Malea                                               remote_url);
1053b766a73dSGreg Clayton                 result.SetStatus (eReturnStatusFailed);
1054b766a73dSGreg Clayton             }
1055b766a73dSGreg Clayton         }
1056b766a73dSGreg Clayton         else
1057b766a73dSGreg Clayton         {
1058fd54b368SJason Molenda             result.AppendErrorWithFormat ("'%s' takes exactly one argument:\nUsage: %s\n",
1059b766a73dSGreg Clayton                                           m_cmd_name.c_str(),
1060b766a73dSGreg Clayton                                           m_cmd_syntax.c_str());
1061b766a73dSGreg Clayton             result.SetStatus (eReturnStatusFailed);
1062b766a73dSGreg Clayton         }
1063b766a73dSGreg Clayton         return result.Succeeded();
1064b766a73dSGreg Clayton     }
1065b766a73dSGreg Clayton 
1066b766a73dSGreg Clayton     CommandOptions m_options;
1067b766a73dSGreg Clayton };
1068b766a73dSGreg Clayton 
1069e0d378b3SGreg Clayton OptionDefinition
1070b766a73dSGreg Clayton CommandObjectProcessConnect::CommandOptions::g_option_table[] =
1071b766a73dSGreg Clayton {
1072b766a73dSGreg Clayton     { LLDB_OPT_SET_ALL, false, "plugin", 'p', required_argument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."},
1073b766a73dSGreg Clayton     { 0,                false, NULL,      0 , 0,                 NULL, 0, eArgTypeNone,   NULL }
1074b766a73dSGreg Clayton };
1075b766a73dSGreg Clayton 
1076b766a73dSGreg Clayton //-------------------------------------------------------------------------
1077998255bfSGreg Clayton // CommandObjectProcessPlugin
1078998255bfSGreg Clayton //-------------------------------------------------------------------------
1079998255bfSGreg Clayton #pragma mark CommandObjectProcessPlugin
1080998255bfSGreg Clayton 
1081998255bfSGreg Clayton class CommandObjectProcessPlugin : public CommandObjectProxy
1082998255bfSGreg Clayton {
1083998255bfSGreg Clayton public:
1084998255bfSGreg Clayton 
1085998255bfSGreg Clayton     CommandObjectProcessPlugin (CommandInterpreter &interpreter) :
1086998255bfSGreg Clayton         CommandObjectProxy (interpreter,
1087998255bfSGreg Clayton                             "process plugin",
1088998255bfSGreg Clayton                             "Send a custom command to the current process plug-in.",
1089998255bfSGreg Clayton                             "process plugin <args>",
1090998255bfSGreg Clayton                             0)
1091998255bfSGreg Clayton     {
1092998255bfSGreg Clayton     }
1093998255bfSGreg Clayton 
1094998255bfSGreg Clayton     ~CommandObjectProcessPlugin ()
1095998255bfSGreg Clayton     {
1096998255bfSGreg Clayton     }
1097998255bfSGreg Clayton 
1098998255bfSGreg Clayton     virtual CommandObject *
1099998255bfSGreg Clayton     GetProxyCommandObject()
1100998255bfSGreg Clayton     {
1101e05b2efeSGreg Clayton         Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
1102998255bfSGreg Clayton         if (process)
1103998255bfSGreg Clayton             return process->GetPluginCommandObject();
1104998255bfSGreg Clayton         return NULL;
1105998255bfSGreg Clayton     }
1106998255bfSGreg Clayton };
1107998255bfSGreg Clayton 
1108998255bfSGreg Clayton 
1109998255bfSGreg Clayton //-------------------------------------------------------------------------
11108f343b09SGreg Clayton // CommandObjectProcessLoad
11118f343b09SGreg Clayton //-------------------------------------------------------------------------
1112bb9caf73SJim Ingham #pragma mark CommandObjectProcessLoad
11138f343b09SGreg Clayton 
11145a988416SJim Ingham class CommandObjectProcessLoad : public CommandObjectParsed
11158f343b09SGreg Clayton {
11168f343b09SGreg Clayton public:
11178f343b09SGreg Clayton 
11188f343b09SGreg Clayton     CommandObjectProcessLoad (CommandInterpreter &interpreter) :
11195a988416SJim Ingham         CommandObjectParsed (interpreter,
11208f343b09SGreg Clayton                              "process load",
11218f343b09SGreg Clayton                              "Load a shared library into the current process.",
11228f343b09SGreg Clayton                              "process load <filename> [<filename> ...]",
1123f9fc609fSGreg Clayton                              eFlagRequiresProcess       |
1124f9fc609fSGreg Clayton                              eFlagTryTargetAPILock      |
1125f9fc609fSGreg Clayton                              eFlagProcessMustBeLaunched |
1126f9fc609fSGreg Clayton                              eFlagProcessMustBePaused   )
11278f343b09SGreg Clayton     {
11288f343b09SGreg Clayton     }
11298f343b09SGreg Clayton 
11308f343b09SGreg Clayton     ~CommandObjectProcessLoad ()
11318f343b09SGreg Clayton     {
11328f343b09SGreg Clayton     }
11338f343b09SGreg Clayton 
11345a988416SJim Ingham protected:
11358f343b09SGreg Clayton     bool
11365a988416SJim Ingham     DoExecute (Args& command,
11378f343b09SGreg Clayton              CommandReturnObject &result)
11388f343b09SGreg Clayton     {
1139f9fc609fSGreg Clayton         Process *process = m_exe_ctx.GetProcessPtr();
11408f343b09SGreg Clayton 
1141c7bece56SGreg Clayton         const size_t argc = command.GetArgumentCount();
11428f343b09SGreg Clayton 
11438f343b09SGreg Clayton         for (uint32_t i=0; i<argc; ++i)
11448f343b09SGreg Clayton         {
11458f343b09SGreg Clayton             Error error;
11468f343b09SGreg Clayton             const char *image_path = command.GetArgumentAtIndex(i);
11478f343b09SGreg Clayton             FileSpec image_spec (image_path, false);
1148aa516843SGreg Clayton             process->GetTarget().GetPlatform()->ResolveRemotePath(image_spec, image_spec);
11498f343b09SGreg Clayton             uint32_t image_token = process->LoadImage(image_spec, error);
11508f343b09SGreg Clayton             if (image_token != LLDB_INVALID_IMAGE_TOKEN)
11518f343b09SGreg Clayton             {
11528f343b09SGreg Clayton                 result.AppendMessageWithFormat ("Loading \"%s\"...ok\nImage %u loaded.\n", image_path, image_token);
11538f343b09SGreg Clayton                 result.SetStatus (eReturnStatusSuccessFinishResult);
11548f343b09SGreg Clayton             }
11558f343b09SGreg Clayton             else
11568f343b09SGreg Clayton             {
11578f343b09SGreg Clayton                 result.AppendErrorWithFormat ("failed to load '%s': %s", image_path, error.AsCString());
11588f343b09SGreg Clayton                 result.SetStatus (eReturnStatusFailed);
11598f343b09SGreg Clayton             }
11608f343b09SGreg Clayton         }
11618f343b09SGreg Clayton         return result.Succeeded();
11628f343b09SGreg Clayton     }
11638f343b09SGreg Clayton };
11648f343b09SGreg Clayton 
11658f343b09SGreg Clayton 
11668f343b09SGreg Clayton //-------------------------------------------------------------------------
11678f343b09SGreg Clayton // CommandObjectProcessUnload
11688f343b09SGreg Clayton //-------------------------------------------------------------------------
1169bb9caf73SJim Ingham #pragma mark CommandObjectProcessUnload
11708f343b09SGreg Clayton 
11715a988416SJim Ingham class CommandObjectProcessUnload : public CommandObjectParsed
11728f343b09SGreg Clayton {
11738f343b09SGreg Clayton public:
11748f343b09SGreg Clayton 
11758f343b09SGreg Clayton     CommandObjectProcessUnload (CommandInterpreter &interpreter) :
11765a988416SJim Ingham         CommandObjectParsed (interpreter,
11778f343b09SGreg Clayton                              "process unload",
11788f343b09SGreg Clayton                              "Unload a shared library from the current process using the index returned by a previous call to \"process load\".",
11798f343b09SGreg Clayton                              "process unload <index>",
1180f9fc609fSGreg Clayton                              eFlagRequiresProcess       |
1181f9fc609fSGreg Clayton                              eFlagTryTargetAPILock      |
1182f9fc609fSGreg Clayton                              eFlagProcessMustBeLaunched |
1183f9fc609fSGreg Clayton                              eFlagProcessMustBePaused   )
11848f343b09SGreg Clayton     {
11858f343b09SGreg Clayton     }
11868f343b09SGreg Clayton 
11878f343b09SGreg Clayton     ~CommandObjectProcessUnload ()
11888f343b09SGreg Clayton     {
11898f343b09SGreg Clayton     }
11908f343b09SGreg Clayton 
11915a988416SJim Ingham protected:
11928f343b09SGreg Clayton     bool
11935a988416SJim Ingham     DoExecute (Args& command,
11948f343b09SGreg Clayton              CommandReturnObject &result)
11958f343b09SGreg Clayton     {
1196f9fc609fSGreg Clayton         Process *process = m_exe_ctx.GetProcessPtr();
11978f343b09SGreg Clayton 
1198c7bece56SGreg Clayton         const size_t argc = command.GetArgumentCount();
11998f343b09SGreg Clayton 
12008f343b09SGreg Clayton         for (uint32_t i=0; i<argc; ++i)
12018f343b09SGreg Clayton         {
12028f343b09SGreg Clayton             const char *image_token_cstr = command.GetArgumentAtIndex(i);
12038f343b09SGreg Clayton             uint32_t image_token = Args::StringToUInt32(image_token_cstr, LLDB_INVALID_IMAGE_TOKEN, 0);
12048f343b09SGreg Clayton             if (image_token == LLDB_INVALID_IMAGE_TOKEN)
12058f343b09SGreg Clayton             {
12068f343b09SGreg Clayton                 result.AppendErrorWithFormat ("invalid image index argument '%s'", image_token_cstr);
12078f343b09SGreg Clayton                 result.SetStatus (eReturnStatusFailed);
12088f343b09SGreg Clayton                 break;
12098f343b09SGreg Clayton             }
12108f343b09SGreg Clayton             else
12118f343b09SGreg Clayton             {
12128f343b09SGreg Clayton                 Error error (process->UnloadImage(image_token));
12138f343b09SGreg Clayton                 if (error.Success())
12148f343b09SGreg Clayton                 {
12158f343b09SGreg Clayton                     result.AppendMessageWithFormat ("Unloading shared library with index %u...ok\n", image_token);
12168f343b09SGreg Clayton                     result.SetStatus (eReturnStatusSuccessFinishResult);
12178f343b09SGreg Clayton                 }
12188f343b09SGreg Clayton                 else
12198f343b09SGreg Clayton                 {
12208f343b09SGreg Clayton                     result.AppendErrorWithFormat ("failed to unload image: %s", error.AsCString());
12218f343b09SGreg Clayton                     result.SetStatus (eReturnStatusFailed);
12228f343b09SGreg Clayton                     break;
12238f343b09SGreg Clayton                 }
12248f343b09SGreg Clayton             }
12258f343b09SGreg Clayton         }
12268f343b09SGreg Clayton         return result.Succeeded();
12278f343b09SGreg Clayton     }
12288f343b09SGreg Clayton };
12298f343b09SGreg Clayton 
12308f343b09SGreg Clayton //-------------------------------------------------------------------------
123130fdc8d8SChris Lattner // CommandObjectProcessSignal
123230fdc8d8SChris Lattner //-------------------------------------------------------------------------
1233bb9caf73SJim Ingham #pragma mark CommandObjectProcessSignal
123430fdc8d8SChris Lattner 
12355a988416SJim Ingham class CommandObjectProcessSignal : public CommandObjectParsed
123630fdc8d8SChris Lattner {
123730fdc8d8SChris Lattner public:
123830fdc8d8SChris Lattner 
1239a7015092SGreg Clayton     CommandObjectProcessSignal (CommandInterpreter &interpreter) :
12405a988416SJim Ingham         CommandObjectParsed (interpreter,
1241a7015092SGreg Clayton                              "process signal",
1242e3d26315SCaroline Tice                              "Send a UNIX signal to the current process being debugged.",
1243f9fc609fSGreg Clayton                              NULL,
1244f9fc609fSGreg Clayton                              eFlagRequiresProcess | eFlagTryTargetAPILock)
124530fdc8d8SChris Lattner     {
1246405fe67fSCaroline Tice         CommandArgumentEntry arg;
1247405fe67fSCaroline Tice         CommandArgumentData signal_arg;
1248405fe67fSCaroline Tice 
1249405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
1250c0dbdfb6SCaroline Tice         signal_arg.arg_type = eArgTypeUnixSignal;
1251405fe67fSCaroline Tice         signal_arg.arg_repetition = eArgRepeatPlain;
1252405fe67fSCaroline Tice 
1253405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
1254405fe67fSCaroline Tice         arg.push_back (signal_arg);
1255405fe67fSCaroline Tice 
1256405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
1257405fe67fSCaroline Tice         m_arguments.push_back (arg);
125830fdc8d8SChris Lattner     }
125930fdc8d8SChris Lattner 
126030fdc8d8SChris Lattner     ~CommandObjectProcessSignal ()
126130fdc8d8SChris Lattner     {
126230fdc8d8SChris Lattner     }
126330fdc8d8SChris Lattner 
12645a988416SJim Ingham protected:
126530fdc8d8SChris Lattner     bool
12665a988416SJim Ingham     DoExecute (Args& command,
126730fdc8d8SChris Lattner              CommandReturnObject &result)
126830fdc8d8SChris Lattner     {
1269f9fc609fSGreg Clayton         Process *process = m_exe_ctx.GetProcessPtr();
127030fdc8d8SChris Lattner 
127130fdc8d8SChris Lattner         if (command.GetArgumentCount() == 1)
127230fdc8d8SChris Lattner         {
1273237cd906SGreg Clayton             int signo = LLDB_INVALID_SIGNAL_NUMBER;
1274237cd906SGreg Clayton 
1275237cd906SGreg Clayton             const char *signal_name = command.GetArgumentAtIndex(0);
1276237cd906SGreg Clayton             if (::isxdigit (signal_name[0]))
1277237cd906SGreg Clayton                 signo = Args::StringToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0);
1278237cd906SGreg Clayton             else
1279237cd906SGreg Clayton                 signo = process->GetUnixSignals().GetSignalNumberFromName (signal_name);
1280237cd906SGreg Clayton 
1281237cd906SGreg Clayton             if (signo == LLDB_INVALID_SIGNAL_NUMBER)
128230fdc8d8SChris Lattner             {
128330fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("Invalid signal argument '%s'.\n", command.GetArgumentAtIndex(0));
128430fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
128530fdc8d8SChris Lattner             }
128630fdc8d8SChris Lattner             else
128730fdc8d8SChris Lattner             {
128830fdc8d8SChris Lattner                 Error error (process->Signal (signo));
128930fdc8d8SChris Lattner                 if (error.Success())
129030fdc8d8SChris Lattner                 {
129130fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusSuccessFinishResult);
129230fdc8d8SChris Lattner                 }
129330fdc8d8SChris Lattner                 else
129430fdc8d8SChris Lattner                 {
129530fdc8d8SChris Lattner                     result.AppendErrorWithFormat ("Failed to send signal %i: %s\n", signo, error.AsCString());
129630fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
129730fdc8d8SChris Lattner                 }
129830fdc8d8SChris Lattner             }
129930fdc8d8SChris Lattner         }
130030fdc8d8SChris Lattner         else
130130fdc8d8SChris Lattner         {
1302fd54b368SJason Molenda             result.AppendErrorWithFormat("'%s' takes exactly one signal number argument:\nUsage: %s\n", m_cmd_name.c_str(),
130330fdc8d8SChris Lattner                                         m_cmd_syntax.c_str());
130430fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
130530fdc8d8SChris Lattner         }
130630fdc8d8SChris Lattner         return result.Succeeded();
130730fdc8d8SChris Lattner     }
130830fdc8d8SChris Lattner };
130930fdc8d8SChris Lattner 
131030fdc8d8SChris Lattner 
131130fdc8d8SChris Lattner //-------------------------------------------------------------------------
131230fdc8d8SChris Lattner // CommandObjectProcessInterrupt
131330fdc8d8SChris Lattner //-------------------------------------------------------------------------
1314bb9caf73SJim Ingham #pragma mark CommandObjectProcessInterrupt
131530fdc8d8SChris Lattner 
13165a988416SJim Ingham class CommandObjectProcessInterrupt : public CommandObjectParsed
131730fdc8d8SChris Lattner {
131830fdc8d8SChris Lattner public:
131930fdc8d8SChris Lattner 
132030fdc8d8SChris Lattner 
1321a7015092SGreg Clayton     CommandObjectProcessInterrupt (CommandInterpreter &interpreter) :
13225a988416SJim Ingham         CommandObjectParsed (interpreter,
1323a7015092SGreg Clayton                              "process interrupt",
1324e3d26315SCaroline Tice                              "Interrupt the current process being debugged.",
132530fdc8d8SChris Lattner                              "process interrupt",
1326f9fc609fSGreg Clayton                              eFlagRequiresProcess      |
1327f9fc609fSGreg Clayton                              eFlagTryTargetAPILock     |
132830fdc8d8SChris Lattner                              eFlagProcessMustBeLaunched)
132930fdc8d8SChris Lattner     {
133030fdc8d8SChris Lattner     }
133130fdc8d8SChris Lattner 
133230fdc8d8SChris Lattner     ~CommandObjectProcessInterrupt ()
133330fdc8d8SChris Lattner     {
133430fdc8d8SChris Lattner     }
133530fdc8d8SChris Lattner 
13365a988416SJim Ingham protected:
133730fdc8d8SChris Lattner     bool
13385a988416SJim Ingham     DoExecute (Args& command,
133930fdc8d8SChris Lattner              CommandReturnObject &result)
134030fdc8d8SChris Lattner     {
1341f9fc609fSGreg Clayton         Process *process = m_exe_ctx.GetProcessPtr();
134230fdc8d8SChris Lattner         if (process == NULL)
134330fdc8d8SChris Lattner         {
134430fdc8d8SChris Lattner             result.AppendError ("no process to halt");
134530fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
134630fdc8d8SChris Lattner             return false;
134730fdc8d8SChris Lattner         }
134830fdc8d8SChris Lattner 
134930fdc8d8SChris Lattner         if (command.GetArgumentCount() == 0)
135030fdc8d8SChris Lattner         {
135130fdc8d8SChris Lattner             Error error(process->Halt ());
135230fdc8d8SChris Lattner             if (error.Success())
135330fdc8d8SChris Lattner             {
135430fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusSuccessFinishResult);
135530fdc8d8SChris Lattner 
135630fdc8d8SChris Lattner                 // Maybe we should add a "SuspendThreadPlans so we
135730fdc8d8SChris Lattner                 // can halt, and keep in place all the current thread plans.
135830fdc8d8SChris Lattner                 process->GetThreadList().DiscardThreadPlans();
135930fdc8d8SChris Lattner             }
136030fdc8d8SChris Lattner             else
136130fdc8d8SChris Lattner             {
136230fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("Failed to halt process: %s\n", error.AsCString());
136330fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
136430fdc8d8SChris Lattner             }
136530fdc8d8SChris Lattner         }
136630fdc8d8SChris Lattner         else
136730fdc8d8SChris Lattner         {
1368fd54b368SJason Molenda             result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n",
136930fdc8d8SChris Lattner                                         m_cmd_name.c_str(),
137030fdc8d8SChris Lattner                                         m_cmd_syntax.c_str());
137130fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
137230fdc8d8SChris Lattner         }
137330fdc8d8SChris Lattner         return result.Succeeded();
137430fdc8d8SChris Lattner     }
137530fdc8d8SChris Lattner };
137630fdc8d8SChris Lattner 
137730fdc8d8SChris Lattner //-------------------------------------------------------------------------
137830fdc8d8SChris Lattner // CommandObjectProcessKill
137930fdc8d8SChris Lattner //-------------------------------------------------------------------------
1380bb9caf73SJim Ingham #pragma mark CommandObjectProcessKill
138130fdc8d8SChris Lattner 
13825a988416SJim Ingham class CommandObjectProcessKill : public CommandObjectParsed
138330fdc8d8SChris Lattner {
138430fdc8d8SChris Lattner public:
138530fdc8d8SChris Lattner 
1386a7015092SGreg Clayton     CommandObjectProcessKill (CommandInterpreter &interpreter) :
13875a988416SJim Ingham         CommandObjectParsed (interpreter,
1388a7015092SGreg Clayton                              "process kill",
1389e3d26315SCaroline Tice                              "Terminate the current process being debugged.",
139030fdc8d8SChris Lattner                              "process kill",
1391f9fc609fSGreg Clayton                              eFlagRequiresProcess      |
1392f9fc609fSGreg Clayton                              eFlagTryTargetAPILock     |
139330fdc8d8SChris Lattner                              eFlagProcessMustBeLaunched)
139430fdc8d8SChris Lattner     {
139530fdc8d8SChris Lattner     }
139630fdc8d8SChris Lattner 
139730fdc8d8SChris Lattner     ~CommandObjectProcessKill ()
139830fdc8d8SChris Lattner     {
139930fdc8d8SChris Lattner     }
140030fdc8d8SChris Lattner 
14015a988416SJim Ingham protected:
140230fdc8d8SChris Lattner     bool
14035a988416SJim Ingham     DoExecute (Args& command,
140430fdc8d8SChris Lattner              CommandReturnObject &result)
140530fdc8d8SChris Lattner     {
1406f9fc609fSGreg Clayton         Process *process = m_exe_ctx.GetProcessPtr();
140730fdc8d8SChris Lattner         if (process == NULL)
140830fdc8d8SChris Lattner         {
140930fdc8d8SChris Lattner             result.AppendError ("no process to kill");
141030fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
141130fdc8d8SChris Lattner             return false;
141230fdc8d8SChris Lattner         }
141330fdc8d8SChris Lattner 
141430fdc8d8SChris Lattner         if (command.GetArgumentCount() == 0)
141530fdc8d8SChris Lattner         {
141630fdc8d8SChris Lattner             Error error (process->Destroy());
141730fdc8d8SChris Lattner             if (error.Success())
141830fdc8d8SChris Lattner             {
141930fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusSuccessFinishResult);
142030fdc8d8SChris Lattner             }
142130fdc8d8SChris Lattner             else
142230fdc8d8SChris Lattner             {
142330fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString());
142430fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
142530fdc8d8SChris Lattner             }
142630fdc8d8SChris Lattner         }
142730fdc8d8SChris Lattner         else
142830fdc8d8SChris Lattner         {
1429fd54b368SJason Molenda             result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n",
143030fdc8d8SChris Lattner                                         m_cmd_name.c_str(),
143130fdc8d8SChris Lattner                                         m_cmd_syntax.c_str());
143230fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
143330fdc8d8SChris Lattner         }
143430fdc8d8SChris Lattner         return result.Succeeded();
143530fdc8d8SChris Lattner     }
143630fdc8d8SChris Lattner };
143730fdc8d8SChris Lattner 
143830fdc8d8SChris Lattner //-------------------------------------------------------------------------
14394b9bea87SJim Ingham // CommandObjectProcessStatus
14404b9bea87SJim Ingham //-------------------------------------------------------------------------
1441bb9caf73SJim Ingham #pragma mark CommandObjectProcessStatus
1442bb9caf73SJim Ingham 
14435a988416SJim Ingham class CommandObjectProcessStatus : public CommandObjectParsed
14444b9bea87SJim Ingham {
14454b9bea87SJim Ingham public:
1446a7015092SGreg Clayton     CommandObjectProcessStatus (CommandInterpreter &interpreter) :
14475a988416SJim Ingham         CommandObjectParsed (interpreter,
1448a7015092SGreg Clayton                              "process status",
1449e3d26315SCaroline Tice                              "Show the current status and location of executing process.",
1450e3d26315SCaroline Tice                              "process status",
1451f9fc609fSGreg Clayton                              eFlagRequiresProcess | eFlagTryTargetAPILock)
14524b9bea87SJim Ingham     {
14534b9bea87SJim Ingham     }
14544b9bea87SJim Ingham 
14554b9bea87SJim Ingham     ~CommandObjectProcessStatus()
14564b9bea87SJim Ingham     {
14574b9bea87SJim Ingham     }
14584b9bea87SJim Ingham 
14594b9bea87SJim Ingham 
14604b9bea87SJim Ingham     bool
14615a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
14624b9bea87SJim Ingham     {
14637260f620SGreg Clayton         Stream &strm = result.GetOutputStream();
14644b9bea87SJim Ingham         result.SetStatus (eReturnStatusSuccessFinishNoResult);
1465f9fc609fSGreg Clayton         // No need to check "process" for validity as eFlagRequiresProcess ensures it is valid
1466f9fc609fSGreg Clayton         Process *process = m_exe_ctx.GetProcessPtr();
14677260f620SGreg Clayton         const bool only_threads_with_stop_reason = true;
14687260f620SGreg Clayton         const uint32_t start_frame = 0;
14697260f620SGreg Clayton         const uint32_t num_frames = 1;
14707260f620SGreg Clayton         const uint32_t num_frames_with_source = 1;
1471c14ee32dSGreg Clayton         process->GetStatus(strm);
1472c14ee32dSGreg Clayton         process->GetThreadStatus (strm,
14737260f620SGreg Clayton                                   only_threads_with_stop_reason,
14747260f620SGreg Clayton                                   start_frame,
14757260f620SGreg Clayton                                   num_frames,
14767260f620SGreg Clayton                                   num_frames_with_source);
14774b9bea87SJim Ingham         return result.Succeeded();
14784b9bea87SJim Ingham     }
14794b9bea87SJim Ingham };
14804b9bea87SJim Ingham 
14814b9bea87SJim Ingham //-------------------------------------------------------------------------
148235731357SCaroline Tice // CommandObjectProcessHandle
148335731357SCaroline Tice //-------------------------------------------------------------------------
1484bb9caf73SJim Ingham #pragma mark CommandObjectProcessHandle
148535731357SCaroline Tice 
14865a988416SJim Ingham class CommandObjectProcessHandle : public CommandObjectParsed
148735731357SCaroline Tice {
148835731357SCaroline Tice public:
148935731357SCaroline Tice 
149035731357SCaroline Tice     class CommandOptions : public Options
149135731357SCaroline Tice     {
149235731357SCaroline Tice     public:
149335731357SCaroline Tice 
1494eb0103f2SGreg Clayton         CommandOptions (CommandInterpreter &interpreter) :
1495eb0103f2SGreg Clayton             Options (interpreter)
149635731357SCaroline Tice         {
1497f6b8b581SGreg Clayton             OptionParsingStarting ();
149835731357SCaroline Tice         }
149935731357SCaroline Tice 
150035731357SCaroline Tice         ~CommandOptions ()
150135731357SCaroline Tice         {
150235731357SCaroline Tice         }
150335731357SCaroline Tice 
150435731357SCaroline Tice         Error
1505f6b8b581SGreg Clayton         SetOptionValue (uint32_t option_idx, const char *option_arg)
150635731357SCaroline Tice         {
150735731357SCaroline Tice             Error error;
15083bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
150935731357SCaroline Tice 
151035731357SCaroline Tice             switch (short_option)
151135731357SCaroline Tice             {
151235731357SCaroline Tice                 case 's':
151335731357SCaroline Tice                     stop = option_arg;
151435731357SCaroline Tice                     break;
151535731357SCaroline Tice                 case 'n':
151635731357SCaroline Tice                     notify = option_arg;
151735731357SCaroline Tice                     break;
151835731357SCaroline Tice                 case 'p':
151935731357SCaroline Tice                     pass = option_arg;
152035731357SCaroline Tice                     break;
152135731357SCaroline Tice                 default:
152286edbf41SGreg Clayton                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
152335731357SCaroline Tice                     break;
152435731357SCaroline Tice             }
152535731357SCaroline Tice             return error;
152635731357SCaroline Tice         }
152735731357SCaroline Tice 
152835731357SCaroline Tice         void
1529f6b8b581SGreg Clayton         OptionParsingStarting ()
153035731357SCaroline Tice         {
153135731357SCaroline Tice             stop.clear();
153235731357SCaroline Tice             notify.clear();
153335731357SCaroline Tice             pass.clear();
153435731357SCaroline Tice         }
153535731357SCaroline Tice 
1536e0d378b3SGreg Clayton         const OptionDefinition*
153735731357SCaroline Tice         GetDefinitions ()
153835731357SCaroline Tice         {
153935731357SCaroline Tice             return g_option_table;
154035731357SCaroline Tice         }
154135731357SCaroline Tice 
154235731357SCaroline Tice         // Options table: Required for subclasses of Options.
154335731357SCaroline Tice 
1544e0d378b3SGreg Clayton         static OptionDefinition g_option_table[];
154535731357SCaroline Tice 
154635731357SCaroline Tice         // Instance variables to hold the values for command options.
154735731357SCaroline Tice 
154835731357SCaroline Tice         std::string stop;
154935731357SCaroline Tice         std::string notify;
155035731357SCaroline Tice         std::string pass;
155135731357SCaroline Tice     };
155235731357SCaroline Tice 
155335731357SCaroline Tice 
155435731357SCaroline Tice     CommandObjectProcessHandle (CommandInterpreter &interpreter) :
15555a988416SJim Ingham         CommandObjectParsed (interpreter,
155635731357SCaroline Tice                              "process handle",
155710ad7993SCaroline Tice                              "Show or update what the process and debugger should do with various signals received from the OS.",
1558eb0103f2SGreg Clayton                              NULL),
1559eb0103f2SGreg Clayton         m_options (interpreter)
156035731357SCaroline Tice     {
156110ad7993SCaroline Tice         SetHelpLong ("If no signals are specified, update them all.  If no update option is specified, list the current values.\n");
156235731357SCaroline Tice         CommandArgumentEntry arg;
1563c0dbdfb6SCaroline Tice         CommandArgumentData signal_arg;
156435731357SCaroline Tice 
1565c0dbdfb6SCaroline Tice         signal_arg.arg_type = eArgTypeUnixSignal;
1566c0dbdfb6SCaroline Tice         signal_arg.arg_repetition = eArgRepeatStar;
156735731357SCaroline Tice 
1568c0dbdfb6SCaroline Tice         arg.push_back (signal_arg);
156935731357SCaroline Tice 
157035731357SCaroline Tice         m_arguments.push_back (arg);
157135731357SCaroline Tice     }
157235731357SCaroline Tice 
157335731357SCaroline Tice     ~CommandObjectProcessHandle ()
157435731357SCaroline Tice     {
157535731357SCaroline Tice     }
157635731357SCaroline Tice 
157735731357SCaroline Tice     Options *
157835731357SCaroline Tice     GetOptions ()
157935731357SCaroline Tice     {
158035731357SCaroline Tice         return &m_options;
158135731357SCaroline Tice     }
158235731357SCaroline Tice 
158335731357SCaroline Tice     bool
158410ad7993SCaroline Tice     VerifyCommandOptionValue (const std::string &option, int &real_value)
158535731357SCaroline Tice     {
158635731357SCaroline Tice         bool okay = true;
158735731357SCaroline Tice 
158810ad7993SCaroline Tice         bool success = false;
158910ad7993SCaroline Tice         bool tmp_value = Args::StringToBoolean (option.c_str(), false, &success);
159010ad7993SCaroline Tice 
159110ad7993SCaroline Tice         if (success && tmp_value)
159210ad7993SCaroline Tice             real_value = 1;
159310ad7993SCaroline Tice         else if (success && !tmp_value)
159410ad7993SCaroline Tice             real_value = 0;
159535731357SCaroline Tice         else
159635731357SCaroline Tice         {
159735731357SCaroline Tice             // If the value isn't 'true' or 'false', it had better be 0 or 1.
159810ad7993SCaroline Tice             real_value = Args::StringToUInt32 (option.c_str(), 3);
159910ad7993SCaroline Tice             if (real_value != 0 && real_value != 1)
160035731357SCaroline Tice                 okay = false;
160135731357SCaroline Tice         }
160235731357SCaroline Tice 
160335731357SCaroline Tice         return okay;
160435731357SCaroline Tice     }
160535731357SCaroline Tice 
160610ad7993SCaroline Tice     void
160710ad7993SCaroline Tice     PrintSignalHeader (Stream &str)
160810ad7993SCaroline Tice     {
160910ad7993SCaroline Tice         str.Printf ("NAME        PASS   STOP   NOTIFY\n");
161010ad7993SCaroline Tice         str.Printf ("==========  =====  =====  ======\n");
161110ad7993SCaroline Tice     }
161210ad7993SCaroline Tice 
161310ad7993SCaroline Tice     void
161410ad7993SCaroline Tice     PrintSignal (Stream &str, int32_t signo, const char *sig_name, UnixSignals &signals)
161510ad7993SCaroline Tice     {
161610ad7993SCaroline Tice         bool stop;
161710ad7993SCaroline Tice         bool suppress;
161810ad7993SCaroline Tice         bool notify;
161910ad7993SCaroline Tice 
162010ad7993SCaroline Tice         str.Printf ("%-10s  ", sig_name);
162110ad7993SCaroline Tice         if (signals.GetSignalInfo (signo, suppress, stop, notify))
162210ad7993SCaroline Tice         {
162310ad7993SCaroline Tice             bool pass = !suppress;
162410ad7993SCaroline Tice             str.Printf ("%s  %s  %s",
162510ad7993SCaroline Tice                         (pass ? "true " : "false"),
162610ad7993SCaroline Tice                         (stop ? "true " : "false"),
162710ad7993SCaroline Tice                         (notify ? "true " : "false"));
162810ad7993SCaroline Tice         }
162910ad7993SCaroline Tice         str.Printf ("\n");
163010ad7993SCaroline Tice     }
163110ad7993SCaroline Tice 
163210ad7993SCaroline Tice     void
163310ad7993SCaroline Tice     PrintSignalInformation (Stream &str, Args &signal_args, int num_valid_signals, UnixSignals &signals)
163410ad7993SCaroline Tice     {
163510ad7993SCaroline Tice         PrintSignalHeader (str);
163610ad7993SCaroline Tice 
163710ad7993SCaroline Tice         if (num_valid_signals > 0)
163810ad7993SCaroline Tice         {
163910ad7993SCaroline Tice             size_t num_args = signal_args.GetArgumentCount();
164010ad7993SCaroline Tice             for (size_t i = 0; i < num_args; ++i)
164110ad7993SCaroline Tice             {
164210ad7993SCaroline Tice                 int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i));
164310ad7993SCaroline Tice                 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
164410ad7993SCaroline Tice                     PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals);
164510ad7993SCaroline Tice             }
164610ad7993SCaroline Tice         }
164710ad7993SCaroline Tice         else // Print info for ALL signals
164810ad7993SCaroline Tice         {
164910ad7993SCaroline Tice             int32_t signo = signals.GetFirstSignalNumber();
165010ad7993SCaroline Tice             while (signo != LLDB_INVALID_SIGNAL_NUMBER)
165110ad7993SCaroline Tice             {
165210ad7993SCaroline Tice                 PrintSignal (str, signo, signals.GetSignalAsCString (signo), signals);
165310ad7993SCaroline Tice                 signo = signals.GetNextSignalNumber (signo);
165410ad7993SCaroline Tice             }
165510ad7993SCaroline Tice         }
165610ad7993SCaroline Tice     }
165710ad7993SCaroline Tice 
16585a988416SJim Ingham protected:
165935731357SCaroline Tice     bool
16605a988416SJim Ingham     DoExecute (Args &signal_args, CommandReturnObject &result)
166135731357SCaroline Tice     {
166235731357SCaroline Tice         TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
166335731357SCaroline Tice 
166435731357SCaroline Tice         if (!target_sp)
166535731357SCaroline Tice         {
166635731357SCaroline Tice             result.AppendError ("No current target;"
166735731357SCaroline Tice                                 " cannot handle signals until you have a valid target and process.\n");
166835731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
166935731357SCaroline Tice             return false;
167035731357SCaroline Tice         }
167135731357SCaroline Tice 
167235731357SCaroline Tice         ProcessSP process_sp = target_sp->GetProcessSP();
167335731357SCaroline Tice 
167435731357SCaroline Tice         if (!process_sp)
167535731357SCaroline Tice         {
167635731357SCaroline Tice             result.AppendError ("No current process; cannot handle signals until you have a valid process.\n");
167735731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
167835731357SCaroline Tice             return false;
167935731357SCaroline Tice         }
168035731357SCaroline Tice 
168135731357SCaroline Tice         int stop_action = -1;   // -1 means leave the current setting alone
168235731357SCaroline Tice         int pass_action = -1;   // -1 means leave the current setting alone
168335731357SCaroline Tice         int notify_action = -1; // -1 means leave the current setting alone
168435731357SCaroline Tice 
168535731357SCaroline Tice         if (! m_options.stop.empty()
168610ad7993SCaroline Tice             && ! VerifyCommandOptionValue (m_options.stop, stop_action))
168735731357SCaroline Tice         {
168835731357SCaroline Tice             result.AppendError ("Invalid argument for command option --stop; must be true or false.\n");
168935731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
169035731357SCaroline Tice             return false;
169135731357SCaroline Tice         }
169235731357SCaroline Tice 
169335731357SCaroline Tice         if (! m_options.notify.empty()
169410ad7993SCaroline Tice             && ! VerifyCommandOptionValue (m_options.notify, notify_action))
169535731357SCaroline Tice         {
169635731357SCaroline Tice             result.AppendError ("Invalid argument for command option --notify; must be true or false.\n");
169735731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
169835731357SCaroline Tice             return false;
169935731357SCaroline Tice         }
170035731357SCaroline Tice 
170135731357SCaroline Tice         if (! m_options.pass.empty()
170210ad7993SCaroline Tice             && ! VerifyCommandOptionValue (m_options.pass, pass_action))
170335731357SCaroline Tice         {
170435731357SCaroline Tice             result.AppendError ("Invalid argument for command option --pass; must be true or false.\n");
170535731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
170635731357SCaroline Tice             return false;
170735731357SCaroline Tice         }
170835731357SCaroline Tice 
170935731357SCaroline Tice         size_t num_args = signal_args.GetArgumentCount();
171035731357SCaroline Tice         UnixSignals &signals = process_sp->GetUnixSignals();
171135731357SCaroline Tice         int num_signals_set = 0;
171235731357SCaroline Tice 
171310ad7993SCaroline Tice         if (num_args > 0)
171410ad7993SCaroline Tice         {
171535731357SCaroline Tice             for (size_t i = 0; i < num_args; ++i)
171635731357SCaroline Tice             {
171735731357SCaroline Tice                 int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i));
171835731357SCaroline Tice                 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
171935731357SCaroline Tice                 {
172010ad7993SCaroline Tice                     // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees
172135731357SCaroline Tice                     // the value is either 0 or 1.
172235731357SCaroline Tice                     if (stop_action != -1)
172335731357SCaroline Tice                         signals.SetShouldStop (signo, (bool) stop_action);
172435731357SCaroline Tice                     if (pass_action != -1)
172535731357SCaroline Tice                     {
172610ad7993SCaroline Tice                         bool suppress = ! ((bool) pass_action);
172710ad7993SCaroline Tice                         signals.SetShouldSuppress (signo, suppress);
172835731357SCaroline Tice                     }
172935731357SCaroline Tice                     if (notify_action != -1)
173035731357SCaroline Tice                         signals.SetShouldNotify (signo, (bool) notify_action);
173135731357SCaroline Tice                     ++num_signals_set;
173235731357SCaroline Tice                 }
173335731357SCaroline Tice                 else
173435731357SCaroline Tice                 {
173535731357SCaroline Tice                     result.AppendErrorWithFormat ("Invalid signal name '%s'\n", signal_args.GetArgumentAtIndex (i));
173635731357SCaroline Tice                 }
173735731357SCaroline Tice             }
173810ad7993SCaroline Tice         }
173910ad7993SCaroline Tice         else
174010ad7993SCaroline Tice         {
174110ad7993SCaroline Tice             // No signal specified, if any command options were specified, update ALL signals.
174210ad7993SCaroline Tice             if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1))
174310ad7993SCaroline Tice             {
174410ad7993SCaroline Tice                 if (m_interpreter.Confirm ("Do you really want to update all the signals?", false))
174510ad7993SCaroline Tice                 {
174610ad7993SCaroline Tice                     int32_t signo = signals.GetFirstSignalNumber();
174710ad7993SCaroline Tice                     while (signo != LLDB_INVALID_SIGNAL_NUMBER)
174810ad7993SCaroline Tice                     {
174910ad7993SCaroline Tice                         if (notify_action != -1)
175010ad7993SCaroline Tice                             signals.SetShouldNotify (signo, (bool) notify_action);
175110ad7993SCaroline Tice                         if (stop_action != -1)
175210ad7993SCaroline Tice                             signals.SetShouldStop (signo, (bool) stop_action);
175310ad7993SCaroline Tice                         if (pass_action != -1)
175410ad7993SCaroline Tice                         {
175510ad7993SCaroline Tice                             bool suppress = ! ((bool) pass_action);
175610ad7993SCaroline Tice                             signals.SetShouldSuppress (signo, suppress);
175710ad7993SCaroline Tice                         }
175810ad7993SCaroline Tice                         signo = signals.GetNextSignalNumber (signo);
175910ad7993SCaroline Tice                     }
176010ad7993SCaroline Tice                 }
176110ad7993SCaroline Tice             }
176210ad7993SCaroline Tice         }
176310ad7993SCaroline Tice 
176410ad7993SCaroline Tice         PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals);
176535731357SCaroline Tice 
176635731357SCaroline Tice         if (num_signals_set > 0)
176735731357SCaroline Tice             result.SetStatus (eReturnStatusSuccessFinishNoResult);
176835731357SCaroline Tice         else
176935731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
177035731357SCaroline Tice 
177135731357SCaroline Tice         return result.Succeeded();
177235731357SCaroline Tice     }
177335731357SCaroline Tice 
177435731357SCaroline Tice     CommandOptions m_options;
177535731357SCaroline Tice };
177635731357SCaroline Tice 
1777e0d378b3SGreg Clayton OptionDefinition
177835731357SCaroline Tice CommandObjectProcessHandle::CommandOptions::g_option_table[] =
177935731357SCaroline Tice {
178035731357SCaroline 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." },
178135731357SCaroline 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." },
178235731357SCaroline Tice { LLDB_OPT_SET_1, false, "pass",  'p', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." },
178335731357SCaroline Tice { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
178435731357SCaroline Tice };
178535731357SCaroline Tice 
178635731357SCaroline Tice //-------------------------------------------------------------------------
178730fdc8d8SChris Lattner // CommandObjectMultiwordProcess
178830fdc8d8SChris Lattner //-------------------------------------------------------------------------
178930fdc8d8SChris Lattner 
17906611103cSGreg Clayton CommandObjectMultiwordProcess::CommandObjectMultiwordProcess (CommandInterpreter &interpreter) :
1791a7015092SGreg Clayton     CommandObjectMultiword (interpreter,
1792a7015092SGreg Clayton                             "process",
179330fdc8d8SChris Lattner                             "A set of commands for operating on a process.",
179430fdc8d8SChris Lattner                             "process <subcommand> [<subcommand-options>]")
179530fdc8d8SChris Lattner {
1796a7015092SGreg Clayton     LoadSubCommand ("attach",      CommandObjectSP (new CommandObjectProcessAttach    (interpreter)));
1797a7015092SGreg Clayton     LoadSubCommand ("launch",      CommandObjectSP (new CommandObjectProcessLaunch    (interpreter)));
1798a7015092SGreg Clayton     LoadSubCommand ("continue",    CommandObjectSP (new CommandObjectProcessContinue  (interpreter)));
1799b766a73dSGreg Clayton     LoadSubCommand ("connect",     CommandObjectSP (new CommandObjectProcessConnect   (interpreter)));
1800a7015092SGreg Clayton     LoadSubCommand ("detach",      CommandObjectSP (new CommandObjectProcessDetach    (interpreter)));
18018f343b09SGreg Clayton     LoadSubCommand ("load",        CommandObjectSP (new CommandObjectProcessLoad      (interpreter)));
18028f343b09SGreg Clayton     LoadSubCommand ("unload",      CommandObjectSP (new CommandObjectProcessUnload    (interpreter)));
1803a7015092SGreg Clayton     LoadSubCommand ("signal",      CommandObjectSP (new CommandObjectProcessSignal    (interpreter)));
180435731357SCaroline Tice     LoadSubCommand ("handle",      CommandObjectSP (new CommandObjectProcessHandle    (interpreter)));
1805a7015092SGreg Clayton     LoadSubCommand ("status",      CommandObjectSP (new CommandObjectProcessStatus    (interpreter)));
1806a7015092SGreg Clayton     LoadSubCommand ("interrupt",   CommandObjectSP (new CommandObjectProcessInterrupt (interpreter)));
1807a7015092SGreg Clayton     LoadSubCommand ("kill",        CommandObjectSP (new CommandObjectProcessKill      (interpreter)));
1808998255bfSGreg Clayton     LoadSubCommand ("plugin",      CommandObjectSP (new CommandObjectProcessPlugin    (interpreter)));
180930fdc8d8SChris Lattner }
181030fdc8d8SChris Lattner 
181130fdc8d8SChris Lattner CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess ()
181230fdc8d8SChris Lattner {
181330fdc8d8SChris Lattner }
181430fdc8d8SChris Lattner 
1815