1ac7ddfbfSEd Maste //===-- CommandObjectProcess.cpp --------------------------------*- C++ -*-===//
2ac7ddfbfSEd Maste //
3ac7ddfbfSEd Maste //                     The LLVM Compiler Infrastructure
4ac7ddfbfSEd Maste //
5ac7ddfbfSEd Maste // This file is distributed under the University of Illinois Open Source
6ac7ddfbfSEd Maste // License. See LICENSE.TXT for details.
7ac7ddfbfSEd Maste //
8ac7ddfbfSEd Maste //===----------------------------------------------------------------------===//
9ac7ddfbfSEd Maste 
10ac7ddfbfSEd Maste #include "lldb/lldb-python.h"
11ac7ddfbfSEd Maste 
12ac7ddfbfSEd Maste #include "CommandObjectProcess.h"
13ac7ddfbfSEd Maste 
14ac7ddfbfSEd Maste // C Includes
15ac7ddfbfSEd Maste // C++ Includes
16ac7ddfbfSEd Maste // Other libraries and framework includes
17ac7ddfbfSEd Maste // Project includes
18ac7ddfbfSEd Maste #include "lldb/Breakpoint/Breakpoint.h"
19ac7ddfbfSEd Maste #include "lldb/Breakpoint/BreakpointLocation.h"
20ac7ddfbfSEd Maste #include "lldb/Breakpoint/BreakpointSite.h"
21ac7ddfbfSEd Maste #include "lldb/Core/State.h"
22ac7ddfbfSEd Maste #include "lldb/Core/Module.h"
230127ef0fSEd Maste #include "lldb/Core/PluginManager.h"
24ac7ddfbfSEd Maste #include "lldb/Host/Host.h"
25ac7ddfbfSEd Maste #include "lldb/Interpreter/Args.h"
26ac7ddfbfSEd Maste #include "lldb/Interpreter/Options.h"
27ac7ddfbfSEd Maste #include "lldb/Interpreter/CommandInterpreter.h"
28ac7ddfbfSEd Maste #include "lldb/Interpreter/CommandReturnObject.h"
29ac7ddfbfSEd Maste #include "lldb/Target/Platform.h"
30ac7ddfbfSEd Maste #include "lldb/Target/Process.h"
31ac7ddfbfSEd Maste #include "lldb/Target/StopInfo.h"
32ac7ddfbfSEd Maste #include "lldb/Target/Target.h"
33ac7ddfbfSEd Maste #include "lldb/Target/Thread.h"
34ac7ddfbfSEd Maste 
35ac7ddfbfSEd Maste using namespace lldb;
36ac7ddfbfSEd Maste using namespace lldb_private;
37ac7ddfbfSEd Maste 
38ac7ddfbfSEd Maste class CommandObjectProcessLaunchOrAttach : public CommandObjectParsed
39ac7ddfbfSEd Maste {
40ac7ddfbfSEd Maste public:
41ac7ddfbfSEd Maste     CommandObjectProcessLaunchOrAttach (CommandInterpreter &interpreter,
42ac7ddfbfSEd Maste                                        const char *name,
43ac7ddfbfSEd Maste                                        const char *help,
44ac7ddfbfSEd Maste                                        const char *syntax,
45ac7ddfbfSEd Maste                                        uint32_t flags,
46ac7ddfbfSEd Maste                                        const char *new_process_action) :
47ac7ddfbfSEd Maste         CommandObjectParsed (interpreter, name, help, syntax, flags),
48ac7ddfbfSEd Maste         m_new_process_action (new_process_action) {}
49ac7ddfbfSEd Maste 
50ac7ddfbfSEd Maste     virtual ~CommandObjectProcessLaunchOrAttach () {}
51ac7ddfbfSEd Maste protected:
52ac7ddfbfSEd Maste     bool
5312b93ac6SEd Maste     StopProcessIfNecessary (Process *process, StateType &state, CommandReturnObject &result)
54ac7ddfbfSEd Maste     {
55ac7ddfbfSEd Maste         state = eStateInvalid;
56ac7ddfbfSEd Maste         if (process)
57ac7ddfbfSEd Maste         {
58ac7ddfbfSEd Maste             state = process->GetState();
59ac7ddfbfSEd Maste 
60ac7ddfbfSEd Maste             if (process->IsAlive() && state != eStateConnected)
61ac7ddfbfSEd Maste             {
62ac7ddfbfSEd Maste                 char message[1024];
63ac7ddfbfSEd Maste                 if (process->GetState() == eStateAttaching)
64ac7ddfbfSEd Maste                     ::snprintf (message, sizeof(message), "There is a pending attach, abort it and %s?", m_new_process_action.c_str());
65ac7ddfbfSEd Maste                 else if (process->GetShouldDetach())
66ac7ddfbfSEd Maste                     ::snprintf (message, sizeof(message), "There is a running process, detach from it and %s?", m_new_process_action.c_str());
67ac7ddfbfSEd Maste                 else
68ac7ddfbfSEd Maste                     ::snprintf (message, sizeof(message), "There is a running process, kill it and %s?", m_new_process_action.c_str());
69ac7ddfbfSEd Maste 
70ac7ddfbfSEd Maste                 if (!m_interpreter.Confirm (message, true))
71ac7ddfbfSEd Maste                 {
72ac7ddfbfSEd Maste                     result.SetStatus (eReturnStatusFailed);
73ac7ddfbfSEd Maste                     return false;
74ac7ddfbfSEd Maste                 }
75ac7ddfbfSEd Maste                 else
76ac7ddfbfSEd Maste                 {
77ac7ddfbfSEd Maste                     if (process->GetShouldDetach())
78ac7ddfbfSEd Maste                     {
79ac7ddfbfSEd Maste                         bool keep_stopped = false;
80ac7ddfbfSEd Maste                         Error detach_error (process->Detach(keep_stopped));
81ac7ddfbfSEd Maste                         if (detach_error.Success())
82ac7ddfbfSEd Maste                         {
83ac7ddfbfSEd Maste                             result.SetStatus (eReturnStatusSuccessFinishResult);
84ac7ddfbfSEd Maste                             process = NULL;
85ac7ddfbfSEd Maste                         }
86ac7ddfbfSEd Maste                         else
87ac7ddfbfSEd Maste                         {
88ac7ddfbfSEd Maste                             result.AppendErrorWithFormat ("Failed to detach from process: %s\n", detach_error.AsCString());
89ac7ddfbfSEd Maste                             result.SetStatus (eReturnStatusFailed);
90ac7ddfbfSEd Maste                         }
91ac7ddfbfSEd Maste                     }
92ac7ddfbfSEd Maste                     else
93ac7ddfbfSEd Maste                     {
94ac7ddfbfSEd Maste                         Error destroy_error (process->Destroy());
95ac7ddfbfSEd Maste                         if (destroy_error.Success())
96ac7ddfbfSEd Maste                         {
97ac7ddfbfSEd Maste                             result.SetStatus (eReturnStatusSuccessFinishResult);
98ac7ddfbfSEd Maste                             process = NULL;
99ac7ddfbfSEd Maste                         }
100ac7ddfbfSEd Maste                         else
101ac7ddfbfSEd Maste                         {
102ac7ddfbfSEd Maste                             result.AppendErrorWithFormat ("Failed to kill process: %s\n", destroy_error.AsCString());
103ac7ddfbfSEd Maste                             result.SetStatus (eReturnStatusFailed);
104ac7ddfbfSEd Maste                         }
105ac7ddfbfSEd Maste                     }
106ac7ddfbfSEd Maste                 }
107ac7ddfbfSEd Maste             }
108ac7ddfbfSEd Maste         }
109ac7ddfbfSEd Maste         return result.Succeeded();
110ac7ddfbfSEd Maste     }
111ac7ddfbfSEd Maste     std::string m_new_process_action;
112ac7ddfbfSEd Maste };
113ac7ddfbfSEd Maste //-------------------------------------------------------------------------
114ac7ddfbfSEd Maste // CommandObjectProcessLaunch
115ac7ddfbfSEd Maste //-------------------------------------------------------------------------
116ac7ddfbfSEd Maste #pragma mark CommandObjectProcessLaunch
117ac7ddfbfSEd Maste class CommandObjectProcessLaunch : public CommandObjectProcessLaunchOrAttach
118ac7ddfbfSEd Maste {
119ac7ddfbfSEd Maste public:
120ac7ddfbfSEd Maste 
121ac7ddfbfSEd Maste     CommandObjectProcessLaunch (CommandInterpreter &interpreter) :
122ac7ddfbfSEd Maste         CommandObjectProcessLaunchOrAttach (interpreter,
123ac7ddfbfSEd Maste                                             "process launch",
124ac7ddfbfSEd Maste                                             "Launch the executable in the debugger.",
125ac7ddfbfSEd Maste                                             NULL,
126ac7ddfbfSEd Maste                                             eFlagRequiresTarget,
127ac7ddfbfSEd Maste                                             "restart"),
128ac7ddfbfSEd Maste         m_options (interpreter)
129ac7ddfbfSEd Maste     {
130ac7ddfbfSEd Maste         CommandArgumentEntry arg;
131ac7ddfbfSEd Maste         CommandArgumentData run_args_arg;
132ac7ddfbfSEd Maste 
133ac7ddfbfSEd Maste         // Define the first (and only) variant of this arg.
134ac7ddfbfSEd Maste         run_args_arg.arg_type = eArgTypeRunArgs;
135ac7ddfbfSEd Maste         run_args_arg.arg_repetition = eArgRepeatOptional;
136ac7ddfbfSEd Maste 
137ac7ddfbfSEd Maste         // There is only one variant this argument could be; put it into the argument entry.
138ac7ddfbfSEd Maste         arg.push_back (run_args_arg);
139ac7ddfbfSEd Maste 
140ac7ddfbfSEd Maste         // Push the data for the first argument into the m_arguments vector.
141ac7ddfbfSEd Maste         m_arguments.push_back (arg);
142ac7ddfbfSEd Maste     }
143ac7ddfbfSEd Maste 
144ac7ddfbfSEd Maste 
145ac7ddfbfSEd Maste     ~CommandObjectProcessLaunch ()
146ac7ddfbfSEd Maste     {
147ac7ddfbfSEd Maste     }
148ac7ddfbfSEd Maste 
149ac7ddfbfSEd Maste     virtual int
150ac7ddfbfSEd Maste     HandleArgumentCompletion (Args &input,
151ac7ddfbfSEd Maste                               int &cursor_index,
152ac7ddfbfSEd Maste                               int &cursor_char_position,
153ac7ddfbfSEd Maste                               OptionElementVector &opt_element_vector,
154ac7ddfbfSEd Maste                               int match_start_point,
155ac7ddfbfSEd Maste                               int max_return_elements,
156ac7ddfbfSEd Maste                               bool &word_complete,
157ac7ddfbfSEd Maste                               StringList &matches)
158ac7ddfbfSEd Maste     {
159ac7ddfbfSEd Maste         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
160ac7ddfbfSEd Maste         completion_str.erase (cursor_char_position);
161ac7ddfbfSEd Maste 
162ac7ddfbfSEd Maste         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
163ac7ddfbfSEd Maste                                                              CommandCompletions::eDiskFileCompletion,
164ac7ddfbfSEd Maste                                                              completion_str.c_str(),
165ac7ddfbfSEd Maste                                                              match_start_point,
166ac7ddfbfSEd Maste                                                              max_return_elements,
167ac7ddfbfSEd Maste                                                              NULL,
168ac7ddfbfSEd Maste                                                              word_complete,
169ac7ddfbfSEd Maste                                                              matches);
170ac7ddfbfSEd Maste         return matches.GetSize();
171ac7ddfbfSEd Maste     }
172ac7ddfbfSEd Maste 
173ac7ddfbfSEd Maste     Options *
174ac7ddfbfSEd Maste     GetOptions ()
175ac7ddfbfSEd Maste     {
176ac7ddfbfSEd Maste         return &m_options;
177ac7ddfbfSEd Maste     }
178ac7ddfbfSEd Maste 
179ac7ddfbfSEd Maste     virtual const char *GetRepeatCommand (Args &current_command_args, uint32_t index)
180ac7ddfbfSEd Maste     {
181ac7ddfbfSEd Maste         // No repeat for "process launch"...
182ac7ddfbfSEd Maste         return "";
183ac7ddfbfSEd Maste     }
184ac7ddfbfSEd Maste 
185ac7ddfbfSEd Maste protected:
186ac7ddfbfSEd Maste     bool
187ac7ddfbfSEd Maste     DoExecute (Args& launch_args, CommandReturnObject &result)
188ac7ddfbfSEd Maste     {
189ac7ddfbfSEd Maste         Debugger &debugger = m_interpreter.GetDebugger();
190ac7ddfbfSEd Maste         Target *target = debugger.GetSelectedTarget().get();
191ac7ddfbfSEd Maste         // If our listener is NULL, users aren't allows to launch
19212b93ac6SEd Maste         ModuleSP exe_module_sp = target->GetExecutableModule();
193ac7ddfbfSEd Maste 
19412b93ac6SEd Maste         if (exe_module_sp == NULL)
195ac7ddfbfSEd Maste         {
196ac7ddfbfSEd Maste             result.AppendError ("no file in target, create a debug target using the 'target create' command");
197ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
198ac7ddfbfSEd Maste             return false;
199ac7ddfbfSEd Maste         }
200ac7ddfbfSEd Maste 
201ac7ddfbfSEd Maste         StateType state = eStateInvalid;
202ac7ddfbfSEd Maste 
20312b93ac6SEd Maste         if (!StopProcessIfNecessary(m_exe_ctx.GetProcessPtr(), state, result))
204ac7ddfbfSEd Maste             return false;
205ac7ddfbfSEd Maste 
206ac7ddfbfSEd Maste         const char *target_settings_argv0 = target->GetArg0();
207ac7ddfbfSEd Maste 
2080127ef0fSEd Maste         // Determine whether we will disable ASLR or leave it in the default state (i.e. enabled if the platform supports it).
2090127ef0fSEd Maste         // First check if the process launch options explicitly turn on/off disabling ASLR.  If so, use that setting;
2100127ef0fSEd Maste         // otherwise, use the 'settings target.disable-aslr' setting.
2110127ef0fSEd Maste         bool disable_aslr = false;
2120127ef0fSEd Maste         if (m_options.disable_aslr != eLazyBoolCalculate)
2130127ef0fSEd Maste         {
2140127ef0fSEd Maste             // The user specified an explicit setting on the process launch line.  Use it.
2150127ef0fSEd Maste             disable_aslr = (m_options.disable_aslr == eLazyBoolYes);
2160127ef0fSEd Maste         }
2170127ef0fSEd Maste         else
2180127ef0fSEd Maste         {
2190127ef0fSEd Maste             // The user did not explicitly specify whether to disable ASLR.  Fall back to the target.disable-aslr setting.
2200127ef0fSEd Maste             disable_aslr = target->GetDisableASLR ();
2210127ef0fSEd Maste         }
2220127ef0fSEd Maste 
2230127ef0fSEd Maste         if (disable_aslr)
22412b93ac6SEd Maste             m_options.launch_info.GetFlags().Set (eLaunchFlagDisableASLR);
2250127ef0fSEd Maste         else
2260127ef0fSEd Maste             m_options.launch_info.GetFlags().Clear (eLaunchFlagDisableASLR);
2270127ef0fSEd Maste 
2280127ef0fSEd Maste         if (target->GetDetachOnError())
2290127ef0fSEd Maste             m_options.launch_info.GetFlags().Set (eLaunchFlagDetachOnError);
23012b93ac6SEd Maste 
23112b93ac6SEd Maste         if (target->GetDisableSTDIO())
23212b93ac6SEd Maste             m_options.launch_info.GetFlags().Set (eLaunchFlagDisableSTDIO);
23312b93ac6SEd Maste 
23412b93ac6SEd Maste         Args environment;
23512b93ac6SEd Maste         target->GetEnvironmentAsArgs (environment);
23612b93ac6SEd Maste         if (environment.GetArgumentCount() > 0)
23712b93ac6SEd Maste             m_options.launch_info.GetEnvironmentEntries ().AppendArguments (environment);
238ac7ddfbfSEd Maste 
239ac7ddfbfSEd Maste         if (target_settings_argv0)
240ac7ddfbfSEd Maste         {
241ac7ddfbfSEd Maste             m_options.launch_info.GetArguments().AppendArgument (target_settings_argv0);
24212b93ac6SEd Maste             m_options.launch_info.SetExecutableFile(exe_module_sp->GetPlatformFileSpec(), false);
243ac7ddfbfSEd Maste         }
244ac7ddfbfSEd Maste         else
245ac7ddfbfSEd Maste         {
24612b93ac6SEd Maste             m_options.launch_info.SetExecutableFile(exe_module_sp->GetPlatformFileSpec(), true);
247ac7ddfbfSEd Maste         }
248ac7ddfbfSEd Maste 
249ac7ddfbfSEd Maste         if (launch_args.GetArgumentCount() == 0)
250ac7ddfbfSEd Maste         {
251ac7ddfbfSEd Maste             Args target_setting_args;
252ac7ddfbfSEd Maste             if (target->GetRunArguments(target_setting_args))
253ac7ddfbfSEd Maste                 m_options.launch_info.GetArguments().AppendArguments (target_setting_args);
254ac7ddfbfSEd Maste         }
255ac7ddfbfSEd Maste         else
256ac7ddfbfSEd Maste         {
257ac7ddfbfSEd Maste             m_options.launch_info.GetArguments().AppendArguments (launch_args);
258ac7ddfbfSEd Maste             // Save the arguments for subsequent runs in the current target.
259ac7ddfbfSEd Maste             target->SetRunArguments (launch_args);
260ac7ddfbfSEd Maste         }
261ac7ddfbfSEd Maste 
26212b93ac6SEd Maste         Error error = target->Launch(debugger.GetListener(), m_options.launch_info);
263ac7ddfbfSEd Maste 
264ac7ddfbfSEd Maste         if (error.Success())
265ac7ddfbfSEd Maste         {
26612b93ac6SEd Maste             const char *archname = exe_module_sp->GetArchitecture().GetArchitectureName();
26712b93ac6SEd Maste             ProcessSP process_sp (target->GetProcessSP());
26812b93ac6SEd Maste             if (process_sp)
269ac7ddfbfSEd Maste             {
27012b93ac6SEd Maste                 result.AppendMessageWithFormat ("Process %" PRIu64 " launched: '%s' (%s)\n", process_sp->GetID(), exe_module_sp->GetFileSpec().GetPath().c_str(), archname);
271ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusSuccessFinishResult);
27212b93ac6SEd Maste                 result.SetDidChangeProcessState (true);
273ac7ddfbfSEd Maste             }
274ac7ddfbfSEd Maste             else
275ac7ddfbfSEd Maste             {
27612b93ac6SEd Maste                 result.AppendError("no error returned from Target::Launch, and target has no process");
277ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusFailed);
278ac7ddfbfSEd Maste             }
279ac7ddfbfSEd Maste         }
280ac7ddfbfSEd Maste         else
281ac7ddfbfSEd Maste         {
28212b93ac6SEd Maste             result.AppendError(error.AsCString());
283ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
284ac7ddfbfSEd Maste         }
285ac7ddfbfSEd Maste         return result.Succeeded();
286ac7ddfbfSEd Maste     }
287ac7ddfbfSEd Maste 
288ac7ddfbfSEd Maste protected:
289ac7ddfbfSEd Maste     ProcessLaunchCommandOptions m_options;
290ac7ddfbfSEd Maste };
291ac7ddfbfSEd Maste 
292ac7ddfbfSEd Maste 
293ac7ddfbfSEd Maste //#define SET1 LLDB_OPT_SET_1
294ac7ddfbfSEd Maste //#define SET2 LLDB_OPT_SET_2
295ac7ddfbfSEd Maste //#define SET3 LLDB_OPT_SET_3
296ac7ddfbfSEd Maste //
297ac7ddfbfSEd Maste //OptionDefinition
298ac7ddfbfSEd Maste //CommandObjectProcessLaunch::CommandOptions::g_option_table[] =
299ac7ddfbfSEd Maste //{
30035617911SEd Maste //{ SET1 | SET2 | SET3, false, "stop-at-entry", 's', OptionParser::eNoArgument,       NULL, 0, eArgTypeNone,    "Stop at the entry point of the program when launching a process."},
30135617911SEd Maste //{ SET1              , false, "stdin",         'i', OptionParser::eRequiredArgument, NULL, 0, eArgTypeDirectoryName,    "Redirect stdin for the process to <path>."},
30235617911SEd Maste //{ SET1              , false, "stdout",        'o', OptionParser::eRequiredArgument, NULL, 0, eArgTypeDirectoryName,    "Redirect stdout for the process to <path>."},
30335617911SEd Maste //{ SET1              , false, "stderr",        'e', OptionParser::eRequiredArgument, NULL, 0, eArgTypeDirectoryName,    "Redirect stderr for the process to <path>."},
30435617911SEd Maste //{ SET1 | SET2 | SET3, false, "plugin",        'p', OptionParser::eRequiredArgument, NULL, 0, eArgTypePlugin,  "Name of the process plugin you want to use."},
30535617911SEd Maste //{        SET2       , false, "tty",           't', OptionParser::eOptionalArgument, 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."},
30635617911SEd Maste //{               SET3, false, "no-stdio",      'n', OptionParser::eNoArgument,       NULL, 0, eArgTypeNone,    "Do not set up for terminal I/O to go to running process."},
30735617911SEd Maste //{ SET1 | SET2 | SET3, false, "working-dir",   'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeDirectoryName,    "Set the current working directory to <path> when running the inferior."},
308ac7ddfbfSEd Maste //{ 0,                  false, NULL,             0,  0,                 NULL, 0, eArgTypeNone,    NULL }
309ac7ddfbfSEd Maste //};
310ac7ddfbfSEd Maste //
311ac7ddfbfSEd Maste //#undef SET1
312ac7ddfbfSEd Maste //#undef SET2
313ac7ddfbfSEd Maste //#undef SET3
314ac7ddfbfSEd Maste 
315ac7ddfbfSEd Maste //-------------------------------------------------------------------------
316ac7ddfbfSEd Maste // CommandObjectProcessAttach
317ac7ddfbfSEd Maste //-------------------------------------------------------------------------
318ac7ddfbfSEd Maste #pragma mark CommandObjectProcessAttach
319ac7ddfbfSEd Maste class CommandObjectProcessAttach : public CommandObjectProcessLaunchOrAttach
320ac7ddfbfSEd Maste {
321ac7ddfbfSEd Maste public:
322ac7ddfbfSEd Maste 
323ac7ddfbfSEd Maste     class CommandOptions : public Options
324ac7ddfbfSEd Maste     {
325ac7ddfbfSEd Maste     public:
326ac7ddfbfSEd Maste 
327ac7ddfbfSEd Maste         CommandOptions (CommandInterpreter &interpreter) :
328ac7ddfbfSEd Maste             Options(interpreter)
329ac7ddfbfSEd Maste         {
330ac7ddfbfSEd Maste             // Keep default values of all options in one place: OptionParsingStarting ()
331ac7ddfbfSEd Maste             OptionParsingStarting ();
332ac7ddfbfSEd Maste         }
333ac7ddfbfSEd Maste 
334ac7ddfbfSEd Maste         ~CommandOptions ()
335ac7ddfbfSEd Maste         {
336ac7ddfbfSEd Maste         }
337ac7ddfbfSEd Maste 
338ac7ddfbfSEd Maste         Error
339ac7ddfbfSEd Maste         SetOptionValue (uint32_t option_idx, const char *option_arg)
340ac7ddfbfSEd Maste         {
341ac7ddfbfSEd Maste             Error error;
342ac7ddfbfSEd Maste             const int short_option = m_getopt_table[option_idx].val;
343ac7ddfbfSEd Maste             bool success = false;
344ac7ddfbfSEd Maste             switch (short_option)
345ac7ddfbfSEd Maste             {
346ac7ddfbfSEd Maste                 case 'c':
347ac7ddfbfSEd Maste                     attach_info.SetContinueOnceAttached(true);
348ac7ddfbfSEd Maste                     break;
349ac7ddfbfSEd Maste 
350ac7ddfbfSEd Maste                 case 'p':
351ac7ddfbfSEd Maste                     {
352ac7ddfbfSEd Maste                         lldb::pid_t pid = Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success);
353ac7ddfbfSEd Maste                         if (!success || pid == LLDB_INVALID_PROCESS_ID)
354ac7ddfbfSEd Maste                         {
355ac7ddfbfSEd Maste                             error.SetErrorStringWithFormat("invalid process ID '%s'", option_arg);
356ac7ddfbfSEd Maste                         }
357ac7ddfbfSEd Maste                         else
358ac7ddfbfSEd Maste                         {
359ac7ddfbfSEd Maste                             attach_info.SetProcessID (pid);
360ac7ddfbfSEd Maste                         }
361ac7ddfbfSEd Maste                     }
362ac7ddfbfSEd Maste                     break;
363ac7ddfbfSEd Maste 
364ac7ddfbfSEd Maste                 case 'P':
365ac7ddfbfSEd Maste                     attach_info.SetProcessPluginName (option_arg);
366ac7ddfbfSEd Maste                     break;
367ac7ddfbfSEd Maste 
368ac7ddfbfSEd Maste                 case 'n':
369ac7ddfbfSEd Maste                     attach_info.GetExecutableFile().SetFile(option_arg, false);
370ac7ddfbfSEd Maste                     break;
371ac7ddfbfSEd Maste 
372ac7ddfbfSEd Maste                 case 'w':
373ac7ddfbfSEd Maste                     attach_info.SetWaitForLaunch(true);
374ac7ddfbfSEd Maste                     break;
375ac7ddfbfSEd Maste 
376ac7ddfbfSEd Maste                 case 'i':
377ac7ddfbfSEd Maste                     attach_info.SetIgnoreExisting(false);
378ac7ddfbfSEd Maste                     break;
379ac7ddfbfSEd Maste 
380ac7ddfbfSEd Maste                 default:
381ac7ddfbfSEd Maste                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
382ac7ddfbfSEd Maste                     break;
383ac7ddfbfSEd Maste             }
384ac7ddfbfSEd Maste             return error;
385ac7ddfbfSEd Maste         }
386ac7ddfbfSEd Maste 
387ac7ddfbfSEd Maste         void
388ac7ddfbfSEd Maste         OptionParsingStarting ()
389ac7ddfbfSEd Maste         {
390ac7ddfbfSEd Maste             attach_info.Clear();
391ac7ddfbfSEd Maste         }
392ac7ddfbfSEd Maste 
393ac7ddfbfSEd Maste         const OptionDefinition*
394ac7ddfbfSEd Maste         GetDefinitions ()
395ac7ddfbfSEd Maste         {
396ac7ddfbfSEd Maste             return g_option_table;
397ac7ddfbfSEd Maste         }
398ac7ddfbfSEd Maste 
399ac7ddfbfSEd Maste         virtual bool
400ac7ddfbfSEd Maste         HandleOptionArgumentCompletion (Args &input,
401ac7ddfbfSEd Maste                                         int cursor_index,
402ac7ddfbfSEd Maste                                         int char_pos,
403ac7ddfbfSEd Maste                                         OptionElementVector &opt_element_vector,
404ac7ddfbfSEd Maste                                         int opt_element_index,
405ac7ddfbfSEd Maste                                         int match_start_point,
406ac7ddfbfSEd Maste                                         int max_return_elements,
407ac7ddfbfSEd Maste                                         bool &word_complete,
408ac7ddfbfSEd Maste                                         StringList &matches)
409ac7ddfbfSEd Maste         {
410ac7ddfbfSEd Maste             int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
411ac7ddfbfSEd Maste             int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
412ac7ddfbfSEd Maste 
413ac7ddfbfSEd Maste             // We are only completing the name option for now...
414ac7ddfbfSEd Maste 
415ac7ddfbfSEd Maste             const OptionDefinition *opt_defs = GetDefinitions();
416ac7ddfbfSEd Maste             if (opt_defs[opt_defs_index].short_option == 'n')
417ac7ddfbfSEd Maste             {
418ac7ddfbfSEd Maste                 // Are we in the name?
419ac7ddfbfSEd Maste 
420ac7ddfbfSEd Maste                 // Look to see if there is a -P argument provided, and if so use that plugin, otherwise
421ac7ddfbfSEd Maste                 // use the default plugin.
422ac7ddfbfSEd Maste 
423ac7ddfbfSEd Maste                 const char *partial_name = NULL;
424ac7ddfbfSEd Maste                 partial_name = input.GetArgumentAtIndex(opt_arg_pos);
425ac7ddfbfSEd Maste 
426ac7ddfbfSEd Maste                 PlatformSP platform_sp (m_interpreter.GetPlatform (true));
427ac7ddfbfSEd Maste                 if (platform_sp)
428ac7ddfbfSEd Maste                 {
429ac7ddfbfSEd Maste                     ProcessInstanceInfoList process_infos;
430ac7ddfbfSEd Maste                     ProcessInstanceInfoMatch match_info;
431ac7ddfbfSEd Maste                     if (partial_name)
432ac7ddfbfSEd Maste                     {
433ac7ddfbfSEd Maste                         match_info.GetProcessInfo().GetExecutableFile().SetFile(partial_name, false);
434ac7ddfbfSEd Maste                         match_info.SetNameMatchType(eNameMatchStartsWith);
435ac7ddfbfSEd Maste                     }
436ac7ddfbfSEd Maste                     platform_sp->FindProcesses (match_info, process_infos);
437ac7ddfbfSEd Maste                     const size_t num_matches = process_infos.GetSize();
438ac7ddfbfSEd Maste                     if (num_matches > 0)
439ac7ddfbfSEd Maste                     {
440ac7ddfbfSEd Maste                         for (size_t i=0; i<num_matches; ++i)
441ac7ddfbfSEd Maste                         {
442ac7ddfbfSEd Maste                             matches.AppendString (process_infos.GetProcessNameAtIndex(i),
443ac7ddfbfSEd Maste                                                   process_infos.GetProcessNameLengthAtIndex(i));
444ac7ddfbfSEd Maste                         }
445ac7ddfbfSEd Maste                     }
446ac7ddfbfSEd Maste                 }
447ac7ddfbfSEd Maste             }
448ac7ddfbfSEd Maste 
449ac7ddfbfSEd Maste             return false;
450ac7ddfbfSEd Maste         }
451ac7ddfbfSEd Maste 
452ac7ddfbfSEd Maste         // Options table: Required for subclasses of Options.
453ac7ddfbfSEd Maste 
454ac7ddfbfSEd Maste         static OptionDefinition g_option_table[];
455ac7ddfbfSEd Maste 
456ac7ddfbfSEd Maste         // Instance variables to hold the values for command options.
457ac7ddfbfSEd Maste 
458ac7ddfbfSEd Maste         ProcessAttachInfo attach_info;
459ac7ddfbfSEd Maste     };
460ac7ddfbfSEd Maste 
461ac7ddfbfSEd Maste     CommandObjectProcessAttach (CommandInterpreter &interpreter) :
462ac7ddfbfSEd Maste         CommandObjectProcessLaunchOrAttach (interpreter,
463ac7ddfbfSEd Maste                                             "process attach",
464ac7ddfbfSEd Maste                                             "Attach to a process.",
465ac7ddfbfSEd Maste                                             "process attach <cmd-options>",
466ac7ddfbfSEd Maste                                             0,
467ac7ddfbfSEd Maste                                             "attach"),
468ac7ddfbfSEd Maste         m_options (interpreter)
469ac7ddfbfSEd Maste     {
470ac7ddfbfSEd Maste     }
471ac7ddfbfSEd Maste 
472ac7ddfbfSEd Maste     ~CommandObjectProcessAttach ()
473ac7ddfbfSEd Maste     {
474ac7ddfbfSEd Maste     }
475ac7ddfbfSEd Maste 
476ac7ddfbfSEd Maste     Options *
477ac7ddfbfSEd Maste     GetOptions ()
478ac7ddfbfSEd Maste     {
479ac7ddfbfSEd Maste         return &m_options;
480ac7ddfbfSEd Maste     }
481ac7ddfbfSEd Maste 
482ac7ddfbfSEd Maste protected:
483ac7ddfbfSEd Maste     bool
484ac7ddfbfSEd Maste     DoExecute (Args& command,
485ac7ddfbfSEd Maste              CommandReturnObject &result)
486ac7ddfbfSEd Maste     {
487ac7ddfbfSEd Maste         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
488ac7ddfbfSEd Maste         // N.B. The attach should be synchronous.  It doesn't help much to get the prompt back between initiating the attach
489ac7ddfbfSEd Maste         // and the target actually stopping.  So even if the interpreter is set to be asynchronous, we wait for the stop
490ac7ddfbfSEd Maste         // ourselves here.
491ac7ddfbfSEd Maste 
492ac7ddfbfSEd Maste         StateType state = eStateInvalid;
493ac7ddfbfSEd Maste         Process *process = m_exe_ctx.GetProcessPtr();
494ac7ddfbfSEd Maste 
495ac7ddfbfSEd Maste         if (!StopProcessIfNecessary (process, state, result))
496ac7ddfbfSEd Maste             return false;
497ac7ddfbfSEd Maste 
498ac7ddfbfSEd Maste         if (target == NULL)
499ac7ddfbfSEd Maste         {
500ac7ddfbfSEd Maste             // If there isn't a current target create one.
501ac7ddfbfSEd Maste             TargetSP new_target_sp;
502ac7ddfbfSEd Maste             Error error;
503ac7ddfbfSEd Maste 
504ac7ddfbfSEd Maste             error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(),
505ac7ddfbfSEd Maste                                                                               NULL,
506ac7ddfbfSEd Maste                                                                               NULL,
507ac7ddfbfSEd Maste                                                                               false,
508ac7ddfbfSEd Maste                                                                               NULL, // No platform options
509ac7ddfbfSEd Maste                                                                               new_target_sp);
510ac7ddfbfSEd Maste             target = new_target_sp.get();
511ac7ddfbfSEd Maste             if (target == NULL || error.Fail())
512ac7ddfbfSEd Maste             {
513ac7ddfbfSEd Maste                 result.AppendError(error.AsCString("Error creating target"));
514ac7ddfbfSEd Maste                 return false;
515ac7ddfbfSEd Maste             }
516ac7ddfbfSEd Maste             m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target);
517ac7ddfbfSEd Maste         }
518ac7ddfbfSEd Maste 
519ac7ddfbfSEd Maste         // Record the old executable module, we want to issue a warning if the process of attaching changed the
520ac7ddfbfSEd Maste         // current executable (like somebody said "file foo" then attached to a PID whose executable was bar.)
521ac7ddfbfSEd Maste 
522ac7ddfbfSEd Maste         ModuleSP old_exec_module_sp = target->GetExecutableModule();
523ac7ddfbfSEd Maste         ArchSpec old_arch_spec = target->GetArchitecture();
524ac7ddfbfSEd Maste 
525ac7ddfbfSEd Maste         if (command.GetArgumentCount())
526ac7ddfbfSEd Maste         {
527ac7ddfbfSEd Maste             result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
528ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
529ac7ddfbfSEd Maste         }
530ac7ddfbfSEd Maste         else
531ac7ddfbfSEd Maste         {
532ac7ddfbfSEd Maste             if (state != eStateConnected)
533ac7ddfbfSEd Maste             {
534ac7ddfbfSEd Maste                 const char *plugin_name = m_options.attach_info.GetProcessPluginName();
535ac7ddfbfSEd Maste                 process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name, NULL).get();
536ac7ddfbfSEd Maste             }
537ac7ddfbfSEd Maste 
538ac7ddfbfSEd Maste             if (process)
539ac7ddfbfSEd Maste             {
540ac7ddfbfSEd Maste                 Error error;
541ac7ddfbfSEd Maste                 // If no process info was specified, then use the target executable
542ac7ddfbfSEd Maste                 // name as the process to attach to by default
543ac7ddfbfSEd Maste                 if (!m_options.attach_info.ProcessInfoSpecified ())
544ac7ddfbfSEd Maste                 {
545ac7ddfbfSEd Maste                     if (old_exec_module_sp)
546ac7ddfbfSEd Maste                         m_options.attach_info.GetExecutableFile().GetFilename() = old_exec_module_sp->GetPlatformFileSpec().GetFilename();
547ac7ddfbfSEd Maste 
548ac7ddfbfSEd Maste                     if (!m_options.attach_info.ProcessInfoSpecified ())
549ac7ddfbfSEd Maste                     {
550ac7ddfbfSEd Maste                         error.SetErrorString ("no process specified, create a target with a file, or specify the --pid or --name command option");
551ac7ddfbfSEd Maste                     }
552ac7ddfbfSEd Maste                 }
553ac7ddfbfSEd Maste 
554ac7ddfbfSEd Maste                 if (error.Success())
555ac7ddfbfSEd Maste                 {
5560127ef0fSEd Maste                     // Update the execution context so the current target and process are now selected
5570127ef0fSEd Maste                     // in case we interrupt
5580127ef0fSEd Maste                     m_interpreter.UpdateExecutionContext(NULL);
55912b93ac6SEd Maste                     ListenerSP listener_sp (new Listener("lldb.CommandObjectProcessAttach.DoExecute.attach.hijack"));
56012b93ac6SEd Maste                     m_options.attach_info.SetHijackListener(listener_sp);
56112b93ac6SEd Maste                     process->HijackProcessEvents(listener_sp.get());
562ac7ddfbfSEd Maste                     error = process->Attach (m_options.attach_info);
563ac7ddfbfSEd Maste 
564ac7ddfbfSEd Maste                     if (error.Success())
565ac7ddfbfSEd Maste                     {
566ac7ddfbfSEd Maste                         result.SetStatus (eReturnStatusSuccessContinuingNoResult);
56712b93ac6SEd Maste                         StateType state = process->WaitForProcessToStop (NULL, NULL, false, listener_sp.get());
56812b93ac6SEd Maste 
56912b93ac6SEd Maste                         process->RestoreProcessEvents();
570ac7ddfbfSEd Maste 
571ac7ddfbfSEd Maste                         result.SetDidChangeProcessState (true);
572ac7ddfbfSEd Maste 
573ac7ddfbfSEd Maste                         if (state == eStateStopped)
574ac7ddfbfSEd Maste                         {
575ac7ddfbfSEd Maste                             result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
576ac7ddfbfSEd Maste                             result.SetStatus (eReturnStatusSuccessFinishNoResult);
577ac7ddfbfSEd Maste                         }
578ac7ddfbfSEd Maste                         else
579ac7ddfbfSEd Maste                         {
5800127ef0fSEd Maste                             const char *exit_desc = process->GetExitDescription();
5810127ef0fSEd Maste                             if (exit_desc)
5820127ef0fSEd Maste                                 result.AppendErrorWithFormat ("attach failed: %s", exit_desc);
5830127ef0fSEd Maste                             else
584ac7ddfbfSEd Maste                                 result.AppendError ("attach failed: process did not stop (no such process or permission problem?)");
585ac7ddfbfSEd Maste                             process->Destroy();
586ac7ddfbfSEd Maste                             result.SetStatus (eReturnStatusFailed);
58712b93ac6SEd Maste                         }
58812b93ac6SEd Maste                     }
58912b93ac6SEd Maste                     else
59012b93ac6SEd Maste                     {
59112b93ac6SEd Maste                         result.AppendErrorWithFormat ("attach failed: %s\n", error.AsCString());
59212b93ac6SEd Maste                         result.SetStatus (eReturnStatusFailed);
593ac7ddfbfSEd Maste                     }
594ac7ddfbfSEd Maste                 }
595ac7ddfbfSEd Maste             }
596ac7ddfbfSEd Maste         }
597ac7ddfbfSEd Maste 
598ac7ddfbfSEd Maste         if (result.Succeeded())
599ac7ddfbfSEd Maste         {
600ac7ddfbfSEd Maste             // Okay, we're done.  Last step is to warn if the executable module has changed:
601ac7ddfbfSEd Maste             char new_path[PATH_MAX];
602ac7ddfbfSEd Maste             ModuleSP new_exec_module_sp (target->GetExecutableModule());
603ac7ddfbfSEd Maste             if (!old_exec_module_sp)
604ac7ddfbfSEd Maste             {
605ac7ddfbfSEd Maste                 // We might not have a module if we attached to a raw pid...
606ac7ddfbfSEd Maste                 if (new_exec_module_sp)
607ac7ddfbfSEd Maste                 {
608ac7ddfbfSEd Maste                     new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX);
609ac7ddfbfSEd Maste                     result.AppendMessageWithFormat("Executable module set to \"%s\".\n", new_path);
610ac7ddfbfSEd Maste                 }
611ac7ddfbfSEd Maste             }
612ac7ddfbfSEd Maste             else if (old_exec_module_sp->GetFileSpec() != new_exec_module_sp->GetFileSpec())
613ac7ddfbfSEd Maste             {
614ac7ddfbfSEd Maste                 char old_path[PATH_MAX];
615ac7ddfbfSEd Maste 
616ac7ddfbfSEd Maste                 old_exec_module_sp->GetFileSpec().GetPath (old_path, PATH_MAX);
617ac7ddfbfSEd Maste                 new_exec_module_sp->GetFileSpec().GetPath (new_path, PATH_MAX);
618ac7ddfbfSEd Maste 
619ac7ddfbfSEd Maste                 result.AppendWarningWithFormat("Executable module changed from \"%s\" to \"%s\".\n",
620ac7ddfbfSEd Maste                                                     old_path, new_path);
621ac7ddfbfSEd Maste             }
622ac7ddfbfSEd Maste 
623ac7ddfbfSEd Maste             if (!old_arch_spec.IsValid())
624ac7ddfbfSEd Maste             {
625ac7ddfbfSEd Maste                 result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().GetTriple().getTriple().c_str());
626ac7ddfbfSEd Maste             }
627ac7ddfbfSEd Maste             else if (!old_arch_spec.IsExactMatch(target->GetArchitecture()))
628ac7ddfbfSEd Maste             {
629ac7ddfbfSEd Maste                 result.AppendWarningWithFormat("Architecture changed from %s to %s.\n",
630ac7ddfbfSEd Maste                                                old_arch_spec.GetTriple().getTriple().c_str(),
631ac7ddfbfSEd Maste                                                target->GetArchitecture().GetTriple().getTriple().c_str());
632ac7ddfbfSEd Maste             }
633ac7ddfbfSEd Maste 
634ac7ddfbfSEd Maste             // This supports the use-case scenario of immediately continuing the process once attached.
635ac7ddfbfSEd Maste             if (m_options.attach_info.GetContinueOnceAttached())
636ac7ddfbfSEd Maste                 m_interpreter.HandleCommand("process continue", eLazyBoolNo, result);
637ac7ddfbfSEd Maste         }
638ac7ddfbfSEd Maste         return result.Succeeded();
639ac7ddfbfSEd Maste     }
640ac7ddfbfSEd Maste 
641ac7ddfbfSEd Maste     CommandOptions m_options;
642ac7ddfbfSEd Maste };
643ac7ddfbfSEd Maste 
644ac7ddfbfSEd Maste 
645ac7ddfbfSEd Maste OptionDefinition
646ac7ddfbfSEd Maste CommandObjectProcessAttach::CommandOptions::g_option_table[] =
647ac7ddfbfSEd Maste {
6480127ef0fSEd Maste { LLDB_OPT_SET_ALL, false, "continue",'c', OptionParser::eNoArgument,         NULL, NULL, 0, eArgTypeNone,         "Immediately continue the process once attached."},
6490127ef0fSEd Maste { LLDB_OPT_SET_ALL, false, "plugin",  'P', OptionParser::eRequiredArgument,   NULL, NULL, 0, eArgTypePlugin,       "Name of the process plugin you want to use."},
6500127ef0fSEd Maste { LLDB_OPT_SET_1,   false, "pid",     'p', OptionParser::eRequiredArgument,   NULL, NULL, 0, eArgTypePid,          "The process ID of an existing process to attach to."},
6510127ef0fSEd Maste { LLDB_OPT_SET_2,   false, "name",    'n', OptionParser::eRequiredArgument,   NULL, NULL, 0, eArgTypeProcessName,  "The name of the process to attach to."},
6520127ef0fSEd Maste { LLDB_OPT_SET_2,   false, "include-existing", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,         "Include existing processes when doing attach -w."},
6530127ef0fSEd Maste { LLDB_OPT_SET_2,   false, "waitfor", 'w', OptionParser::eNoArgument,         NULL, NULL, 0, eArgTypeNone,         "Wait for the process with <process-name> to launch."},
6540127ef0fSEd Maste { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
655ac7ddfbfSEd Maste };
656ac7ddfbfSEd Maste 
657ac7ddfbfSEd Maste //-------------------------------------------------------------------------
658ac7ddfbfSEd Maste // CommandObjectProcessContinue
659ac7ddfbfSEd Maste //-------------------------------------------------------------------------
660ac7ddfbfSEd Maste #pragma mark CommandObjectProcessContinue
661ac7ddfbfSEd Maste 
662ac7ddfbfSEd Maste class CommandObjectProcessContinue : public CommandObjectParsed
663ac7ddfbfSEd Maste {
664ac7ddfbfSEd Maste public:
665ac7ddfbfSEd Maste 
666ac7ddfbfSEd Maste     CommandObjectProcessContinue (CommandInterpreter &interpreter) :
667ac7ddfbfSEd Maste         CommandObjectParsed (interpreter,
668ac7ddfbfSEd Maste                              "process continue",
669ac7ddfbfSEd Maste                              "Continue execution of all threads in the current process.",
670ac7ddfbfSEd Maste                              "process continue",
671ac7ddfbfSEd Maste                              eFlagRequiresProcess       |
672ac7ddfbfSEd Maste                              eFlagTryTargetAPILock      |
673ac7ddfbfSEd Maste                              eFlagProcessMustBeLaunched |
674ac7ddfbfSEd Maste                              eFlagProcessMustBePaused   ),
675ac7ddfbfSEd Maste         m_options(interpreter)
676ac7ddfbfSEd Maste     {
677ac7ddfbfSEd Maste     }
678ac7ddfbfSEd Maste 
679ac7ddfbfSEd Maste 
680ac7ddfbfSEd Maste     ~CommandObjectProcessContinue ()
681ac7ddfbfSEd Maste     {
682ac7ddfbfSEd Maste     }
683ac7ddfbfSEd Maste 
684ac7ddfbfSEd Maste protected:
685ac7ddfbfSEd Maste 
686ac7ddfbfSEd Maste     class CommandOptions : public Options
687ac7ddfbfSEd Maste     {
688ac7ddfbfSEd Maste     public:
689ac7ddfbfSEd Maste 
690ac7ddfbfSEd Maste         CommandOptions (CommandInterpreter &interpreter) :
691ac7ddfbfSEd Maste             Options(interpreter)
692ac7ddfbfSEd Maste         {
693ac7ddfbfSEd Maste             // Keep default values of all options in one place: OptionParsingStarting ()
694ac7ddfbfSEd Maste             OptionParsingStarting ();
695ac7ddfbfSEd Maste         }
696ac7ddfbfSEd Maste 
697ac7ddfbfSEd Maste         ~CommandOptions ()
698ac7ddfbfSEd Maste         {
699ac7ddfbfSEd Maste         }
700ac7ddfbfSEd Maste 
701ac7ddfbfSEd Maste         Error
702ac7ddfbfSEd Maste         SetOptionValue (uint32_t option_idx, const char *option_arg)
703ac7ddfbfSEd Maste         {
704ac7ddfbfSEd Maste             Error error;
705ac7ddfbfSEd Maste             const int short_option = m_getopt_table[option_idx].val;
706ac7ddfbfSEd Maste             bool success = false;
707ac7ddfbfSEd Maste             switch (short_option)
708ac7ddfbfSEd Maste             {
709ac7ddfbfSEd Maste                 case 'i':
710ac7ddfbfSEd Maste                     m_ignore = Args::StringToUInt32 (option_arg, 0, 0, &success);
711ac7ddfbfSEd Maste                     if (!success)
712ac7ddfbfSEd Maste                         error.SetErrorStringWithFormat ("invalid value for ignore option: \"%s\", should be a number.", option_arg);
713ac7ddfbfSEd Maste                     break;
714ac7ddfbfSEd Maste 
715ac7ddfbfSEd Maste                 default:
716ac7ddfbfSEd Maste                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
717ac7ddfbfSEd Maste                     break;
718ac7ddfbfSEd Maste             }
719ac7ddfbfSEd Maste             return error;
720ac7ddfbfSEd Maste         }
721ac7ddfbfSEd Maste 
722ac7ddfbfSEd Maste         void
723ac7ddfbfSEd Maste         OptionParsingStarting ()
724ac7ddfbfSEd Maste         {
725ac7ddfbfSEd Maste             m_ignore = 0;
726ac7ddfbfSEd Maste         }
727ac7ddfbfSEd Maste 
728ac7ddfbfSEd Maste         const OptionDefinition*
729ac7ddfbfSEd Maste         GetDefinitions ()
730ac7ddfbfSEd Maste         {
731ac7ddfbfSEd Maste             return g_option_table;
732ac7ddfbfSEd Maste         }
733ac7ddfbfSEd Maste 
734ac7ddfbfSEd Maste         // Options table: Required for subclasses of Options.
735ac7ddfbfSEd Maste 
736ac7ddfbfSEd Maste         static OptionDefinition g_option_table[];
737ac7ddfbfSEd Maste 
738ac7ddfbfSEd Maste         uint32_t m_ignore;
739ac7ddfbfSEd Maste     };
740ac7ddfbfSEd Maste 
741ac7ddfbfSEd Maste     bool
742ac7ddfbfSEd Maste     DoExecute (Args& command, CommandReturnObject &result)
743ac7ddfbfSEd Maste     {
744ac7ddfbfSEd Maste         Process *process = m_exe_ctx.GetProcessPtr();
745ac7ddfbfSEd Maste         bool synchronous_execution = m_interpreter.GetSynchronous ();
746ac7ddfbfSEd Maste         StateType state = process->GetState();
747ac7ddfbfSEd Maste         if (state == eStateStopped)
748ac7ddfbfSEd Maste         {
749ac7ddfbfSEd Maste             if (command.GetArgumentCount() != 0)
750ac7ddfbfSEd Maste             {
751ac7ddfbfSEd Maste                 result.AppendErrorWithFormat ("The '%s' command does not take any arguments.\n", m_cmd_name.c_str());
752ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusFailed);
753ac7ddfbfSEd Maste                 return false;
754ac7ddfbfSEd Maste             }
755ac7ddfbfSEd Maste 
756ac7ddfbfSEd Maste             if (m_options.m_ignore > 0)
757ac7ddfbfSEd Maste             {
758ac7ddfbfSEd Maste                 ThreadSP sel_thread_sp(process->GetThreadList().GetSelectedThread());
759ac7ddfbfSEd Maste                 if (sel_thread_sp)
760ac7ddfbfSEd Maste                 {
761ac7ddfbfSEd Maste                     StopInfoSP stop_info_sp = sel_thread_sp->GetStopInfo();
762ac7ddfbfSEd Maste                     if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonBreakpoint)
763ac7ddfbfSEd Maste                     {
764ac7ddfbfSEd Maste                         lldb::break_id_t bp_site_id = (lldb::break_id_t)stop_info_sp->GetValue();
765ac7ddfbfSEd Maste                         BreakpointSiteSP bp_site_sp(process->GetBreakpointSiteList().FindByID(bp_site_id));
766ac7ddfbfSEd Maste                         if (bp_site_sp)
767ac7ddfbfSEd Maste                         {
768ac7ddfbfSEd Maste                             const size_t num_owners = bp_site_sp->GetNumberOfOwners();
769ac7ddfbfSEd Maste                             for (size_t i = 0; i < num_owners; i++)
770ac7ddfbfSEd Maste                             {
771ac7ddfbfSEd Maste                                 Breakpoint &bp_ref = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
772ac7ddfbfSEd Maste                                 if (!bp_ref.IsInternal())
773ac7ddfbfSEd Maste                                 {
774ac7ddfbfSEd Maste                                     bp_ref.SetIgnoreCount(m_options.m_ignore);
775ac7ddfbfSEd Maste                                 }
776ac7ddfbfSEd Maste                             }
777ac7ddfbfSEd Maste                         }
778ac7ddfbfSEd Maste                     }
779ac7ddfbfSEd Maste                 }
780ac7ddfbfSEd Maste             }
781ac7ddfbfSEd Maste 
782ac7ddfbfSEd Maste             {  // Scope for thread list mutex:
783ac7ddfbfSEd Maste                 Mutex::Locker locker (process->GetThreadList().GetMutex());
784ac7ddfbfSEd Maste                 const uint32_t num_threads = process->GetThreadList().GetSize();
785ac7ddfbfSEd Maste 
786ac7ddfbfSEd Maste                 // Set the actions that the threads should each take when resuming
787ac7ddfbfSEd Maste                 for (uint32_t idx=0; idx<num_threads; ++idx)
788ac7ddfbfSEd Maste                 {
7890127ef0fSEd Maste                     const bool override_suspend = false;
7900127ef0fSEd Maste                     process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState (eStateRunning, override_suspend);
791ac7ddfbfSEd Maste                 }
792ac7ddfbfSEd Maste             }
793ac7ddfbfSEd Maste 
794ac7ddfbfSEd Maste             Error error(process->Resume());
7950127ef0fSEd Maste 
796ac7ddfbfSEd Maste             if (error.Success())
797ac7ddfbfSEd Maste             {
7980127ef0fSEd Maste                 // There is a race condition where this thread will return up the call stack to the main command
7990127ef0fSEd Maste                 // handler and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has
8000127ef0fSEd Maste                 // a chance to call PushProcessIOHandler().
8010127ef0fSEd Maste                 process->SyncIOHandler(2000);
8020127ef0fSEd Maste 
803ac7ddfbfSEd Maste                 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
804ac7ddfbfSEd Maste                 if (synchronous_execution)
805ac7ddfbfSEd Maste                 {
806ac7ddfbfSEd Maste                     state = process->WaitForProcessToStop (NULL);
807ac7ddfbfSEd Maste 
808ac7ddfbfSEd Maste                     result.SetDidChangeProcessState (true);
809ac7ddfbfSEd Maste                     result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
810ac7ddfbfSEd Maste                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
811ac7ddfbfSEd Maste                 }
812ac7ddfbfSEd Maste                 else
813ac7ddfbfSEd Maste                 {
814ac7ddfbfSEd Maste                     result.SetStatus (eReturnStatusSuccessContinuingNoResult);
815ac7ddfbfSEd Maste                 }
816ac7ddfbfSEd Maste             }
817ac7ddfbfSEd Maste             else
818ac7ddfbfSEd Maste             {
819ac7ddfbfSEd Maste                 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
820ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusFailed);
821ac7ddfbfSEd Maste             }
822ac7ddfbfSEd Maste         }
823ac7ddfbfSEd Maste         else
824ac7ddfbfSEd Maste         {
825ac7ddfbfSEd Maste             result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
826ac7ddfbfSEd Maste                                          StateAsCString(state));
827ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
828ac7ddfbfSEd Maste         }
829ac7ddfbfSEd Maste         return result.Succeeded();
830ac7ddfbfSEd Maste     }
831ac7ddfbfSEd Maste 
832ac7ddfbfSEd Maste     Options *
833ac7ddfbfSEd Maste     GetOptions ()
834ac7ddfbfSEd Maste     {
835ac7ddfbfSEd Maste         return &m_options;
836ac7ddfbfSEd Maste     }
837ac7ddfbfSEd Maste 
838ac7ddfbfSEd Maste     CommandOptions m_options;
839ac7ddfbfSEd Maste 
840ac7ddfbfSEd Maste };
841ac7ddfbfSEd Maste 
842ac7ddfbfSEd Maste OptionDefinition
843ac7ddfbfSEd Maste CommandObjectProcessContinue::CommandOptions::g_option_table[] =
844ac7ddfbfSEd Maste {
8450127ef0fSEd Maste { LLDB_OPT_SET_ALL, false, "ignore-count",'i', OptionParser::eRequiredArgument,         NULL, NULL, 0, eArgTypeUnsignedInteger,
846ac7ddfbfSEd Maste                            "Ignore <N> crossings of the breakpoint (if it exists) for the currently selected thread."},
8470127ef0fSEd Maste { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
848ac7ddfbfSEd Maste };
849ac7ddfbfSEd Maste 
850ac7ddfbfSEd Maste //-------------------------------------------------------------------------
851ac7ddfbfSEd Maste // CommandObjectProcessDetach
852ac7ddfbfSEd Maste //-------------------------------------------------------------------------
853ac7ddfbfSEd Maste #pragma mark CommandObjectProcessDetach
854ac7ddfbfSEd Maste 
855ac7ddfbfSEd Maste class CommandObjectProcessDetach : public CommandObjectParsed
856ac7ddfbfSEd Maste {
857ac7ddfbfSEd Maste public:
858ac7ddfbfSEd Maste     class CommandOptions : public Options
859ac7ddfbfSEd Maste     {
860ac7ddfbfSEd Maste     public:
861ac7ddfbfSEd Maste 
862ac7ddfbfSEd Maste         CommandOptions (CommandInterpreter &interpreter) :
863ac7ddfbfSEd Maste             Options (interpreter)
864ac7ddfbfSEd Maste         {
865ac7ddfbfSEd Maste             OptionParsingStarting ();
866ac7ddfbfSEd Maste         }
867ac7ddfbfSEd Maste 
868ac7ddfbfSEd Maste         ~CommandOptions ()
869ac7ddfbfSEd Maste         {
870ac7ddfbfSEd Maste         }
871ac7ddfbfSEd Maste 
872ac7ddfbfSEd Maste         Error
873ac7ddfbfSEd Maste         SetOptionValue (uint32_t option_idx, const char *option_arg)
874ac7ddfbfSEd Maste         {
875ac7ddfbfSEd Maste             Error error;
876ac7ddfbfSEd Maste             const int short_option = m_getopt_table[option_idx].val;
877ac7ddfbfSEd Maste 
878ac7ddfbfSEd Maste             switch (short_option)
879ac7ddfbfSEd Maste             {
880ac7ddfbfSEd Maste                 case 's':
881ac7ddfbfSEd Maste                     bool tmp_result;
882ac7ddfbfSEd Maste                     bool success;
883ac7ddfbfSEd Maste                     tmp_result = Args::StringToBoolean(option_arg, false, &success);
884ac7ddfbfSEd Maste                     if (!success)
885ac7ddfbfSEd Maste                         error.SetErrorStringWithFormat("invalid boolean option: \"%s\"", option_arg);
886ac7ddfbfSEd Maste                     else
887ac7ddfbfSEd Maste                     {
888ac7ddfbfSEd Maste                         if (tmp_result)
889ac7ddfbfSEd Maste                             m_keep_stopped = eLazyBoolYes;
890ac7ddfbfSEd Maste                         else
891ac7ddfbfSEd Maste                             m_keep_stopped = eLazyBoolNo;
892ac7ddfbfSEd Maste                     }
893ac7ddfbfSEd Maste                     break;
894ac7ddfbfSEd Maste                 default:
895ac7ddfbfSEd Maste                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
896ac7ddfbfSEd Maste                     break;
897ac7ddfbfSEd Maste             }
898ac7ddfbfSEd Maste             return error;
899ac7ddfbfSEd Maste         }
900ac7ddfbfSEd Maste 
901ac7ddfbfSEd Maste         void
902ac7ddfbfSEd Maste         OptionParsingStarting ()
903ac7ddfbfSEd Maste         {
904ac7ddfbfSEd Maste             m_keep_stopped = eLazyBoolCalculate;
905ac7ddfbfSEd Maste         }
906ac7ddfbfSEd Maste 
907ac7ddfbfSEd Maste         const OptionDefinition*
908ac7ddfbfSEd Maste         GetDefinitions ()
909ac7ddfbfSEd Maste         {
910ac7ddfbfSEd Maste             return g_option_table;
911ac7ddfbfSEd Maste         }
912ac7ddfbfSEd Maste 
913ac7ddfbfSEd Maste         // Options table: Required for subclasses of Options.
914ac7ddfbfSEd Maste 
915ac7ddfbfSEd Maste         static OptionDefinition g_option_table[];
916ac7ddfbfSEd Maste 
917ac7ddfbfSEd Maste         // Instance variables to hold the values for command options.
918ac7ddfbfSEd Maste         LazyBool m_keep_stopped;
919ac7ddfbfSEd Maste     };
920ac7ddfbfSEd Maste 
921ac7ddfbfSEd Maste     CommandObjectProcessDetach (CommandInterpreter &interpreter) :
922ac7ddfbfSEd Maste         CommandObjectParsed (interpreter,
923ac7ddfbfSEd Maste                              "process detach",
924ac7ddfbfSEd Maste                              "Detach from the current process being debugged.",
925ac7ddfbfSEd Maste                              "process detach",
926ac7ddfbfSEd Maste                              eFlagRequiresProcess      |
927ac7ddfbfSEd Maste                              eFlagTryTargetAPILock     |
928ac7ddfbfSEd Maste                              eFlagProcessMustBeLaunched),
929ac7ddfbfSEd Maste         m_options(interpreter)
930ac7ddfbfSEd Maste     {
931ac7ddfbfSEd Maste     }
932ac7ddfbfSEd Maste 
933ac7ddfbfSEd Maste     ~CommandObjectProcessDetach ()
934ac7ddfbfSEd Maste     {
935ac7ddfbfSEd Maste     }
936ac7ddfbfSEd Maste 
937ac7ddfbfSEd Maste     Options *
938ac7ddfbfSEd Maste     GetOptions ()
939ac7ddfbfSEd Maste     {
940ac7ddfbfSEd Maste         return &m_options;
941ac7ddfbfSEd Maste     }
942ac7ddfbfSEd Maste 
943ac7ddfbfSEd Maste 
944ac7ddfbfSEd Maste protected:
945ac7ddfbfSEd Maste     bool
946ac7ddfbfSEd Maste     DoExecute (Args& command, CommandReturnObject &result)
947ac7ddfbfSEd Maste     {
948ac7ddfbfSEd Maste         Process *process = m_exe_ctx.GetProcessPtr();
949ac7ddfbfSEd Maste         // FIXME: This will be a Command Option:
950ac7ddfbfSEd Maste         bool keep_stopped;
951ac7ddfbfSEd Maste         if (m_options.m_keep_stopped == eLazyBoolCalculate)
952ac7ddfbfSEd Maste         {
953ac7ddfbfSEd Maste             // Check the process default:
954ac7ddfbfSEd Maste             if (process->GetDetachKeepsStopped())
955ac7ddfbfSEd Maste                 keep_stopped = true;
956ac7ddfbfSEd Maste             else
957ac7ddfbfSEd Maste                 keep_stopped = false;
958ac7ddfbfSEd Maste         }
959ac7ddfbfSEd Maste         else if (m_options.m_keep_stopped == eLazyBoolYes)
960ac7ddfbfSEd Maste             keep_stopped = true;
961ac7ddfbfSEd Maste         else
962ac7ddfbfSEd Maste             keep_stopped = false;
963ac7ddfbfSEd Maste 
964ac7ddfbfSEd Maste         Error error (process->Detach(keep_stopped));
965ac7ddfbfSEd Maste         if (error.Success())
966ac7ddfbfSEd Maste         {
967ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusSuccessFinishResult);
968ac7ddfbfSEd Maste         }
969ac7ddfbfSEd Maste         else
970ac7ddfbfSEd Maste         {
971ac7ddfbfSEd Maste             result.AppendErrorWithFormat ("Detach failed: %s\n", error.AsCString());
972ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
973ac7ddfbfSEd Maste             return false;
974ac7ddfbfSEd Maste         }
975ac7ddfbfSEd Maste         return result.Succeeded();
976ac7ddfbfSEd Maste     }
977ac7ddfbfSEd Maste 
978ac7ddfbfSEd Maste     CommandOptions m_options;
979ac7ddfbfSEd Maste };
980ac7ddfbfSEd Maste 
981ac7ddfbfSEd Maste OptionDefinition
982ac7ddfbfSEd Maste CommandObjectProcessDetach::CommandOptions::g_option_table[] =
983ac7ddfbfSEd Maste {
9840127ef0fSEd Maste { LLDB_OPT_SET_1, false, "keep-stopped",   's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Whether or not the process should be kept stopped on detach (if possible)." },
9850127ef0fSEd Maste { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
986ac7ddfbfSEd Maste };
987ac7ddfbfSEd Maste 
988ac7ddfbfSEd Maste //-------------------------------------------------------------------------
989ac7ddfbfSEd Maste // CommandObjectProcessConnect
990ac7ddfbfSEd Maste //-------------------------------------------------------------------------
991ac7ddfbfSEd Maste #pragma mark CommandObjectProcessConnect
992ac7ddfbfSEd Maste 
993ac7ddfbfSEd Maste class CommandObjectProcessConnect : public CommandObjectParsed
994ac7ddfbfSEd Maste {
995ac7ddfbfSEd Maste public:
996ac7ddfbfSEd Maste 
997ac7ddfbfSEd Maste     class CommandOptions : public Options
998ac7ddfbfSEd Maste     {
999ac7ddfbfSEd Maste     public:
1000ac7ddfbfSEd Maste 
1001ac7ddfbfSEd Maste         CommandOptions (CommandInterpreter &interpreter) :
1002ac7ddfbfSEd Maste             Options(interpreter)
1003ac7ddfbfSEd Maste         {
1004ac7ddfbfSEd Maste             // Keep default values of all options in one place: OptionParsingStarting ()
1005ac7ddfbfSEd Maste             OptionParsingStarting ();
1006ac7ddfbfSEd Maste         }
1007ac7ddfbfSEd Maste 
1008ac7ddfbfSEd Maste         ~CommandOptions ()
1009ac7ddfbfSEd Maste         {
1010ac7ddfbfSEd Maste         }
1011ac7ddfbfSEd Maste 
1012ac7ddfbfSEd Maste         Error
1013ac7ddfbfSEd Maste         SetOptionValue (uint32_t option_idx, const char *option_arg)
1014ac7ddfbfSEd Maste         {
1015ac7ddfbfSEd Maste             Error error;
1016ac7ddfbfSEd Maste             const int short_option = m_getopt_table[option_idx].val;
1017ac7ddfbfSEd Maste 
1018ac7ddfbfSEd Maste             switch (short_option)
1019ac7ddfbfSEd Maste             {
1020ac7ddfbfSEd Maste             case 'p':
1021ac7ddfbfSEd Maste                 plugin_name.assign (option_arg);
1022ac7ddfbfSEd Maste                 break;
1023ac7ddfbfSEd Maste 
1024ac7ddfbfSEd Maste             default:
1025ac7ddfbfSEd Maste                 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
1026ac7ddfbfSEd Maste                 break;
1027ac7ddfbfSEd Maste             }
1028ac7ddfbfSEd Maste             return error;
1029ac7ddfbfSEd Maste         }
1030ac7ddfbfSEd Maste 
1031ac7ddfbfSEd Maste         void
1032ac7ddfbfSEd Maste         OptionParsingStarting ()
1033ac7ddfbfSEd Maste         {
1034ac7ddfbfSEd Maste             plugin_name.clear();
1035ac7ddfbfSEd Maste         }
1036ac7ddfbfSEd Maste 
1037ac7ddfbfSEd Maste         const OptionDefinition*
1038ac7ddfbfSEd Maste         GetDefinitions ()
1039ac7ddfbfSEd Maste         {
1040ac7ddfbfSEd Maste             return g_option_table;
1041ac7ddfbfSEd Maste         }
1042ac7ddfbfSEd Maste 
1043ac7ddfbfSEd Maste         // Options table: Required for subclasses of Options.
1044ac7ddfbfSEd Maste 
1045ac7ddfbfSEd Maste         static OptionDefinition g_option_table[];
1046ac7ddfbfSEd Maste 
1047ac7ddfbfSEd Maste         // Instance variables to hold the values for command options.
1048ac7ddfbfSEd Maste 
1049ac7ddfbfSEd Maste         std::string plugin_name;
1050ac7ddfbfSEd Maste     };
1051ac7ddfbfSEd Maste 
1052ac7ddfbfSEd Maste     CommandObjectProcessConnect (CommandInterpreter &interpreter) :
1053ac7ddfbfSEd Maste         CommandObjectParsed (interpreter,
1054ac7ddfbfSEd Maste                              "process connect",
1055ac7ddfbfSEd Maste                              "Connect to a remote debug service.",
1056ac7ddfbfSEd Maste                              "process connect <remote-url>",
1057ac7ddfbfSEd Maste                              0),
1058ac7ddfbfSEd Maste         m_options (interpreter)
1059ac7ddfbfSEd Maste     {
1060ac7ddfbfSEd Maste     }
1061ac7ddfbfSEd Maste 
1062ac7ddfbfSEd Maste     ~CommandObjectProcessConnect ()
1063ac7ddfbfSEd Maste     {
1064ac7ddfbfSEd Maste     }
1065ac7ddfbfSEd Maste 
1066ac7ddfbfSEd Maste 
1067ac7ddfbfSEd Maste     Options *
1068ac7ddfbfSEd Maste     GetOptions ()
1069ac7ddfbfSEd Maste     {
1070ac7ddfbfSEd Maste         return &m_options;
1071ac7ddfbfSEd Maste     }
1072ac7ddfbfSEd Maste 
1073ac7ddfbfSEd Maste protected:
1074ac7ddfbfSEd Maste     bool
1075ac7ddfbfSEd Maste     DoExecute (Args& command,
1076ac7ddfbfSEd Maste              CommandReturnObject &result)
1077ac7ddfbfSEd Maste     {
1078ac7ddfbfSEd Maste 
1079ac7ddfbfSEd Maste         TargetSP target_sp (m_interpreter.GetDebugger().GetSelectedTarget());
1080ac7ddfbfSEd Maste         Error error;
1081ac7ddfbfSEd Maste         Process *process = m_exe_ctx.GetProcessPtr();
1082ac7ddfbfSEd Maste         if (process)
1083ac7ddfbfSEd Maste         {
1084ac7ddfbfSEd Maste             if (process->IsAlive())
1085ac7ddfbfSEd Maste             {
1086ac7ddfbfSEd Maste                 result.AppendErrorWithFormat ("Process %" PRIu64 " is currently being debugged, kill the process before connecting.\n",
1087ac7ddfbfSEd Maste                                               process->GetID());
1088ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusFailed);
1089ac7ddfbfSEd Maste                 return false;
1090ac7ddfbfSEd Maste             }
1091ac7ddfbfSEd Maste         }
1092ac7ddfbfSEd Maste 
1093ac7ddfbfSEd Maste         if (!target_sp)
1094ac7ddfbfSEd Maste         {
1095ac7ddfbfSEd Maste             // If there isn't a current target create one.
1096ac7ddfbfSEd Maste 
1097ac7ddfbfSEd Maste             error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(),
1098ac7ddfbfSEd Maste                                                                               NULL,
1099ac7ddfbfSEd Maste                                                                               NULL,
1100ac7ddfbfSEd Maste                                                                               false,
1101ac7ddfbfSEd Maste                                                                               NULL, // No platform options
1102ac7ddfbfSEd Maste                                                                               target_sp);
1103ac7ddfbfSEd Maste             if (!target_sp || error.Fail())
1104ac7ddfbfSEd Maste             {
1105ac7ddfbfSEd Maste                 result.AppendError(error.AsCString("Error creating target"));
1106ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusFailed);
1107ac7ddfbfSEd Maste                 return false;
1108ac7ddfbfSEd Maste             }
1109ac7ddfbfSEd Maste             m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target_sp.get());
1110ac7ddfbfSEd Maste         }
1111ac7ddfbfSEd Maste 
1112ac7ddfbfSEd Maste         if (command.GetArgumentCount() == 1)
1113ac7ddfbfSEd Maste         {
1114ac7ddfbfSEd Maste             const char *plugin_name = NULL;
1115ac7ddfbfSEd Maste             if (!m_options.plugin_name.empty())
1116ac7ddfbfSEd Maste                 plugin_name = m_options.plugin_name.c_str();
1117ac7ddfbfSEd Maste 
1118ac7ddfbfSEd Maste             const char *remote_url = command.GetArgumentAtIndex(0);
1119ac7ddfbfSEd Maste             process = target_sp->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name, NULL).get();
1120ac7ddfbfSEd Maste 
1121ac7ddfbfSEd Maste             if (process)
1122ac7ddfbfSEd Maste             {
112312b93ac6SEd Maste                 error = process->ConnectRemote (process->GetTarget().GetDebugger().GetOutputFile().get(), remote_url);
1124ac7ddfbfSEd Maste 
1125ac7ddfbfSEd Maste                 if (error.Fail())
1126ac7ddfbfSEd Maste                 {
1127ac7ddfbfSEd Maste                     result.AppendError(error.AsCString("Remote connect failed"));
1128ac7ddfbfSEd Maste                     result.SetStatus (eReturnStatusFailed);
1129ac7ddfbfSEd Maste                     target_sp->DeleteCurrentProcess();
1130ac7ddfbfSEd Maste                     return false;
1131ac7ddfbfSEd Maste                 }
1132ac7ddfbfSEd Maste             }
1133ac7ddfbfSEd Maste             else
1134ac7ddfbfSEd Maste             {
1135ac7ddfbfSEd Maste                 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",
1136ac7ddfbfSEd Maste                                               remote_url);
1137ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusFailed);
1138ac7ddfbfSEd Maste             }
1139ac7ddfbfSEd Maste         }
1140ac7ddfbfSEd Maste         else
1141ac7ddfbfSEd Maste         {
1142ac7ddfbfSEd Maste             result.AppendErrorWithFormat ("'%s' takes exactly one argument:\nUsage: %s\n",
1143ac7ddfbfSEd Maste                                           m_cmd_name.c_str(),
1144ac7ddfbfSEd Maste                                           m_cmd_syntax.c_str());
1145ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
1146ac7ddfbfSEd Maste         }
1147ac7ddfbfSEd Maste         return result.Succeeded();
1148ac7ddfbfSEd Maste     }
1149ac7ddfbfSEd Maste 
1150ac7ddfbfSEd Maste     CommandOptions m_options;
1151ac7ddfbfSEd Maste };
1152ac7ddfbfSEd Maste 
1153ac7ddfbfSEd Maste OptionDefinition
1154ac7ddfbfSEd Maste CommandObjectProcessConnect::CommandOptions::g_option_table[] =
1155ac7ddfbfSEd Maste {
11560127ef0fSEd Maste     { LLDB_OPT_SET_ALL, false, "plugin", 'p', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."},
11570127ef0fSEd Maste     { 0,                false, NULL,      0 , 0,                 NULL, NULL, 0, eArgTypeNone,   NULL }
1158ac7ddfbfSEd Maste };
1159ac7ddfbfSEd Maste 
1160ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1161ac7ddfbfSEd Maste // CommandObjectProcessPlugin
1162ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1163ac7ddfbfSEd Maste #pragma mark CommandObjectProcessPlugin
1164ac7ddfbfSEd Maste 
1165ac7ddfbfSEd Maste class CommandObjectProcessPlugin : public CommandObjectProxy
1166ac7ddfbfSEd Maste {
1167ac7ddfbfSEd Maste public:
1168ac7ddfbfSEd Maste 
1169ac7ddfbfSEd Maste     CommandObjectProcessPlugin (CommandInterpreter &interpreter) :
1170ac7ddfbfSEd Maste         CommandObjectProxy (interpreter,
1171ac7ddfbfSEd Maste                             "process plugin",
1172ac7ddfbfSEd Maste                             "Send a custom command to the current process plug-in.",
1173ac7ddfbfSEd Maste                             "process plugin <args>",
1174ac7ddfbfSEd Maste                             0)
1175ac7ddfbfSEd Maste     {
1176ac7ddfbfSEd Maste     }
1177ac7ddfbfSEd Maste 
1178ac7ddfbfSEd Maste     ~CommandObjectProcessPlugin ()
1179ac7ddfbfSEd Maste     {
1180ac7ddfbfSEd Maste     }
1181ac7ddfbfSEd Maste 
1182ac7ddfbfSEd Maste     virtual CommandObject *
1183ac7ddfbfSEd Maste     GetProxyCommandObject()
1184ac7ddfbfSEd Maste     {
1185ac7ddfbfSEd Maste         Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
1186ac7ddfbfSEd Maste         if (process)
1187ac7ddfbfSEd Maste             return process->GetPluginCommandObject();
1188ac7ddfbfSEd Maste         return NULL;
1189ac7ddfbfSEd Maste     }
1190ac7ddfbfSEd Maste };
1191ac7ddfbfSEd Maste 
1192ac7ddfbfSEd Maste 
1193ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1194ac7ddfbfSEd Maste // CommandObjectProcessLoad
1195ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1196ac7ddfbfSEd Maste #pragma mark CommandObjectProcessLoad
1197ac7ddfbfSEd Maste 
1198ac7ddfbfSEd Maste class CommandObjectProcessLoad : public CommandObjectParsed
1199ac7ddfbfSEd Maste {
1200ac7ddfbfSEd Maste public:
1201ac7ddfbfSEd Maste 
1202ac7ddfbfSEd Maste     CommandObjectProcessLoad (CommandInterpreter &interpreter) :
1203ac7ddfbfSEd Maste         CommandObjectParsed (interpreter,
1204ac7ddfbfSEd Maste                              "process load",
1205ac7ddfbfSEd Maste                              "Load a shared library into the current process.",
1206ac7ddfbfSEd Maste                              "process load <filename> [<filename> ...]",
1207ac7ddfbfSEd Maste                              eFlagRequiresProcess       |
1208ac7ddfbfSEd Maste                              eFlagTryTargetAPILock      |
1209ac7ddfbfSEd Maste                              eFlagProcessMustBeLaunched |
1210ac7ddfbfSEd Maste                              eFlagProcessMustBePaused   )
1211ac7ddfbfSEd Maste     {
1212ac7ddfbfSEd Maste     }
1213ac7ddfbfSEd Maste 
1214ac7ddfbfSEd Maste     ~CommandObjectProcessLoad ()
1215ac7ddfbfSEd Maste     {
1216ac7ddfbfSEd Maste     }
1217ac7ddfbfSEd Maste 
1218ac7ddfbfSEd Maste protected:
1219ac7ddfbfSEd Maste     bool
1220ac7ddfbfSEd Maste     DoExecute (Args& command,
1221ac7ddfbfSEd Maste              CommandReturnObject &result)
1222ac7ddfbfSEd Maste     {
1223ac7ddfbfSEd Maste         Process *process = m_exe_ctx.GetProcessPtr();
1224ac7ddfbfSEd Maste 
1225ac7ddfbfSEd Maste         const size_t argc = command.GetArgumentCount();
1226ac7ddfbfSEd Maste 
1227ac7ddfbfSEd Maste         for (uint32_t i=0; i<argc; ++i)
1228ac7ddfbfSEd Maste         {
1229ac7ddfbfSEd Maste             Error error;
1230ac7ddfbfSEd Maste             const char *image_path = command.GetArgumentAtIndex(i);
1231ac7ddfbfSEd Maste             FileSpec image_spec (image_path, false);
1232ac7ddfbfSEd Maste             process->GetTarget().GetPlatform()->ResolveRemotePath(image_spec, image_spec);
1233ac7ddfbfSEd Maste             uint32_t image_token = process->LoadImage(image_spec, error);
1234ac7ddfbfSEd Maste             if (image_token != LLDB_INVALID_IMAGE_TOKEN)
1235ac7ddfbfSEd Maste             {
1236ac7ddfbfSEd Maste                 result.AppendMessageWithFormat ("Loading \"%s\"...ok\nImage %u loaded.\n", image_path, image_token);
1237ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusSuccessFinishResult);
1238ac7ddfbfSEd Maste             }
1239ac7ddfbfSEd Maste             else
1240ac7ddfbfSEd Maste             {
1241ac7ddfbfSEd Maste                 result.AppendErrorWithFormat ("failed to load '%s': %s", image_path, error.AsCString());
1242ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusFailed);
1243ac7ddfbfSEd Maste             }
1244ac7ddfbfSEd Maste         }
1245ac7ddfbfSEd Maste         return result.Succeeded();
1246ac7ddfbfSEd Maste     }
1247ac7ddfbfSEd Maste };
1248ac7ddfbfSEd Maste 
1249ac7ddfbfSEd Maste 
1250ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1251ac7ddfbfSEd Maste // CommandObjectProcessUnload
1252ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1253ac7ddfbfSEd Maste #pragma mark CommandObjectProcessUnload
1254ac7ddfbfSEd Maste 
1255ac7ddfbfSEd Maste class CommandObjectProcessUnload : public CommandObjectParsed
1256ac7ddfbfSEd Maste {
1257ac7ddfbfSEd Maste public:
1258ac7ddfbfSEd Maste 
1259ac7ddfbfSEd Maste     CommandObjectProcessUnload (CommandInterpreter &interpreter) :
1260ac7ddfbfSEd Maste         CommandObjectParsed (interpreter,
1261ac7ddfbfSEd Maste                              "process unload",
1262ac7ddfbfSEd Maste                              "Unload a shared library from the current process using the index returned by a previous call to \"process load\".",
1263ac7ddfbfSEd Maste                              "process unload <index>",
1264ac7ddfbfSEd Maste                              eFlagRequiresProcess       |
1265ac7ddfbfSEd Maste                              eFlagTryTargetAPILock      |
1266ac7ddfbfSEd Maste                              eFlagProcessMustBeLaunched |
1267ac7ddfbfSEd Maste                              eFlagProcessMustBePaused   )
1268ac7ddfbfSEd Maste     {
1269ac7ddfbfSEd Maste     }
1270ac7ddfbfSEd Maste 
1271ac7ddfbfSEd Maste     ~CommandObjectProcessUnload ()
1272ac7ddfbfSEd Maste     {
1273ac7ddfbfSEd Maste     }
1274ac7ddfbfSEd Maste 
1275ac7ddfbfSEd Maste protected:
1276ac7ddfbfSEd Maste     bool
1277ac7ddfbfSEd Maste     DoExecute (Args& command,
1278ac7ddfbfSEd Maste              CommandReturnObject &result)
1279ac7ddfbfSEd Maste     {
1280ac7ddfbfSEd Maste         Process *process = m_exe_ctx.GetProcessPtr();
1281ac7ddfbfSEd Maste 
1282ac7ddfbfSEd Maste         const size_t argc = command.GetArgumentCount();
1283ac7ddfbfSEd Maste 
1284ac7ddfbfSEd Maste         for (uint32_t i=0; i<argc; ++i)
1285ac7ddfbfSEd Maste         {
1286ac7ddfbfSEd Maste             const char *image_token_cstr = command.GetArgumentAtIndex(i);
1287ac7ddfbfSEd Maste             uint32_t image_token = Args::StringToUInt32(image_token_cstr, LLDB_INVALID_IMAGE_TOKEN, 0);
1288ac7ddfbfSEd Maste             if (image_token == LLDB_INVALID_IMAGE_TOKEN)
1289ac7ddfbfSEd Maste             {
1290ac7ddfbfSEd Maste                 result.AppendErrorWithFormat ("invalid image index argument '%s'", image_token_cstr);
1291ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusFailed);
1292ac7ddfbfSEd Maste                 break;
1293ac7ddfbfSEd Maste             }
1294ac7ddfbfSEd Maste             else
1295ac7ddfbfSEd Maste             {
1296ac7ddfbfSEd Maste                 Error error (process->UnloadImage(image_token));
1297ac7ddfbfSEd Maste                 if (error.Success())
1298ac7ddfbfSEd Maste                 {
1299ac7ddfbfSEd Maste                     result.AppendMessageWithFormat ("Unloading shared library with index %u...ok\n", image_token);
1300ac7ddfbfSEd Maste                     result.SetStatus (eReturnStatusSuccessFinishResult);
1301ac7ddfbfSEd Maste                 }
1302ac7ddfbfSEd Maste                 else
1303ac7ddfbfSEd Maste                 {
1304ac7ddfbfSEd Maste                     result.AppendErrorWithFormat ("failed to unload image: %s", error.AsCString());
1305ac7ddfbfSEd Maste                     result.SetStatus (eReturnStatusFailed);
1306ac7ddfbfSEd Maste                     break;
1307ac7ddfbfSEd Maste                 }
1308ac7ddfbfSEd Maste             }
1309ac7ddfbfSEd Maste         }
1310ac7ddfbfSEd Maste         return result.Succeeded();
1311ac7ddfbfSEd Maste     }
1312ac7ddfbfSEd Maste };
1313ac7ddfbfSEd Maste 
1314ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1315ac7ddfbfSEd Maste // CommandObjectProcessSignal
1316ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1317ac7ddfbfSEd Maste #pragma mark CommandObjectProcessSignal
1318ac7ddfbfSEd Maste 
1319ac7ddfbfSEd Maste class CommandObjectProcessSignal : public CommandObjectParsed
1320ac7ddfbfSEd Maste {
1321ac7ddfbfSEd Maste public:
1322ac7ddfbfSEd Maste 
1323ac7ddfbfSEd Maste     CommandObjectProcessSignal (CommandInterpreter &interpreter) :
1324ac7ddfbfSEd Maste         CommandObjectParsed (interpreter,
1325ac7ddfbfSEd Maste                              "process signal",
1326ac7ddfbfSEd Maste                              "Send a UNIX signal to the current process being debugged.",
1327ac7ddfbfSEd Maste                              NULL,
1328ac7ddfbfSEd Maste                              eFlagRequiresProcess | eFlagTryTargetAPILock)
1329ac7ddfbfSEd Maste     {
1330ac7ddfbfSEd Maste         CommandArgumentEntry arg;
1331ac7ddfbfSEd Maste         CommandArgumentData signal_arg;
1332ac7ddfbfSEd Maste 
1333ac7ddfbfSEd Maste         // Define the first (and only) variant of this arg.
1334ac7ddfbfSEd Maste         signal_arg.arg_type = eArgTypeUnixSignal;
1335ac7ddfbfSEd Maste         signal_arg.arg_repetition = eArgRepeatPlain;
1336ac7ddfbfSEd Maste 
1337ac7ddfbfSEd Maste         // There is only one variant this argument could be; put it into the argument entry.
1338ac7ddfbfSEd Maste         arg.push_back (signal_arg);
1339ac7ddfbfSEd Maste 
1340ac7ddfbfSEd Maste         // Push the data for the first argument into the m_arguments vector.
1341ac7ddfbfSEd Maste         m_arguments.push_back (arg);
1342ac7ddfbfSEd Maste     }
1343ac7ddfbfSEd Maste 
1344ac7ddfbfSEd Maste     ~CommandObjectProcessSignal ()
1345ac7ddfbfSEd Maste     {
1346ac7ddfbfSEd Maste     }
1347ac7ddfbfSEd Maste 
1348ac7ddfbfSEd Maste protected:
1349ac7ddfbfSEd Maste     bool
1350ac7ddfbfSEd Maste     DoExecute (Args& command,
1351ac7ddfbfSEd Maste              CommandReturnObject &result)
1352ac7ddfbfSEd Maste     {
1353ac7ddfbfSEd Maste         Process *process = m_exe_ctx.GetProcessPtr();
1354ac7ddfbfSEd Maste 
1355ac7ddfbfSEd Maste         if (command.GetArgumentCount() == 1)
1356ac7ddfbfSEd Maste         {
1357ac7ddfbfSEd Maste             int signo = LLDB_INVALID_SIGNAL_NUMBER;
1358ac7ddfbfSEd Maste 
1359ac7ddfbfSEd Maste             const char *signal_name = command.GetArgumentAtIndex(0);
1360ac7ddfbfSEd Maste             if (::isxdigit (signal_name[0]))
1361ac7ddfbfSEd Maste                 signo = Args::StringToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0);
1362ac7ddfbfSEd Maste             else
1363ac7ddfbfSEd Maste                 signo = process->GetUnixSignals().GetSignalNumberFromName (signal_name);
1364ac7ddfbfSEd Maste 
1365ac7ddfbfSEd Maste             if (signo == LLDB_INVALID_SIGNAL_NUMBER)
1366ac7ddfbfSEd Maste             {
1367ac7ddfbfSEd Maste                 result.AppendErrorWithFormat ("Invalid signal argument '%s'.\n", command.GetArgumentAtIndex(0));
1368ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusFailed);
1369ac7ddfbfSEd Maste             }
1370ac7ddfbfSEd Maste             else
1371ac7ddfbfSEd Maste             {
1372ac7ddfbfSEd Maste                 Error error (process->Signal (signo));
1373ac7ddfbfSEd Maste                 if (error.Success())
1374ac7ddfbfSEd Maste                 {
1375ac7ddfbfSEd Maste                     result.SetStatus (eReturnStatusSuccessFinishResult);
1376ac7ddfbfSEd Maste                 }
1377ac7ddfbfSEd Maste                 else
1378ac7ddfbfSEd Maste                 {
1379ac7ddfbfSEd Maste                     result.AppendErrorWithFormat ("Failed to send signal %i: %s\n", signo, error.AsCString());
1380ac7ddfbfSEd Maste                     result.SetStatus (eReturnStatusFailed);
1381ac7ddfbfSEd Maste                 }
1382ac7ddfbfSEd Maste             }
1383ac7ddfbfSEd Maste         }
1384ac7ddfbfSEd Maste         else
1385ac7ddfbfSEd Maste         {
1386ac7ddfbfSEd Maste             result.AppendErrorWithFormat("'%s' takes exactly one signal number argument:\nUsage: %s\n", m_cmd_name.c_str(),
1387ac7ddfbfSEd Maste                                         m_cmd_syntax.c_str());
1388ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
1389ac7ddfbfSEd Maste         }
1390ac7ddfbfSEd Maste         return result.Succeeded();
1391ac7ddfbfSEd Maste     }
1392ac7ddfbfSEd Maste };
1393ac7ddfbfSEd Maste 
1394ac7ddfbfSEd Maste 
1395ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1396ac7ddfbfSEd Maste // CommandObjectProcessInterrupt
1397ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1398ac7ddfbfSEd Maste #pragma mark CommandObjectProcessInterrupt
1399ac7ddfbfSEd Maste 
1400ac7ddfbfSEd Maste class CommandObjectProcessInterrupt : public CommandObjectParsed
1401ac7ddfbfSEd Maste {
1402ac7ddfbfSEd Maste public:
1403ac7ddfbfSEd Maste 
1404ac7ddfbfSEd Maste 
1405ac7ddfbfSEd Maste     CommandObjectProcessInterrupt (CommandInterpreter &interpreter) :
1406ac7ddfbfSEd Maste         CommandObjectParsed (interpreter,
1407ac7ddfbfSEd Maste                              "process interrupt",
1408ac7ddfbfSEd Maste                              "Interrupt the current process being debugged.",
1409ac7ddfbfSEd Maste                              "process interrupt",
1410ac7ddfbfSEd Maste                              eFlagRequiresProcess      |
1411ac7ddfbfSEd Maste                              eFlagTryTargetAPILock     |
1412ac7ddfbfSEd Maste                              eFlagProcessMustBeLaunched)
1413ac7ddfbfSEd Maste     {
1414ac7ddfbfSEd Maste     }
1415ac7ddfbfSEd Maste 
1416ac7ddfbfSEd Maste     ~CommandObjectProcessInterrupt ()
1417ac7ddfbfSEd Maste     {
1418ac7ddfbfSEd Maste     }
1419ac7ddfbfSEd Maste 
1420ac7ddfbfSEd Maste protected:
1421ac7ddfbfSEd Maste     bool
1422ac7ddfbfSEd Maste     DoExecute (Args& command,
1423ac7ddfbfSEd Maste                CommandReturnObject &result)
1424ac7ddfbfSEd Maste     {
1425ac7ddfbfSEd Maste         Process *process = m_exe_ctx.GetProcessPtr();
1426ac7ddfbfSEd Maste         if (process == NULL)
1427ac7ddfbfSEd Maste         {
1428ac7ddfbfSEd Maste             result.AppendError ("no process to halt");
1429ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
1430ac7ddfbfSEd Maste             return false;
1431ac7ddfbfSEd Maste         }
1432ac7ddfbfSEd Maste 
1433ac7ddfbfSEd Maste         if (command.GetArgumentCount() == 0)
1434ac7ddfbfSEd Maste         {
1435ac7ddfbfSEd Maste             bool clear_thread_plans = true;
1436ac7ddfbfSEd Maste             Error error(process->Halt (clear_thread_plans));
1437ac7ddfbfSEd Maste             if (error.Success())
1438ac7ddfbfSEd Maste             {
1439ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusSuccessFinishResult);
1440ac7ddfbfSEd Maste             }
1441ac7ddfbfSEd Maste             else
1442ac7ddfbfSEd Maste             {
1443ac7ddfbfSEd Maste                 result.AppendErrorWithFormat ("Failed to halt process: %s\n", error.AsCString());
1444ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusFailed);
1445ac7ddfbfSEd Maste             }
1446ac7ddfbfSEd Maste         }
1447ac7ddfbfSEd Maste         else
1448ac7ddfbfSEd Maste         {
1449ac7ddfbfSEd Maste             result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n",
1450ac7ddfbfSEd Maste                                         m_cmd_name.c_str(),
1451ac7ddfbfSEd Maste                                         m_cmd_syntax.c_str());
1452ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
1453ac7ddfbfSEd Maste         }
1454ac7ddfbfSEd Maste         return result.Succeeded();
1455ac7ddfbfSEd Maste     }
1456ac7ddfbfSEd Maste };
1457ac7ddfbfSEd Maste 
1458ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1459ac7ddfbfSEd Maste // CommandObjectProcessKill
1460ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1461ac7ddfbfSEd Maste #pragma mark CommandObjectProcessKill
1462ac7ddfbfSEd Maste 
1463ac7ddfbfSEd Maste class CommandObjectProcessKill : public CommandObjectParsed
1464ac7ddfbfSEd Maste {
1465ac7ddfbfSEd Maste public:
1466ac7ddfbfSEd Maste 
1467ac7ddfbfSEd Maste     CommandObjectProcessKill (CommandInterpreter &interpreter) :
1468ac7ddfbfSEd Maste         CommandObjectParsed (interpreter,
1469ac7ddfbfSEd Maste                              "process kill",
1470ac7ddfbfSEd Maste                              "Terminate the current process being debugged.",
1471ac7ddfbfSEd Maste                              "process kill",
1472ac7ddfbfSEd Maste                              eFlagRequiresProcess      |
1473ac7ddfbfSEd Maste                              eFlagTryTargetAPILock     |
1474ac7ddfbfSEd Maste                              eFlagProcessMustBeLaunched)
1475ac7ddfbfSEd Maste     {
1476ac7ddfbfSEd Maste     }
1477ac7ddfbfSEd Maste 
1478ac7ddfbfSEd Maste     ~CommandObjectProcessKill ()
1479ac7ddfbfSEd Maste     {
1480ac7ddfbfSEd Maste     }
1481ac7ddfbfSEd Maste 
1482ac7ddfbfSEd Maste protected:
1483ac7ddfbfSEd Maste     bool
1484ac7ddfbfSEd Maste     DoExecute (Args& command,
1485ac7ddfbfSEd Maste              CommandReturnObject &result)
1486ac7ddfbfSEd Maste     {
1487ac7ddfbfSEd Maste         Process *process = m_exe_ctx.GetProcessPtr();
1488ac7ddfbfSEd Maste         if (process == NULL)
1489ac7ddfbfSEd Maste         {
1490ac7ddfbfSEd Maste             result.AppendError ("no process to kill");
1491ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
1492ac7ddfbfSEd Maste             return false;
1493ac7ddfbfSEd Maste         }
1494ac7ddfbfSEd Maste 
1495ac7ddfbfSEd Maste         if (command.GetArgumentCount() == 0)
1496ac7ddfbfSEd Maste         {
1497ac7ddfbfSEd Maste             Error error (process->Destroy());
1498ac7ddfbfSEd Maste             if (error.Success())
1499ac7ddfbfSEd Maste             {
1500ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusSuccessFinishResult);
1501ac7ddfbfSEd Maste             }
1502ac7ddfbfSEd Maste             else
1503ac7ddfbfSEd Maste             {
1504ac7ddfbfSEd Maste                 result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString());
1505ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusFailed);
1506ac7ddfbfSEd Maste             }
1507ac7ddfbfSEd Maste         }
1508ac7ddfbfSEd Maste         else
1509ac7ddfbfSEd Maste         {
1510ac7ddfbfSEd Maste             result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n",
1511ac7ddfbfSEd Maste                                         m_cmd_name.c_str(),
1512ac7ddfbfSEd Maste                                         m_cmd_syntax.c_str());
1513ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
1514ac7ddfbfSEd Maste         }
1515ac7ddfbfSEd Maste         return result.Succeeded();
1516ac7ddfbfSEd Maste     }
1517ac7ddfbfSEd Maste };
1518ac7ddfbfSEd Maste 
1519ac7ddfbfSEd Maste //-------------------------------------------------------------------------
15200127ef0fSEd Maste // CommandObjectProcessSaveCore
15210127ef0fSEd Maste //-------------------------------------------------------------------------
15220127ef0fSEd Maste #pragma mark CommandObjectProcessSaveCore
15230127ef0fSEd Maste 
15240127ef0fSEd Maste class CommandObjectProcessSaveCore : public CommandObjectParsed
15250127ef0fSEd Maste {
15260127ef0fSEd Maste public:
15270127ef0fSEd Maste 
15280127ef0fSEd Maste     CommandObjectProcessSaveCore (CommandInterpreter &interpreter) :
15290127ef0fSEd Maste     CommandObjectParsed (interpreter,
15300127ef0fSEd Maste                          "process save-core",
15310127ef0fSEd Maste                          "Save the current process as a core file using an appropriate file type.",
15320127ef0fSEd Maste                          "process save-core FILE",
15330127ef0fSEd Maste                          eFlagRequiresProcess      |
15340127ef0fSEd Maste                          eFlagTryTargetAPILock     |
15350127ef0fSEd Maste                          eFlagProcessMustBeLaunched)
15360127ef0fSEd Maste     {
15370127ef0fSEd Maste     }
15380127ef0fSEd Maste 
15390127ef0fSEd Maste     ~CommandObjectProcessSaveCore ()
15400127ef0fSEd Maste     {
15410127ef0fSEd Maste     }
15420127ef0fSEd Maste 
15430127ef0fSEd Maste protected:
15440127ef0fSEd Maste     bool
15450127ef0fSEd Maste     DoExecute (Args& command,
15460127ef0fSEd Maste                CommandReturnObject &result)
15470127ef0fSEd Maste     {
15480127ef0fSEd Maste         ProcessSP process_sp = m_exe_ctx.GetProcessSP();
15490127ef0fSEd Maste         if (process_sp)
15500127ef0fSEd Maste         {
15510127ef0fSEd Maste             if (command.GetArgumentCount() == 1)
15520127ef0fSEd Maste             {
15530127ef0fSEd Maste                 FileSpec output_file(command.GetArgumentAtIndex(0), false);
15540127ef0fSEd Maste                 Error error = PluginManager::SaveCore(process_sp, output_file);
15550127ef0fSEd Maste                 if (error.Success())
15560127ef0fSEd Maste                 {
15570127ef0fSEd Maste                     result.SetStatus (eReturnStatusSuccessFinishResult);
15580127ef0fSEd Maste                 }
15590127ef0fSEd Maste                 else
15600127ef0fSEd Maste                 {
15610127ef0fSEd Maste                     result.AppendErrorWithFormat ("Failed to save core file for process: %s\n", error.AsCString());
15620127ef0fSEd Maste                     result.SetStatus (eReturnStatusFailed);
15630127ef0fSEd Maste                 }
15640127ef0fSEd Maste             }
15650127ef0fSEd Maste             else
15660127ef0fSEd Maste             {
15670127ef0fSEd Maste                 result.AppendErrorWithFormat ("'%s' takes one arguments:\nUsage: %s\n",
15680127ef0fSEd Maste                                               m_cmd_name.c_str(),
15690127ef0fSEd Maste                                               m_cmd_syntax.c_str());
15700127ef0fSEd Maste                 result.SetStatus (eReturnStatusFailed);
15710127ef0fSEd Maste             }
15720127ef0fSEd Maste         }
15730127ef0fSEd Maste         else
15740127ef0fSEd Maste         {
15750127ef0fSEd Maste             result.AppendError ("invalid process");
15760127ef0fSEd Maste             result.SetStatus (eReturnStatusFailed);
15770127ef0fSEd Maste             return false;
15780127ef0fSEd Maste         }
15790127ef0fSEd Maste 
15800127ef0fSEd Maste         return result.Succeeded();
15810127ef0fSEd Maste     }
15820127ef0fSEd Maste };
15830127ef0fSEd Maste 
15840127ef0fSEd Maste //-------------------------------------------------------------------------
1585ac7ddfbfSEd Maste // CommandObjectProcessStatus
1586ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1587ac7ddfbfSEd Maste #pragma mark CommandObjectProcessStatus
1588ac7ddfbfSEd Maste 
1589ac7ddfbfSEd Maste class CommandObjectProcessStatus : public CommandObjectParsed
1590ac7ddfbfSEd Maste {
1591ac7ddfbfSEd Maste public:
1592ac7ddfbfSEd Maste     CommandObjectProcessStatus (CommandInterpreter &interpreter) :
1593ac7ddfbfSEd Maste         CommandObjectParsed (interpreter,
1594ac7ddfbfSEd Maste                              "process status",
1595ac7ddfbfSEd Maste                              "Show the current status and location of executing process.",
1596ac7ddfbfSEd Maste                              "process status",
1597ac7ddfbfSEd Maste                              eFlagRequiresProcess | eFlagTryTargetAPILock)
1598ac7ddfbfSEd Maste     {
1599ac7ddfbfSEd Maste     }
1600ac7ddfbfSEd Maste 
1601ac7ddfbfSEd Maste     ~CommandObjectProcessStatus()
1602ac7ddfbfSEd Maste     {
1603ac7ddfbfSEd Maste     }
1604ac7ddfbfSEd Maste 
1605ac7ddfbfSEd Maste 
1606ac7ddfbfSEd Maste     bool
1607ac7ddfbfSEd Maste     DoExecute (Args& command, CommandReturnObject &result)
1608ac7ddfbfSEd Maste     {
1609ac7ddfbfSEd Maste         Stream &strm = result.GetOutputStream();
1610ac7ddfbfSEd Maste         result.SetStatus (eReturnStatusSuccessFinishNoResult);
1611ac7ddfbfSEd Maste         // No need to check "process" for validity as eFlagRequiresProcess ensures it is valid
1612ac7ddfbfSEd Maste         Process *process = m_exe_ctx.GetProcessPtr();
1613ac7ddfbfSEd Maste         const bool only_threads_with_stop_reason = true;
1614ac7ddfbfSEd Maste         const uint32_t start_frame = 0;
1615ac7ddfbfSEd Maste         const uint32_t num_frames = 1;
1616ac7ddfbfSEd Maste         const uint32_t num_frames_with_source = 1;
1617ac7ddfbfSEd Maste         process->GetStatus(strm);
1618ac7ddfbfSEd Maste         process->GetThreadStatus (strm,
1619ac7ddfbfSEd Maste                                   only_threads_with_stop_reason,
1620ac7ddfbfSEd Maste                                   start_frame,
1621ac7ddfbfSEd Maste                                   num_frames,
1622ac7ddfbfSEd Maste                                   num_frames_with_source);
1623ac7ddfbfSEd Maste         return result.Succeeded();
1624ac7ddfbfSEd Maste     }
1625ac7ddfbfSEd Maste };
1626ac7ddfbfSEd Maste 
1627ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1628ac7ddfbfSEd Maste // CommandObjectProcessHandle
1629ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1630ac7ddfbfSEd Maste #pragma mark CommandObjectProcessHandle
1631ac7ddfbfSEd Maste 
1632ac7ddfbfSEd Maste class CommandObjectProcessHandle : public CommandObjectParsed
1633ac7ddfbfSEd Maste {
1634ac7ddfbfSEd Maste public:
1635ac7ddfbfSEd Maste 
1636ac7ddfbfSEd Maste     class CommandOptions : public Options
1637ac7ddfbfSEd Maste     {
1638ac7ddfbfSEd Maste     public:
1639ac7ddfbfSEd Maste 
1640ac7ddfbfSEd Maste         CommandOptions (CommandInterpreter &interpreter) :
1641ac7ddfbfSEd Maste             Options (interpreter)
1642ac7ddfbfSEd Maste         {
1643ac7ddfbfSEd Maste             OptionParsingStarting ();
1644ac7ddfbfSEd Maste         }
1645ac7ddfbfSEd Maste 
1646ac7ddfbfSEd Maste         ~CommandOptions ()
1647ac7ddfbfSEd Maste         {
1648ac7ddfbfSEd Maste         }
1649ac7ddfbfSEd Maste 
1650ac7ddfbfSEd Maste         Error
1651ac7ddfbfSEd Maste         SetOptionValue (uint32_t option_idx, const char *option_arg)
1652ac7ddfbfSEd Maste         {
1653ac7ddfbfSEd Maste             Error error;
1654ac7ddfbfSEd Maste             const int short_option = m_getopt_table[option_idx].val;
1655ac7ddfbfSEd Maste 
1656ac7ddfbfSEd Maste             switch (short_option)
1657ac7ddfbfSEd Maste             {
1658ac7ddfbfSEd Maste                 case 's':
1659ac7ddfbfSEd Maste                     stop = option_arg;
1660ac7ddfbfSEd Maste                     break;
1661ac7ddfbfSEd Maste                 case 'n':
1662ac7ddfbfSEd Maste                     notify = option_arg;
1663ac7ddfbfSEd Maste                     break;
1664ac7ddfbfSEd Maste                 case 'p':
1665ac7ddfbfSEd Maste                     pass = option_arg;
1666ac7ddfbfSEd Maste                     break;
1667ac7ddfbfSEd Maste                 default:
1668ac7ddfbfSEd Maste                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
1669ac7ddfbfSEd Maste                     break;
1670ac7ddfbfSEd Maste             }
1671ac7ddfbfSEd Maste             return error;
1672ac7ddfbfSEd Maste         }
1673ac7ddfbfSEd Maste 
1674ac7ddfbfSEd Maste         void
1675ac7ddfbfSEd Maste         OptionParsingStarting ()
1676ac7ddfbfSEd Maste         {
1677ac7ddfbfSEd Maste             stop.clear();
1678ac7ddfbfSEd Maste             notify.clear();
1679ac7ddfbfSEd Maste             pass.clear();
1680ac7ddfbfSEd Maste         }
1681ac7ddfbfSEd Maste 
1682ac7ddfbfSEd Maste         const OptionDefinition*
1683ac7ddfbfSEd Maste         GetDefinitions ()
1684ac7ddfbfSEd Maste         {
1685ac7ddfbfSEd Maste             return g_option_table;
1686ac7ddfbfSEd Maste         }
1687ac7ddfbfSEd Maste 
1688ac7ddfbfSEd Maste         // Options table: Required for subclasses of Options.
1689ac7ddfbfSEd Maste 
1690ac7ddfbfSEd Maste         static OptionDefinition g_option_table[];
1691ac7ddfbfSEd Maste 
1692ac7ddfbfSEd Maste         // Instance variables to hold the values for command options.
1693ac7ddfbfSEd Maste 
1694ac7ddfbfSEd Maste         std::string stop;
1695ac7ddfbfSEd Maste         std::string notify;
1696ac7ddfbfSEd Maste         std::string pass;
1697ac7ddfbfSEd Maste     };
1698ac7ddfbfSEd Maste 
1699ac7ddfbfSEd Maste 
1700ac7ddfbfSEd Maste     CommandObjectProcessHandle (CommandInterpreter &interpreter) :
1701ac7ddfbfSEd Maste         CommandObjectParsed (interpreter,
1702ac7ddfbfSEd Maste                              "process handle",
1703ac7ddfbfSEd Maste                              "Show or update what the process and debugger should do with various signals received from the OS.",
1704ac7ddfbfSEd Maste                              NULL),
1705ac7ddfbfSEd Maste         m_options (interpreter)
1706ac7ddfbfSEd Maste     {
1707ac7ddfbfSEd Maste         SetHelpLong ("If no signals are specified, update them all.  If no update option is specified, list the current values.\n");
1708ac7ddfbfSEd Maste         CommandArgumentEntry arg;
1709ac7ddfbfSEd Maste         CommandArgumentData signal_arg;
1710ac7ddfbfSEd Maste 
1711ac7ddfbfSEd Maste         signal_arg.arg_type = eArgTypeUnixSignal;
1712ac7ddfbfSEd Maste         signal_arg.arg_repetition = eArgRepeatStar;
1713ac7ddfbfSEd Maste 
1714ac7ddfbfSEd Maste         arg.push_back (signal_arg);
1715ac7ddfbfSEd Maste 
1716ac7ddfbfSEd Maste         m_arguments.push_back (arg);
1717ac7ddfbfSEd Maste     }
1718ac7ddfbfSEd Maste 
1719ac7ddfbfSEd Maste     ~CommandObjectProcessHandle ()
1720ac7ddfbfSEd Maste     {
1721ac7ddfbfSEd Maste     }
1722ac7ddfbfSEd Maste 
1723ac7ddfbfSEd Maste     Options *
1724ac7ddfbfSEd Maste     GetOptions ()
1725ac7ddfbfSEd Maste     {
1726ac7ddfbfSEd Maste         return &m_options;
1727ac7ddfbfSEd Maste     }
1728ac7ddfbfSEd Maste 
1729ac7ddfbfSEd Maste     bool
1730ac7ddfbfSEd Maste     VerifyCommandOptionValue (const std::string &option, int &real_value)
1731ac7ddfbfSEd Maste     {
1732ac7ddfbfSEd Maste         bool okay = true;
1733ac7ddfbfSEd Maste 
1734ac7ddfbfSEd Maste         bool success = false;
1735ac7ddfbfSEd Maste         bool tmp_value = Args::StringToBoolean (option.c_str(), false, &success);
1736ac7ddfbfSEd Maste 
1737ac7ddfbfSEd Maste         if (success && tmp_value)
1738ac7ddfbfSEd Maste             real_value = 1;
1739ac7ddfbfSEd Maste         else if (success && !tmp_value)
1740ac7ddfbfSEd Maste             real_value = 0;
1741ac7ddfbfSEd Maste         else
1742ac7ddfbfSEd Maste         {
1743ac7ddfbfSEd Maste             // If the value isn't 'true' or 'false', it had better be 0 or 1.
1744ac7ddfbfSEd Maste             real_value = Args::StringToUInt32 (option.c_str(), 3);
1745ac7ddfbfSEd Maste             if (real_value != 0 && real_value != 1)
1746ac7ddfbfSEd Maste                 okay = false;
1747ac7ddfbfSEd Maste         }
1748ac7ddfbfSEd Maste 
1749ac7ddfbfSEd Maste         return okay;
1750ac7ddfbfSEd Maste     }
1751ac7ddfbfSEd Maste 
1752ac7ddfbfSEd Maste     void
1753ac7ddfbfSEd Maste     PrintSignalHeader (Stream &str)
1754ac7ddfbfSEd Maste     {
1755ac7ddfbfSEd Maste         str.Printf ("NAME        PASS   STOP   NOTIFY\n");
1756ac7ddfbfSEd Maste         str.Printf ("==========  =====  =====  ======\n");
1757ac7ddfbfSEd Maste     }
1758ac7ddfbfSEd Maste 
1759ac7ddfbfSEd Maste     void
1760ac7ddfbfSEd Maste     PrintSignal (Stream &str, int32_t signo, const char *sig_name, UnixSignals &signals)
1761ac7ddfbfSEd Maste     {
1762ac7ddfbfSEd Maste         bool stop;
1763ac7ddfbfSEd Maste         bool suppress;
1764ac7ddfbfSEd Maste         bool notify;
1765ac7ddfbfSEd Maste 
1766ac7ddfbfSEd Maste         str.Printf ("%-10s  ", sig_name);
1767ac7ddfbfSEd Maste         if (signals.GetSignalInfo (signo, suppress, stop, notify))
1768ac7ddfbfSEd Maste         {
1769ac7ddfbfSEd Maste             bool pass = !suppress;
1770ac7ddfbfSEd Maste             str.Printf ("%s  %s  %s",
1771ac7ddfbfSEd Maste                         (pass ? "true " : "false"),
1772ac7ddfbfSEd Maste                         (stop ? "true " : "false"),
1773ac7ddfbfSEd Maste                         (notify ? "true " : "false"));
1774ac7ddfbfSEd Maste         }
1775ac7ddfbfSEd Maste         str.Printf ("\n");
1776ac7ddfbfSEd Maste     }
1777ac7ddfbfSEd Maste 
1778ac7ddfbfSEd Maste     void
1779ac7ddfbfSEd Maste     PrintSignalInformation (Stream &str, Args &signal_args, int num_valid_signals, UnixSignals &signals)
1780ac7ddfbfSEd Maste     {
1781ac7ddfbfSEd Maste         PrintSignalHeader (str);
1782ac7ddfbfSEd Maste 
1783ac7ddfbfSEd Maste         if (num_valid_signals > 0)
1784ac7ddfbfSEd Maste         {
1785ac7ddfbfSEd Maste             size_t num_args = signal_args.GetArgumentCount();
1786ac7ddfbfSEd Maste             for (size_t i = 0; i < num_args; ++i)
1787ac7ddfbfSEd Maste             {
1788ac7ddfbfSEd Maste                 int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i));
1789ac7ddfbfSEd Maste                 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
1790ac7ddfbfSEd Maste                     PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals);
1791ac7ddfbfSEd Maste             }
1792ac7ddfbfSEd Maste         }
1793ac7ddfbfSEd Maste         else // Print info for ALL signals
1794ac7ddfbfSEd Maste         {
1795ac7ddfbfSEd Maste             int32_t signo = signals.GetFirstSignalNumber();
1796ac7ddfbfSEd Maste             while (signo != LLDB_INVALID_SIGNAL_NUMBER)
1797ac7ddfbfSEd Maste             {
1798ac7ddfbfSEd Maste                 PrintSignal (str, signo, signals.GetSignalAsCString (signo), signals);
1799ac7ddfbfSEd Maste                 signo = signals.GetNextSignalNumber (signo);
1800ac7ddfbfSEd Maste             }
1801ac7ddfbfSEd Maste         }
1802ac7ddfbfSEd Maste     }
1803ac7ddfbfSEd Maste 
1804ac7ddfbfSEd Maste protected:
1805ac7ddfbfSEd Maste     bool
1806ac7ddfbfSEd Maste     DoExecute (Args &signal_args, CommandReturnObject &result)
1807ac7ddfbfSEd Maste     {
1808ac7ddfbfSEd Maste         TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
1809ac7ddfbfSEd Maste 
1810ac7ddfbfSEd Maste         if (!target_sp)
1811ac7ddfbfSEd Maste         {
1812ac7ddfbfSEd Maste             result.AppendError ("No current target;"
1813ac7ddfbfSEd Maste                                 " cannot handle signals until you have a valid target and process.\n");
1814ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
1815ac7ddfbfSEd Maste             return false;
1816ac7ddfbfSEd Maste         }
1817ac7ddfbfSEd Maste 
1818ac7ddfbfSEd Maste         ProcessSP process_sp = target_sp->GetProcessSP();
1819ac7ddfbfSEd Maste 
1820ac7ddfbfSEd Maste         if (!process_sp)
1821ac7ddfbfSEd Maste         {
1822ac7ddfbfSEd Maste             result.AppendError ("No current process; cannot handle signals until you have a valid process.\n");
1823ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
1824ac7ddfbfSEd Maste             return false;
1825ac7ddfbfSEd Maste         }
1826ac7ddfbfSEd Maste 
1827ac7ddfbfSEd Maste         int stop_action = -1;   // -1 means leave the current setting alone
1828ac7ddfbfSEd Maste         int pass_action = -1;   // -1 means leave the current setting alone
1829ac7ddfbfSEd Maste         int notify_action = -1; // -1 means leave the current setting alone
1830ac7ddfbfSEd Maste 
1831ac7ddfbfSEd Maste         if (! m_options.stop.empty()
1832ac7ddfbfSEd Maste             && ! VerifyCommandOptionValue (m_options.stop, stop_action))
1833ac7ddfbfSEd Maste         {
1834ac7ddfbfSEd Maste             result.AppendError ("Invalid argument for command option --stop; must be true or false.\n");
1835ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
1836ac7ddfbfSEd Maste             return false;
1837ac7ddfbfSEd Maste         }
1838ac7ddfbfSEd Maste 
1839ac7ddfbfSEd Maste         if (! m_options.notify.empty()
1840ac7ddfbfSEd Maste             && ! VerifyCommandOptionValue (m_options.notify, notify_action))
1841ac7ddfbfSEd Maste         {
1842ac7ddfbfSEd Maste             result.AppendError ("Invalid argument for command option --notify; must be true or false.\n");
1843ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
1844ac7ddfbfSEd Maste             return false;
1845ac7ddfbfSEd Maste         }
1846ac7ddfbfSEd Maste 
1847ac7ddfbfSEd Maste         if (! m_options.pass.empty()
1848ac7ddfbfSEd Maste             && ! VerifyCommandOptionValue (m_options.pass, pass_action))
1849ac7ddfbfSEd Maste         {
1850ac7ddfbfSEd Maste             result.AppendError ("Invalid argument for command option --pass; must be true or false.\n");
1851ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
1852ac7ddfbfSEd Maste             return false;
1853ac7ddfbfSEd Maste         }
1854ac7ddfbfSEd Maste 
1855ac7ddfbfSEd Maste         size_t num_args = signal_args.GetArgumentCount();
1856ac7ddfbfSEd Maste         UnixSignals &signals = process_sp->GetUnixSignals();
1857ac7ddfbfSEd Maste         int num_signals_set = 0;
1858ac7ddfbfSEd Maste 
1859ac7ddfbfSEd Maste         if (num_args > 0)
1860ac7ddfbfSEd Maste         {
1861ac7ddfbfSEd Maste             for (size_t i = 0; i < num_args; ++i)
1862ac7ddfbfSEd Maste             {
1863ac7ddfbfSEd Maste                 int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i));
1864ac7ddfbfSEd Maste                 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
1865ac7ddfbfSEd Maste                 {
1866ac7ddfbfSEd Maste                     // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees
1867ac7ddfbfSEd Maste                     // the value is either 0 or 1.
1868ac7ddfbfSEd Maste                     if (stop_action != -1)
1869ac7ddfbfSEd Maste                         signals.SetShouldStop (signo, (bool) stop_action);
1870ac7ddfbfSEd Maste                     if (pass_action != -1)
1871ac7ddfbfSEd Maste                     {
1872ac7ddfbfSEd Maste                         bool suppress = ! ((bool) pass_action);
1873ac7ddfbfSEd Maste                         signals.SetShouldSuppress (signo, suppress);
1874ac7ddfbfSEd Maste                     }
1875ac7ddfbfSEd Maste                     if (notify_action != -1)
1876ac7ddfbfSEd Maste                         signals.SetShouldNotify (signo, (bool) notify_action);
1877ac7ddfbfSEd Maste                     ++num_signals_set;
1878ac7ddfbfSEd Maste                 }
1879ac7ddfbfSEd Maste                 else
1880ac7ddfbfSEd Maste                 {
1881ac7ddfbfSEd Maste                     result.AppendErrorWithFormat ("Invalid signal name '%s'\n", signal_args.GetArgumentAtIndex (i));
1882ac7ddfbfSEd Maste                 }
1883ac7ddfbfSEd Maste             }
1884ac7ddfbfSEd Maste         }
1885ac7ddfbfSEd Maste         else
1886ac7ddfbfSEd Maste         {
1887ac7ddfbfSEd Maste             // No signal specified, if any command options were specified, update ALL signals.
1888ac7ddfbfSEd Maste             if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1))
1889ac7ddfbfSEd Maste             {
1890ac7ddfbfSEd Maste                 if (m_interpreter.Confirm ("Do you really want to update all the signals?", false))
1891ac7ddfbfSEd Maste                 {
1892ac7ddfbfSEd Maste                     int32_t signo = signals.GetFirstSignalNumber();
1893ac7ddfbfSEd Maste                     while (signo != LLDB_INVALID_SIGNAL_NUMBER)
1894ac7ddfbfSEd Maste                     {
1895ac7ddfbfSEd Maste                         if (notify_action != -1)
1896ac7ddfbfSEd Maste                             signals.SetShouldNotify (signo, (bool) notify_action);
1897ac7ddfbfSEd Maste                         if (stop_action != -1)
1898ac7ddfbfSEd Maste                             signals.SetShouldStop (signo, (bool) stop_action);
1899ac7ddfbfSEd Maste                         if (pass_action != -1)
1900ac7ddfbfSEd Maste                         {
1901ac7ddfbfSEd Maste                             bool suppress = ! ((bool) pass_action);
1902ac7ddfbfSEd Maste                             signals.SetShouldSuppress (signo, suppress);
1903ac7ddfbfSEd Maste                         }
1904ac7ddfbfSEd Maste                         signo = signals.GetNextSignalNumber (signo);
1905ac7ddfbfSEd Maste                     }
1906ac7ddfbfSEd Maste                 }
1907ac7ddfbfSEd Maste             }
1908ac7ddfbfSEd Maste         }
1909ac7ddfbfSEd Maste 
1910ac7ddfbfSEd Maste         PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals);
1911ac7ddfbfSEd Maste 
1912ac7ddfbfSEd Maste         if (num_signals_set > 0)
1913ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1914ac7ddfbfSEd Maste         else
1915ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
1916ac7ddfbfSEd Maste 
1917ac7ddfbfSEd Maste         return result.Succeeded();
1918ac7ddfbfSEd Maste     }
1919ac7ddfbfSEd Maste 
1920ac7ddfbfSEd Maste     CommandOptions m_options;
1921ac7ddfbfSEd Maste };
1922ac7ddfbfSEd Maste 
1923ac7ddfbfSEd Maste OptionDefinition
1924ac7ddfbfSEd Maste CommandObjectProcessHandle::CommandOptions::g_option_table[] =
1925ac7ddfbfSEd Maste {
19260127ef0fSEd Maste { LLDB_OPT_SET_1, false, "stop",   's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Whether or not the process should be stopped if the signal is received." },
19270127ef0fSEd Maste { LLDB_OPT_SET_1, false, "notify", 'n', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Whether or not the debugger should notify the user if the signal is received." },
19280127ef0fSEd Maste { LLDB_OPT_SET_1, false, "pass",  'p', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." },
19290127ef0fSEd Maste { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
1930ac7ddfbfSEd Maste };
1931ac7ddfbfSEd Maste 
1932ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1933ac7ddfbfSEd Maste // CommandObjectMultiwordProcess
1934ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1935ac7ddfbfSEd Maste 
1936ac7ddfbfSEd Maste CommandObjectMultiwordProcess::CommandObjectMultiwordProcess (CommandInterpreter &interpreter) :
1937ac7ddfbfSEd Maste     CommandObjectMultiword (interpreter,
1938ac7ddfbfSEd Maste                             "process",
1939ac7ddfbfSEd Maste                             "A set of commands for operating on a process.",
1940ac7ddfbfSEd Maste                             "process <subcommand> [<subcommand-options>]")
1941ac7ddfbfSEd Maste {
1942ac7ddfbfSEd Maste     LoadSubCommand ("attach",      CommandObjectSP (new CommandObjectProcessAttach    (interpreter)));
1943ac7ddfbfSEd Maste     LoadSubCommand ("launch",      CommandObjectSP (new CommandObjectProcessLaunch    (interpreter)));
1944ac7ddfbfSEd Maste     LoadSubCommand ("continue",    CommandObjectSP (new CommandObjectProcessContinue  (interpreter)));
1945ac7ddfbfSEd Maste     LoadSubCommand ("connect",     CommandObjectSP (new CommandObjectProcessConnect   (interpreter)));
1946ac7ddfbfSEd Maste     LoadSubCommand ("detach",      CommandObjectSP (new CommandObjectProcessDetach    (interpreter)));
1947ac7ddfbfSEd Maste     LoadSubCommand ("load",        CommandObjectSP (new CommandObjectProcessLoad      (interpreter)));
1948ac7ddfbfSEd Maste     LoadSubCommand ("unload",      CommandObjectSP (new CommandObjectProcessUnload    (interpreter)));
1949ac7ddfbfSEd Maste     LoadSubCommand ("signal",      CommandObjectSP (new CommandObjectProcessSignal    (interpreter)));
1950ac7ddfbfSEd Maste     LoadSubCommand ("handle",      CommandObjectSP (new CommandObjectProcessHandle    (interpreter)));
1951ac7ddfbfSEd Maste     LoadSubCommand ("status",      CommandObjectSP (new CommandObjectProcessStatus    (interpreter)));
1952ac7ddfbfSEd Maste     LoadSubCommand ("interrupt",   CommandObjectSP (new CommandObjectProcessInterrupt (interpreter)));
1953ac7ddfbfSEd Maste     LoadSubCommand ("kill",        CommandObjectSP (new CommandObjectProcessKill      (interpreter)));
1954ac7ddfbfSEd Maste     LoadSubCommand ("plugin",      CommandObjectSP (new CommandObjectProcessPlugin    (interpreter)));
19550127ef0fSEd Maste     LoadSubCommand ("save-core",   CommandObjectSP (new CommandObjectProcessSaveCore  (interpreter)));
1956ac7ddfbfSEd Maste }
1957ac7ddfbfSEd Maste 
1958ac7ddfbfSEd Maste CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess ()
1959ac7ddfbfSEd Maste {
1960ac7ddfbfSEd Maste }
1961ac7ddfbfSEd Maste 
1962