1*30fdc8d8SChris Lattner //===-- CommandObjectProcess.cpp --------------------------------*- C++ -*-===//
2*30fdc8d8SChris Lattner //
3*30fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
4*30fdc8d8SChris Lattner //
5*30fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
6*30fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
7*30fdc8d8SChris Lattner //
8*30fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
9*30fdc8d8SChris Lattner 
10*30fdc8d8SChris Lattner #include "CommandObjectProcess.h"
11*30fdc8d8SChris Lattner 
12*30fdc8d8SChris Lattner // C Includes
13*30fdc8d8SChris Lattner // C++ Includes
14*30fdc8d8SChris Lattner // Other libraries and framework includes
15*30fdc8d8SChris Lattner // Project includes
16*30fdc8d8SChris Lattner #include "lldb/Core/Args.h"
17*30fdc8d8SChris Lattner #include "lldb/Core/Options.h"
18*30fdc8d8SChris Lattner #include "lldb/Core/State.h"
19*30fdc8d8SChris Lattner #include "lldb/Interpreter/CommandInterpreter.h"
20*30fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h"
21*30fdc8d8SChris Lattner #include "lldb/Target/Process.h"
22*30fdc8d8SChris Lattner #include "lldb/Target/Target.h"
23*30fdc8d8SChris Lattner #include "lldb/Target/Thread.h"
24*30fdc8d8SChris Lattner 
25*30fdc8d8SChris Lattner using namespace lldb;
26*30fdc8d8SChris Lattner using namespace lldb_private;
27*30fdc8d8SChris Lattner 
28*30fdc8d8SChris Lattner //-------------------------------------------------------------------------
29*30fdc8d8SChris Lattner // CommandObjectProcessLaunch
30*30fdc8d8SChris Lattner //-------------------------------------------------------------------------
31*30fdc8d8SChris Lattner 
32*30fdc8d8SChris Lattner class CommandObjectProcessLaunch : public CommandObject
33*30fdc8d8SChris Lattner {
34*30fdc8d8SChris Lattner public:
35*30fdc8d8SChris Lattner 
36*30fdc8d8SChris Lattner     class CommandOptions : public Options
37*30fdc8d8SChris Lattner     {
38*30fdc8d8SChris Lattner     public:
39*30fdc8d8SChris Lattner 
40*30fdc8d8SChris Lattner         CommandOptions () :
41*30fdc8d8SChris Lattner             Options()
42*30fdc8d8SChris Lattner         {
43*30fdc8d8SChris Lattner             // Keep default values of all options in one place: ResetOptionValues ()
44*30fdc8d8SChris Lattner             ResetOptionValues ();
45*30fdc8d8SChris Lattner         }
46*30fdc8d8SChris Lattner 
47*30fdc8d8SChris Lattner         ~CommandOptions ()
48*30fdc8d8SChris Lattner         {
49*30fdc8d8SChris Lattner         }
50*30fdc8d8SChris Lattner 
51*30fdc8d8SChris Lattner         Error
52*30fdc8d8SChris Lattner         SetOptionValue (int option_idx, const char *option_arg)
53*30fdc8d8SChris Lattner         {
54*30fdc8d8SChris Lattner             Error error;
55*30fdc8d8SChris Lattner             char short_option = (char) m_getopt_table[option_idx].val;
56*30fdc8d8SChris Lattner 
57*30fdc8d8SChris Lattner             switch (short_option)
58*30fdc8d8SChris Lattner             {
59*30fdc8d8SChris Lattner                 case 's':   stop_at_entry = true;       break;
60*30fdc8d8SChris Lattner                 case 'e':   stderr_path = option_arg;   break;
61*30fdc8d8SChris Lattner                 case 'i':   stdin_path  = option_arg;   break;
62*30fdc8d8SChris Lattner                 case 'o':   stdout_path = option_arg;   break;
63*30fdc8d8SChris Lattner                 case 'p':   plugin_name = option_arg;   break;
64*30fdc8d8SChris Lattner                 default:
65*30fdc8d8SChris Lattner                     error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
66*30fdc8d8SChris Lattner                     break;
67*30fdc8d8SChris Lattner 
68*30fdc8d8SChris Lattner             }
69*30fdc8d8SChris Lattner             return error;
70*30fdc8d8SChris Lattner         }
71*30fdc8d8SChris Lattner 
72*30fdc8d8SChris Lattner         void
73*30fdc8d8SChris Lattner         ResetOptionValues ()
74*30fdc8d8SChris Lattner         {
75*30fdc8d8SChris Lattner             Options::ResetOptionValues();
76*30fdc8d8SChris Lattner             stop_at_entry = false;
77*30fdc8d8SChris Lattner             stdin_path.clear();
78*30fdc8d8SChris Lattner             stdout_path.clear();
79*30fdc8d8SChris Lattner             stderr_path.clear();
80*30fdc8d8SChris Lattner             plugin_name.clear();
81*30fdc8d8SChris Lattner         }
82*30fdc8d8SChris Lattner 
83*30fdc8d8SChris Lattner         const lldb::OptionDefinition*
84*30fdc8d8SChris Lattner         GetDefinitions ()
85*30fdc8d8SChris Lattner         {
86*30fdc8d8SChris Lattner             return g_option_table;
87*30fdc8d8SChris Lattner         }
88*30fdc8d8SChris Lattner 
89*30fdc8d8SChris Lattner         // Options table: Required for subclasses of Options.
90*30fdc8d8SChris Lattner 
91*30fdc8d8SChris Lattner         static lldb::OptionDefinition g_option_table[];
92*30fdc8d8SChris Lattner 
93*30fdc8d8SChris Lattner         // Instance variables to hold the values for command options.
94*30fdc8d8SChris Lattner 
95*30fdc8d8SChris Lattner         bool stop_at_entry;
96*30fdc8d8SChris Lattner         std::string stderr_path;
97*30fdc8d8SChris Lattner         std::string stdin_path;
98*30fdc8d8SChris Lattner         std::string stdout_path;
99*30fdc8d8SChris Lattner         std::string plugin_name;
100*30fdc8d8SChris Lattner 
101*30fdc8d8SChris Lattner     };
102*30fdc8d8SChris Lattner 
103*30fdc8d8SChris Lattner     CommandObjectProcessLaunch () :
104*30fdc8d8SChris Lattner         CommandObject ("process launch",
105*30fdc8d8SChris Lattner                        "Launches the executable in the debugger.",
106*30fdc8d8SChris Lattner                        "process launch [<cmd-options>] [<arguments-for-running-the-program>]")
107*30fdc8d8SChris Lattner     {
108*30fdc8d8SChris Lattner     }
109*30fdc8d8SChris Lattner 
110*30fdc8d8SChris Lattner 
111*30fdc8d8SChris Lattner     ~CommandObjectProcessLaunch ()
112*30fdc8d8SChris Lattner     {
113*30fdc8d8SChris Lattner     }
114*30fdc8d8SChris Lattner 
115*30fdc8d8SChris Lattner     Options *
116*30fdc8d8SChris Lattner     GetOptions ()
117*30fdc8d8SChris Lattner     {
118*30fdc8d8SChris Lattner         return &m_options;
119*30fdc8d8SChris Lattner     }
120*30fdc8d8SChris Lattner 
121*30fdc8d8SChris Lattner     bool
122*30fdc8d8SChris Lattner     Execute (Args& launch_args,
123*30fdc8d8SChris Lattner              CommandContext *context,
124*30fdc8d8SChris Lattner              CommandInterpreter *interpreter,
125*30fdc8d8SChris Lattner              CommandReturnObject &result)
126*30fdc8d8SChris Lattner     {
127*30fdc8d8SChris Lattner         Target *target = context->GetTarget();
128*30fdc8d8SChris Lattner         bool synchronous_execution = interpreter->GetSynchronous ();
129*30fdc8d8SChris Lattner     //    bool launched = false;
130*30fdc8d8SChris Lattner     //    bool stopped_after_launch = false;
131*30fdc8d8SChris Lattner 
132*30fdc8d8SChris Lattner         if (target == NULL)
133*30fdc8d8SChris Lattner         {
134*30fdc8d8SChris Lattner             result.AppendError ("invalid target, set executable file using 'file' command");
135*30fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
136*30fdc8d8SChris Lattner             return false;
137*30fdc8d8SChris Lattner         }
138*30fdc8d8SChris Lattner 
139*30fdc8d8SChris Lattner         // If our listener is NULL, users aren't allows to launch
140*30fdc8d8SChris Lattner         Listener *listener = interpreter->GetListener();
141*30fdc8d8SChris Lattner         if (listener == NULL)
142*30fdc8d8SChris Lattner         {
143*30fdc8d8SChris Lattner             result.AppendError ("operation not allowed through the command interpreter");
144*30fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
145*30fdc8d8SChris Lattner             return false;
146*30fdc8d8SChris Lattner         }
147*30fdc8d8SChris Lattner 
148*30fdc8d8SChris Lattner         char filename[PATH_MAX];
149*30fdc8d8SChris Lattner         Module *exe_module = target->GetExecutableModule().get();
150*30fdc8d8SChris Lattner         exe_module->GetFileSpec().GetPath(filename, sizeof(filename));
151*30fdc8d8SChris Lattner 
152*30fdc8d8SChris Lattner         Process *process = context->GetExecutionContext().process;
153*30fdc8d8SChris Lattner         if (process)
154*30fdc8d8SChris Lattner         {
155*30fdc8d8SChris Lattner             if (process->IsAlive())
156*30fdc8d8SChris Lattner             {
157*30fdc8d8SChris Lattner                result.AppendErrorWithFormat ("Process %u is currently being debugged, kill the process before running again.\n",
158*30fdc8d8SChris Lattner                                             process->GetID());
159*30fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
160*30fdc8d8SChris Lattner                 return false;
161*30fdc8d8SChris Lattner             }
162*30fdc8d8SChris Lattner         }
163*30fdc8d8SChris Lattner 
164*30fdc8d8SChris Lattner         const char *plugin_name;
165*30fdc8d8SChris Lattner         if (!m_options.plugin_name.empty())
166*30fdc8d8SChris Lattner             plugin_name = m_options.plugin_name.c_str();
167*30fdc8d8SChris Lattner         else
168*30fdc8d8SChris Lattner             plugin_name = NULL;
169*30fdc8d8SChris Lattner 
170*30fdc8d8SChris Lattner         process = target->CreateProcess (*listener, plugin_name).get();
171*30fdc8d8SChris Lattner 
172*30fdc8d8SChris Lattner         const Args *environment = interpreter->GetEnvironmentVariables();
173*30fdc8d8SChris Lattner         const Args *run_args = interpreter->GetProgramArguments();
174*30fdc8d8SChris Lattner 
175*30fdc8d8SChris Lattner         // There are two possible sources of args to be passed to the process upon launching:  Those the user
176*30fdc8d8SChris Lattner         // typed at the run command (launch_args); or those the user pre-set in the run-args variable (run_args).
177*30fdc8d8SChris Lattner 
178*30fdc8d8SChris Lattner         // If launch_args is empty, use run_args.
179*30fdc8d8SChris Lattner         if (launch_args.GetArgumentCount() == 0)
180*30fdc8d8SChris Lattner         {
181*30fdc8d8SChris Lattner             if (run_args != NULL)
182*30fdc8d8SChris Lattner                 launch_args.AppendArguments (*run_args);
183*30fdc8d8SChris Lattner         }
184*30fdc8d8SChris Lattner         else
185*30fdc8d8SChris Lattner         {
186*30fdc8d8SChris Lattner             // launch-args was not empty; use that, AND re-set run-args to contains launch-args values.
187*30fdc8d8SChris Lattner             StateVariable *run_args_var = interpreter->GetStateVariable ("run-args");
188*30fdc8d8SChris Lattner             if (run_args_var != NULL)
189*30fdc8d8SChris Lattner             {
190*30fdc8d8SChris Lattner                 run_args_var->ArrayClearValues();
191*30fdc8d8SChris Lattner                 run_args_var->GetArgs().AppendArguments (launch_args);
192*30fdc8d8SChris Lattner             }
193*30fdc8d8SChris Lattner         }
194*30fdc8d8SChris Lattner 
195*30fdc8d8SChris Lattner 
196*30fdc8d8SChris Lattner         if (process)
197*30fdc8d8SChris Lattner         {
198*30fdc8d8SChris Lattner             const char *archname = exe_module->GetArchitecture().AsCString();
199*30fdc8d8SChris Lattner 
200*30fdc8d8SChris Lattner             const char * stdin_path = NULL;
201*30fdc8d8SChris Lattner             const char * stdout_path = NULL;
202*30fdc8d8SChris Lattner             const char * stderr_path = NULL;
203*30fdc8d8SChris Lattner 
204*30fdc8d8SChris Lattner             if (!(m_options.stdin_path.empty() &&
205*30fdc8d8SChris Lattner                 m_options.stdout_path.empty() &&
206*30fdc8d8SChris Lattner                 m_options.stderr_path.empty()))
207*30fdc8d8SChris Lattner             {
208*30fdc8d8SChris Lattner                 stdin_path =    m_options.stdin_path.empty()  ? "/dev/null" : m_options.stdin_path.c_str();
209*30fdc8d8SChris Lattner                 stdout_path =   m_options.stdout_path.empty() ? "/dev/null" : m_options.stdout_path.c_str();
210*30fdc8d8SChris Lattner                 stderr_path =   m_options.stderr_path.empty() ? "/dev/null" : m_options.stderr_path.c_str();
211*30fdc8d8SChris Lattner             }
212*30fdc8d8SChris Lattner 
213*30fdc8d8SChris Lattner             Error error (process->Launch (launch_args.GetConstArgumentVector(),
214*30fdc8d8SChris Lattner                                           environment ? environment->GetConstArgumentVector() : NULL,
215*30fdc8d8SChris Lattner                                           stdin_path,
216*30fdc8d8SChris Lattner                                           stdout_path,
217*30fdc8d8SChris Lattner                                           stderr_path));
218*30fdc8d8SChris Lattner 
219*30fdc8d8SChris Lattner             if (error.Success())
220*30fdc8d8SChris Lattner             {
221*30fdc8d8SChris Lattner                 result.AppendMessageWithFormat ("Launching '%s'  (%s)\n", filename, archname);
222*30fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
223*30fdc8d8SChris Lattner                 if (m_options.stop_at_entry == false)
224*30fdc8d8SChris Lattner                 {
225*30fdc8d8SChris Lattner                     StateType state = process->WaitForProcessToStop (NULL);
226*30fdc8d8SChris Lattner 
227*30fdc8d8SChris Lattner                     if (state == eStateStopped)
228*30fdc8d8SChris Lattner                     {
229*30fdc8d8SChris Lattner                         // Call continue_command.
230*30fdc8d8SChris Lattner                         CommandReturnObject continue_result;
231*30fdc8d8SChris Lattner                         interpreter->HandleCommand("process continue", false, continue_result);
232*30fdc8d8SChris Lattner                     }
233*30fdc8d8SChris Lattner 
234*30fdc8d8SChris Lattner                     if (synchronous_execution)
235*30fdc8d8SChris Lattner                     {
236*30fdc8d8SChris Lattner                         result.SetDidChangeProcessState (true);
237*30fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusSuccessFinishNoResult);
238*30fdc8d8SChris Lattner                     }
239*30fdc8d8SChris Lattner                 }
240*30fdc8d8SChris Lattner             }
241*30fdc8d8SChris Lattner             else
242*30fdc8d8SChris Lattner             {
243*30fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("Process launch failed: %s",
244*30fdc8d8SChris Lattner                                               error.AsCString());
245*30fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
246*30fdc8d8SChris Lattner             }
247*30fdc8d8SChris Lattner         }
248*30fdc8d8SChris Lattner         else
249*30fdc8d8SChris Lattner         {
250*30fdc8d8SChris Lattner             result.AppendErrorWithFormat ("Process launch failed: unable to create a process object.\n");
251*30fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
252*30fdc8d8SChris Lattner             return false;
253*30fdc8d8SChris Lattner         }
254*30fdc8d8SChris Lattner 
255*30fdc8d8SChris Lattner         return result.Succeeded();
256*30fdc8d8SChris Lattner     }
257*30fdc8d8SChris Lattner 
258*30fdc8d8SChris Lattner protected:
259*30fdc8d8SChris Lattner 
260*30fdc8d8SChris Lattner     CommandOptions m_options;
261*30fdc8d8SChris Lattner };
262*30fdc8d8SChris Lattner 
263*30fdc8d8SChris Lattner 
264*30fdc8d8SChris Lattner lldb::OptionDefinition
265*30fdc8d8SChris Lattner CommandObjectProcessLaunch::CommandOptions::g_option_table[] =
266*30fdc8d8SChris Lattner {
267*30fdc8d8SChris Lattner { 0, false, "stop-at-entry", 's', no_argument,       NULL, 0, NULL,        "Stop at the entry point of the program when launching a process."},
268*30fdc8d8SChris Lattner { 0, false, "stdin",         'i', required_argument, NULL, 0, "<path>",    "Redirect stdin for the process to <path>."},
269*30fdc8d8SChris Lattner { 0, false, "stdout",        'o', required_argument, NULL, 0, "<path>",    "Redirect stdout for the process to <path>."},
270*30fdc8d8SChris Lattner { 0, false, "stderr",        'e', required_argument, NULL, 0, "<path>",    "Redirect stderr for the process to <path>."},
271*30fdc8d8SChris Lattner { 0, false, "plugin",        'p', required_argument, NULL, 0, "<plugin>",  "Name of the process plugin you want to use."},
272*30fdc8d8SChris Lattner { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
273*30fdc8d8SChris Lattner };
274*30fdc8d8SChris Lattner 
275*30fdc8d8SChris Lattner 
276*30fdc8d8SChris Lattner //-------------------------------------------------------------------------
277*30fdc8d8SChris Lattner // CommandObjectProcessAttach
278*30fdc8d8SChris Lattner //-------------------------------------------------------------------------
279*30fdc8d8SChris Lattner 
280*30fdc8d8SChris Lattner class CommandObjectProcessAttach : public CommandObject
281*30fdc8d8SChris Lattner {
282*30fdc8d8SChris Lattner public:
283*30fdc8d8SChris Lattner 
284*30fdc8d8SChris Lattner     CommandObjectProcessAttach () :
285*30fdc8d8SChris Lattner         CommandObject ("process attach",
286*30fdc8d8SChris Lattner                        "Attaches to a process.",
287*30fdc8d8SChris Lattner                        "process attach <cmd-options>")
288*30fdc8d8SChris Lattner     {
289*30fdc8d8SChris Lattner         SetHelpLong("Currently, you must set the executable file before you can attach "
290*30fdc8d8SChris Lattner                     "to a process.\n");
291*30fdc8d8SChris Lattner     }
292*30fdc8d8SChris Lattner 
293*30fdc8d8SChris Lattner     ~CommandObjectProcessAttach ()
294*30fdc8d8SChris Lattner     {
295*30fdc8d8SChris Lattner     }
296*30fdc8d8SChris Lattner 
297*30fdc8d8SChris Lattner     bool
298*30fdc8d8SChris Lattner     Execute (Args& command,
299*30fdc8d8SChris Lattner              CommandContext *context,
300*30fdc8d8SChris Lattner              CommandInterpreter *interpreter,
301*30fdc8d8SChris Lattner              CommandReturnObject &result)
302*30fdc8d8SChris Lattner     {
303*30fdc8d8SChris Lattner         Target *target = context->GetTarget();
304*30fdc8d8SChris Lattner         if (target == NULL)
305*30fdc8d8SChris Lattner         {
306*30fdc8d8SChris Lattner             result.AppendError ("invalid target, set executable file using 'file' command");
307*30fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
308*30fdc8d8SChris Lattner             return false;
309*30fdc8d8SChris Lattner         }
310*30fdc8d8SChris Lattner 
311*30fdc8d8SChris Lattner         // If our listener is NULL, users aren't allows to launch
312*30fdc8d8SChris Lattner         Listener *listener = interpreter->GetListener();
313*30fdc8d8SChris Lattner         if (listener == NULL)
314*30fdc8d8SChris Lattner         {
315*30fdc8d8SChris Lattner             result.AppendError ("operation not allowed through the command interpreter");
316*30fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
317*30fdc8d8SChris Lattner             return false;
318*30fdc8d8SChris Lattner         }
319*30fdc8d8SChris Lattner         Process *process = context->GetExecutionContext().process;
320*30fdc8d8SChris Lattner         if (process)
321*30fdc8d8SChris Lattner         {
322*30fdc8d8SChris Lattner             if (process->IsAlive())
323*30fdc8d8SChris Lattner             {
324*30fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("Process %u is currently being debugged, kill the process before attaching.\n", process->GetID());
325*30fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
326*30fdc8d8SChris Lattner                 return false;
327*30fdc8d8SChris Lattner             }
328*30fdc8d8SChris Lattner         }
329*30fdc8d8SChris Lattner 
330*30fdc8d8SChris Lattner         if (command.GetArgumentCount())
331*30fdc8d8SChris Lattner         {
332*30fdc8d8SChris Lattner             result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: \n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
333*30fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
334*30fdc8d8SChris Lattner         }
335*30fdc8d8SChris Lattner         else
336*30fdc8d8SChris Lattner         {
337*30fdc8d8SChris Lattner             const char *plugin_name = NULL;
338*30fdc8d8SChris Lattner 
339*30fdc8d8SChris Lattner             if (!m_options.plugin_name.empty())
340*30fdc8d8SChris Lattner                 plugin_name = m_options.plugin_name.c_str();
341*30fdc8d8SChris Lattner 
342*30fdc8d8SChris Lattner             process = target->CreateProcess (*listener, plugin_name).get();
343*30fdc8d8SChris Lattner 
344*30fdc8d8SChris Lattner             if (process)
345*30fdc8d8SChris Lattner             {
346*30fdc8d8SChris Lattner                 Error error;
347*30fdc8d8SChris Lattner                 int attach_pid = m_options.pid;
348*30fdc8d8SChris Lattner 
349*30fdc8d8SChris Lattner                 if (attach_pid != LLDB_INVALID_PROCESS_ID)
350*30fdc8d8SChris Lattner                 {
351*30fdc8d8SChris Lattner                     error = process->Attach (attach_pid);
352*30fdc8d8SChris Lattner                     if (error.Success())
353*30fdc8d8SChris Lattner                     {
354*30fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusSuccessContinuingNoResult);
355*30fdc8d8SChris Lattner                     }
356*30fdc8d8SChris Lattner                     else
357*30fdc8d8SChris Lattner                     {
358*30fdc8d8SChris Lattner                         result.AppendErrorWithFormat ("Attaching to process %i failed: %s.\n",
359*30fdc8d8SChris Lattner                                                      attach_pid,
360*30fdc8d8SChris Lattner                                                      error.AsCString());
361*30fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusFailed);
362*30fdc8d8SChris Lattner                     }
363*30fdc8d8SChris Lattner                 }
364*30fdc8d8SChris Lattner                 else if (!m_options.name.empty())
365*30fdc8d8SChris Lattner                 {
366*30fdc8d8SChris Lattner                     error = process->Attach (m_options.name.c_str(), m_options.waitfor);
367*30fdc8d8SChris Lattner                     if (error.Success())
368*30fdc8d8SChris Lattner                     {
369*30fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusSuccessContinuingNoResult);
370*30fdc8d8SChris Lattner                     }
371*30fdc8d8SChris Lattner                     else
372*30fdc8d8SChris Lattner                     {
373*30fdc8d8SChris Lattner                         if (m_options.waitfor)
374*30fdc8d8SChris Lattner                             result.AppendErrorWithFormat ("Waiting for a process to launch named '%s': %s\n",
375*30fdc8d8SChris Lattner                                                          m_options.name.c_str(),
376*30fdc8d8SChris Lattner                                                          error.AsCString());
377*30fdc8d8SChris Lattner                         else
378*30fdc8d8SChris Lattner                             result.AppendErrorWithFormat ("Failed to a process named '%s': %s\n",
379*30fdc8d8SChris Lattner                                                          m_options.name.c_str(),
380*30fdc8d8SChris Lattner                                                          error.AsCString());
381*30fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusFailed);
382*30fdc8d8SChris Lattner                     }
383*30fdc8d8SChris Lattner                 }
384*30fdc8d8SChris Lattner             }
385*30fdc8d8SChris Lattner         }
386*30fdc8d8SChris Lattner         return result.Succeeded();
387*30fdc8d8SChris Lattner     }
388*30fdc8d8SChris Lattner 
389*30fdc8d8SChris Lattner     Options *
390*30fdc8d8SChris Lattner     GetOptions ()
391*30fdc8d8SChris Lattner     {
392*30fdc8d8SChris Lattner         return &m_options;
393*30fdc8d8SChris Lattner     }
394*30fdc8d8SChris Lattner 
395*30fdc8d8SChris Lattner     class CommandOptions : public Options
396*30fdc8d8SChris Lattner     {
397*30fdc8d8SChris Lattner     public:
398*30fdc8d8SChris Lattner 
399*30fdc8d8SChris Lattner         CommandOptions () :
400*30fdc8d8SChris Lattner             Options()
401*30fdc8d8SChris Lattner         {
402*30fdc8d8SChris Lattner             // Keep default values of all options in one place: ResetOptionValues ()
403*30fdc8d8SChris Lattner             ResetOptionValues ();
404*30fdc8d8SChris Lattner         }
405*30fdc8d8SChris Lattner 
406*30fdc8d8SChris Lattner         ~CommandOptions ()
407*30fdc8d8SChris Lattner         {
408*30fdc8d8SChris Lattner         }
409*30fdc8d8SChris Lattner 
410*30fdc8d8SChris Lattner         Error
411*30fdc8d8SChris Lattner         SetOptionValue (int option_idx, const char *option_arg)
412*30fdc8d8SChris Lattner         {
413*30fdc8d8SChris Lattner             Error error;
414*30fdc8d8SChris Lattner             char short_option = (char) m_getopt_table[option_idx].val;
415*30fdc8d8SChris Lattner             bool success = false;
416*30fdc8d8SChris Lattner             switch (short_option)
417*30fdc8d8SChris Lattner             {
418*30fdc8d8SChris Lattner                 case 'p':
419*30fdc8d8SChris Lattner                     pid = Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success);
420*30fdc8d8SChris Lattner                     if (!success || pid == LLDB_INVALID_PROCESS_ID)
421*30fdc8d8SChris Lattner                     {
422*30fdc8d8SChris Lattner                         error.SetErrorStringWithFormat("Invalid process ID '%s'.\n", option_arg);
423*30fdc8d8SChris Lattner                     }
424*30fdc8d8SChris Lattner                     break;
425*30fdc8d8SChris Lattner 
426*30fdc8d8SChris Lattner                 case 'P':
427*30fdc8d8SChris Lattner                     plugin_name = option_arg;
428*30fdc8d8SChris Lattner                     break;
429*30fdc8d8SChris Lattner 
430*30fdc8d8SChris Lattner                 case 'n':
431*30fdc8d8SChris Lattner                     name.assign(option_arg);
432*30fdc8d8SChris Lattner                     break;
433*30fdc8d8SChris Lattner 
434*30fdc8d8SChris Lattner                 case 'w':
435*30fdc8d8SChris Lattner                     waitfor = true;
436*30fdc8d8SChris Lattner                     break;
437*30fdc8d8SChris Lattner 
438*30fdc8d8SChris Lattner                 default:
439*30fdc8d8SChris Lattner                     error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
440*30fdc8d8SChris Lattner                     break;
441*30fdc8d8SChris Lattner             }
442*30fdc8d8SChris Lattner             return error;
443*30fdc8d8SChris Lattner         }
444*30fdc8d8SChris Lattner 
445*30fdc8d8SChris Lattner         void
446*30fdc8d8SChris Lattner         ResetOptionValues ()
447*30fdc8d8SChris Lattner         {
448*30fdc8d8SChris Lattner             Options::ResetOptionValues();
449*30fdc8d8SChris Lattner             pid = LLDB_INVALID_PROCESS_ID;
450*30fdc8d8SChris Lattner             name.clear();
451*30fdc8d8SChris Lattner             waitfor = false;
452*30fdc8d8SChris Lattner         }
453*30fdc8d8SChris Lattner 
454*30fdc8d8SChris Lattner         const lldb::OptionDefinition*
455*30fdc8d8SChris Lattner         GetDefinitions ()
456*30fdc8d8SChris Lattner         {
457*30fdc8d8SChris Lattner             return g_option_table;
458*30fdc8d8SChris Lattner         }
459*30fdc8d8SChris Lattner 
460*30fdc8d8SChris Lattner         // Options table: Required for subclasses of Options.
461*30fdc8d8SChris Lattner 
462*30fdc8d8SChris Lattner         static lldb::OptionDefinition g_option_table[];
463*30fdc8d8SChris Lattner 
464*30fdc8d8SChris Lattner         // Instance variables to hold the values for command options.
465*30fdc8d8SChris Lattner 
466*30fdc8d8SChris Lattner         lldb::pid_t pid;
467*30fdc8d8SChris Lattner         std::string plugin_name;
468*30fdc8d8SChris Lattner         std::string name;
469*30fdc8d8SChris Lattner         bool waitfor;
470*30fdc8d8SChris Lattner     };
471*30fdc8d8SChris Lattner 
472*30fdc8d8SChris Lattner protected:
473*30fdc8d8SChris Lattner 
474*30fdc8d8SChris Lattner     CommandOptions m_options;
475*30fdc8d8SChris Lattner };
476*30fdc8d8SChris Lattner 
477*30fdc8d8SChris Lattner 
478*30fdc8d8SChris Lattner lldb::OptionDefinition
479*30fdc8d8SChris Lattner CommandObjectProcessAttach::CommandOptions::g_option_table[] =
480*30fdc8d8SChris Lattner {
481*30fdc8d8SChris Lattner { 0, false, "pid",          'p', required_argument, NULL, 0, "<pid>",           "The process ID of an existing process to attach to."},
482*30fdc8d8SChris Lattner { 0, false, "plugin",       'P', required_argument, NULL, 0, "<plugin>",        "Name of the process plugin you want to use."},
483*30fdc8d8SChris Lattner { 1, true,  "name",         'n', required_argument, NULL, 0, "<process-name>",  "The name of the process to attach to."},
484*30fdc8d8SChris Lattner { 1, false, "waitfor",      'w', no_argument,       NULL, 0, NULL,              "Wait for the the process with <process-name> to launch."},
485*30fdc8d8SChris Lattner { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
486*30fdc8d8SChris Lattner };
487*30fdc8d8SChris Lattner 
488*30fdc8d8SChris Lattner //-------------------------------------------------------------------------
489*30fdc8d8SChris Lattner // CommandObjectProcessContinue
490*30fdc8d8SChris Lattner //-------------------------------------------------------------------------
491*30fdc8d8SChris Lattner 
492*30fdc8d8SChris Lattner class CommandObjectProcessContinue : public CommandObject
493*30fdc8d8SChris Lattner {
494*30fdc8d8SChris Lattner public:
495*30fdc8d8SChris Lattner 
496*30fdc8d8SChris Lattner     CommandObjectProcessContinue () :
497*30fdc8d8SChris Lattner         CommandObject ("process continue",
498*30fdc8d8SChris Lattner                        "Continues execution all threads in the current process.",
499*30fdc8d8SChris Lattner                        "process continue",
500*30fdc8d8SChris Lattner                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
501*30fdc8d8SChris Lattner     {
502*30fdc8d8SChris Lattner     }
503*30fdc8d8SChris Lattner 
504*30fdc8d8SChris Lattner 
505*30fdc8d8SChris Lattner     ~CommandObjectProcessContinue ()
506*30fdc8d8SChris Lattner     {
507*30fdc8d8SChris Lattner     }
508*30fdc8d8SChris Lattner 
509*30fdc8d8SChris Lattner     bool
510*30fdc8d8SChris Lattner     Execute (Args& command,
511*30fdc8d8SChris Lattner              CommandContext *context,
512*30fdc8d8SChris Lattner              CommandInterpreter *interpreter,
513*30fdc8d8SChris Lattner              CommandReturnObject &result)
514*30fdc8d8SChris Lattner     {
515*30fdc8d8SChris Lattner         Process *process = context->GetExecutionContext().process;
516*30fdc8d8SChris Lattner         bool synchronous_execution = interpreter->GetSynchronous ();
517*30fdc8d8SChris Lattner 
518*30fdc8d8SChris Lattner         if (process == NULL)
519*30fdc8d8SChris Lattner         {
520*30fdc8d8SChris Lattner             result.AppendError ("no process to continue");
521*30fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
522*30fdc8d8SChris Lattner             return false;
523*30fdc8d8SChris Lattner          }
524*30fdc8d8SChris Lattner 
525*30fdc8d8SChris Lattner         StateType state = process->GetState();
526*30fdc8d8SChris Lattner         if (state == eStateStopped)
527*30fdc8d8SChris Lattner         {
528*30fdc8d8SChris Lattner             if (command.GetArgumentCount() != 0)
529*30fdc8d8SChris Lattner             {
530*30fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("The '%s' command does not take any arguments.\n", m_cmd_name.c_str());
531*30fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
532*30fdc8d8SChris Lattner                 return false;
533*30fdc8d8SChris Lattner             }
534*30fdc8d8SChris Lattner 
535*30fdc8d8SChris Lattner             const uint32_t num_threads = process->GetThreadList().GetSize();
536*30fdc8d8SChris Lattner 
537*30fdc8d8SChris Lattner             // Set the actions that the threads should each take when resuming
538*30fdc8d8SChris Lattner             for (uint32_t idx=0; idx<num_threads; ++idx)
539*30fdc8d8SChris Lattner             {
540*30fdc8d8SChris Lattner                 process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState (eStateRunning);
541*30fdc8d8SChris Lattner             }
542*30fdc8d8SChris Lattner 
543*30fdc8d8SChris Lattner             Error error(process->Resume());
544*30fdc8d8SChris Lattner             if (error.Success())
545*30fdc8d8SChris Lattner             {
546*30fdc8d8SChris Lattner                 result.AppendMessageWithFormat ("Resuming process %i\n", process->GetID());
547*30fdc8d8SChris Lattner                 if (synchronous_execution)
548*30fdc8d8SChris Lattner                 {
549*30fdc8d8SChris Lattner                     StateType state = process->WaitForProcessToStop (NULL);
550*30fdc8d8SChris Lattner 
551*30fdc8d8SChris Lattner                     result.SetDidChangeProcessState (true);
552*30fdc8d8SChris Lattner                     result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state));
553*30fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
554*30fdc8d8SChris Lattner                 }
555*30fdc8d8SChris Lattner                 else
556*30fdc8d8SChris Lattner                 {
557*30fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusSuccessContinuingNoResult);
558*30fdc8d8SChris Lattner                 }
559*30fdc8d8SChris Lattner             }
560*30fdc8d8SChris Lattner             else
561*30fdc8d8SChris Lattner             {
562*30fdc8d8SChris Lattner                 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
563*30fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
564*30fdc8d8SChris Lattner             }
565*30fdc8d8SChris Lattner         }
566*30fdc8d8SChris Lattner         else
567*30fdc8d8SChris Lattner         {
568*30fdc8d8SChris Lattner             result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
569*30fdc8d8SChris Lattner                                          StateAsCString(state));
570*30fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
571*30fdc8d8SChris Lattner         }
572*30fdc8d8SChris Lattner         return result.Succeeded();
573*30fdc8d8SChris Lattner     }
574*30fdc8d8SChris Lattner };
575*30fdc8d8SChris Lattner 
576*30fdc8d8SChris Lattner //-------------------------------------------------------------------------
577*30fdc8d8SChris Lattner // CommandObjectProcessDetach
578*30fdc8d8SChris Lattner //-------------------------------------------------------------------------
579*30fdc8d8SChris Lattner 
580*30fdc8d8SChris Lattner class CommandObjectProcessDetach : public CommandObject
581*30fdc8d8SChris Lattner {
582*30fdc8d8SChris Lattner public:
583*30fdc8d8SChris Lattner 
584*30fdc8d8SChris Lattner     CommandObjectProcessDetach () :
585*30fdc8d8SChris Lattner         CommandObject ("process detach",
586*30fdc8d8SChris Lattner                        "Detaches from the current process being debugged.",
587*30fdc8d8SChris Lattner                        "process detach",
588*30fdc8d8SChris Lattner                        eFlagProcessMustBeLaunched)
589*30fdc8d8SChris Lattner     {
590*30fdc8d8SChris Lattner     }
591*30fdc8d8SChris Lattner 
592*30fdc8d8SChris Lattner     ~CommandObjectProcessDetach ()
593*30fdc8d8SChris Lattner     {
594*30fdc8d8SChris Lattner     }
595*30fdc8d8SChris Lattner 
596*30fdc8d8SChris Lattner     bool
597*30fdc8d8SChris Lattner     Execute (Args& command,
598*30fdc8d8SChris Lattner              CommandContext *context,
599*30fdc8d8SChris Lattner              CommandInterpreter *interpreter,
600*30fdc8d8SChris Lattner              CommandReturnObject &result)
601*30fdc8d8SChris Lattner     {
602*30fdc8d8SChris Lattner         Process *process = context->GetExecutionContext().process;
603*30fdc8d8SChris Lattner         if (process == NULL)
604*30fdc8d8SChris Lattner         {
605*30fdc8d8SChris Lattner             result.AppendError ("must have a valid process in order to detach");
606*30fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
607*30fdc8d8SChris Lattner             return false;
608*30fdc8d8SChris Lattner         }
609*30fdc8d8SChris Lattner 
610*30fdc8d8SChris Lattner         Error error (process->Detach());
611*30fdc8d8SChris Lattner         if (error.Success())
612*30fdc8d8SChris Lattner         {
613*30fdc8d8SChris Lattner             result.SetStatus (eReturnStatusSuccessFinishResult);
614*30fdc8d8SChris Lattner         }
615*30fdc8d8SChris Lattner         else
616*30fdc8d8SChris Lattner         {
617*30fdc8d8SChris Lattner             result.AppendErrorWithFormat ("Detach failed: %s\n", error.AsCString());
618*30fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
619*30fdc8d8SChris Lattner             return false;
620*30fdc8d8SChris Lattner         }
621*30fdc8d8SChris Lattner         return result.Succeeded();
622*30fdc8d8SChris Lattner     }
623*30fdc8d8SChris Lattner };
624*30fdc8d8SChris Lattner 
625*30fdc8d8SChris Lattner //-------------------------------------------------------------------------
626*30fdc8d8SChris Lattner // CommandObjectProcessSignal
627*30fdc8d8SChris Lattner //-------------------------------------------------------------------------
628*30fdc8d8SChris Lattner 
629*30fdc8d8SChris Lattner class CommandObjectProcessSignal : public CommandObject
630*30fdc8d8SChris Lattner {
631*30fdc8d8SChris Lattner public:
632*30fdc8d8SChris Lattner 
633*30fdc8d8SChris Lattner     CommandObjectProcessSignal () :
634*30fdc8d8SChris Lattner         CommandObject ("process signal",
635*30fdc8d8SChris Lattner                        "Sends a UNIX signal to the current process being debugged.",
636*30fdc8d8SChris Lattner                        "process signal <unix-signal-number>")
637*30fdc8d8SChris Lattner     {
638*30fdc8d8SChris Lattner     }
639*30fdc8d8SChris Lattner 
640*30fdc8d8SChris Lattner     ~CommandObjectProcessSignal ()
641*30fdc8d8SChris Lattner     {
642*30fdc8d8SChris Lattner     }
643*30fdc8d8SChris Lattner 
644*30fdc8d8SChris Lattner     bool
645*30fdc8d8SChris Lattner     Execute (Args& command,
646*30fdc8d8SChris Lattner              CommandContext *context,
647*30fdc8d8SChris Lattner              CommandInterpreter *interpreter,
648*30fdc8d8SChris Lattner              CommandReturnObject &result)
649*30fdc8d8SChris Lattner     {
650*30fdc8d8SChris Lattner         Process *process = context->GetExecutionContext().process;
651*30fdc8d8SChris Lattner         if (process == NULL)
652*30fdc8d8SChris Lattner         {
653*30fdc8d8SChris Lattner             result.AppendError ("no process to signal");
654*30fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
655*30fdc8d8SChris Lattner             return false;
656*30fdc8d8SChris Lattner         }
657*30fdc8d8SChris Lattner 
658*30fdc8d8SChris Lattner         if (command.GetArgumentCount() == 1)
659*30fdc8d8SChris Lattner         {
660*30fdc8d8SChris Lattner             int signo = Args::StringToSInt32(command.GetArgumentAtIndex(0), -1, 0);
661*30fdc8d8SChris Lattner             if (signo == -1)
662*30fdc8d8SChris Lattner             {
663*30fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("Invalid signal argument '%s'.\n", command.GetArgumentAtIndex(0));
664*30fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
665*30fdc8d8SChris Lattner             }
666*30fdc8d8SChris Lattner             else
667*30fdc8d8SChris Lattner             {
668*30fdc8d8SChris Lattner                 Error error (process->Signal (signo));
669*30fdc8d8SChris Lattner                 if (error.Success())
670*30fdc8d8SChris Lattner                 {
671*30fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusSuccessFinishResult);
672*30fdc8d8SChris Lattner                 }
673*30fdc8d8SChris Lattner                 else
674*30fdc8d8SChris Lattner                 {
675*30fdc8d8SChris Lattner                     result.AppendErrorWithFormat ("Failed to send signal %i: %s\n", signo, error.AsCString());
676*30fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
677*30fdc8d8SChris Lattner                 }
678*30fdc8d8SChris Lattner             }
679*30fdc8d8SChris Lattner         }
680*30fdc8d8SChris Lattner         else
681*30fdc8d8SChris Lattner         {
682*30fdc8d8SChris Lattner             result.AppendErrorWithFormat("'%s' takes exactly one signal number argument:\nUsage: \n", m_cmd_name.c_str(),
683*30fdc8d8SChris Lattner                                         m_cmd_syntax.c_str());
684*30fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
685*30fdc8d8SChris Lattner         }
686*30fdc8d8SChris Lattner         return result.Succeeded();
687*30fdc8d8SChris Lattner     }
688*30fdc8d8SChris Lattner };
689*30fdc8d8SChris Lattner 
690*30fdc8d8SChris Lattner 
691*30fdc8d8SChris Lattner //-------------------------------------------------------------------------
692*30fdc8d8SChris Lattner // CommandObjectProcessInterrupt
693*30fdc8d8SChris Lattner //-------------------------------------------------------------------------
694*30fdc8d8SChris Lattner 
695*30fdc8d8SChris Lattner class CommandObjectProcessInterrupt : public CommandObject
696*30fdc8d8SChris Lattner {
697*30fdc8d8SChris Lattner public:
698*30fdc8d8SChris Lattner 
699*30fdc8d8SChris Lattner 
700*30fdc8d8SChris Lattner     CommandObjectProcessInterrupt () :
701*30fdc8d8SChris Lattner     CommandObject ("process interrupt",
702*30fdc8d8SChris Lattner                    "Interrupts the current process being debugged.",
703*30fdc8d8SChris Lattner                    "process interrupt",
704*30fdc8d8SChris Lattner                    eFlagProcessMustBeLaunched)
705*30fdc8d8SChris Lattner     {
706*30fdc8d8SChris Lattner     }
707*30fdc8d8SChris Lattner 
708*30fdc8d8SChris Lattner     ~CommandObjectProcessInterrupt ()
709*30fdc8d8SChris Lattner     {
710*30fdc8d8SChris Lattner     }
711*30fdc8d8SChris Lattner 
712*30fdc8d8SChris Lattner     bool
713*30fdc8d8SChris Lattner     Execute (Args& command,
714*30fdc8d8SChris Lattner              CommandContext *context,
715*30fdc8d8SChris Lattner              CommandInterpreter *interpreter,
716*30fdc8d8SChris Lattner              CommandReturnObject &result)
717*30fdc8d8SChris Lattner     {
718*30fdc8d8SChris Lattner         Process *process = context->GetExecutionContext().process;
719*30fdc8d8SChris Lattner         if (process == NULL)
720*30fdc8d8SChris Lattner         {
721*30fdc8d8SChris Lattner             result.AppendError ("no process to halt");
722*30fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
723*30fdc8d8SChris Lattner             return false;
724*30fdc8d8SChris Lattner         }
725*30fdc8d8SChris Lattner 
726*30fdc8d8SChris Lattner         if (command.GetArgumentCount() == 0)
727*30fdc8d8SChris Lattner         {
728*30fdc8d8SChris Lattner             Error error(process->Halt ());
729*30fdc8d8SChris Lattner             if (error.Success())
730*30fdc8d8SChris Lattner             {
731*30fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusSuccessFinishResult);
732*30fdc8d8SChris Lattner 
733*30fdc8d8SChris Lattner                 // Maybe we should add a "SuspendThreadPlans so we
734*30fdc8d8SChris Lattner                 // can halt, and keep in place all the current thread plans.
735*30fdc8d8SChris Lattner                 process->GetThreadList().DiscardThreadPlans();
736*30fdc8d8SChris Lattner             }
737*30fdc8d8SChris Lattner             else
738*30fdc8d8SChris Lattner             {
739*30fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("Failed to halt process: %s\n", error.AsCString());
740*30fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
741*30fdc8d8SChris Lattner             }
742*30fdc8d8SChris Lattner         }
743*30fdc8d8SChris Lattner         else
744*30fdc8d8SChris Lattner         {
745*30fdc8d8SChris Lattner             result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: \n",
746*30fdc8d8SChris Lattner                                         m_cmd_name.c_str(),
747*30fdc8d8SChris Lattner                                         m_cmd_syntax.c_str());
748*30fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
749*30fdc8d8SChris Lattner         }
750*30fdc8d8SChris Lattner         return result.Succeeded();
751*30fdc8d8SChris Lattner     }
752*30fdc8d8SChris Lattner };
753*30fdc8d8SChris Lattner 
754*30fdc8d8SChris Lattner //-------------------------------------------------------------------------
755*30fdc8d8SChris Lattner // CommandObjectProcessKill
756*30fdc8d8SChris Lattner //-------------------------------------------------------------------------
757*30fdc8d8SChris Lattner 
758*30fdc8d8SChris Lattner class CommandObjectProcessKill : public CommandObject
759*30fdc8d8SChris Lattner {
760*30fdc8d8SChris Lattner public:
761*30fdc8d8SChris Lattner 
762*30fdc8d8SChris Lattner     CommandObjectProcessKill () :
763*30fdc8d8SChris Lattner     CommandObject ("process kill",
764*30fdc8d8SChris Lattner                    "Terminates the current process being debugged.",
765*30fdc8d8SChris Lattner                    "process kill",
766*30fdc8d8SChris Lattner                    eFlagProcessMustBeLaunched)
767*30fdc8d8SChris Lattner     {
768*30fdc8d8SChris Lattner     }
769*30fdc8d8SChris Lattner 
770*30fdc8d8SChris Lattner     ~CommandObjectProcessKill ()
771*30fdc8d8SChris Lattner     {
772*30fdc8d8SChris Lattner     }
773*30fdc8d8SChris Lattner 
774*30fdc8d8SChris Lattner     bool
775*30fdc8d8SChris Lattner     Execute (Args& command,
776*30fdc8d8SChris Lattner              CommandContext *context,
777*30fdc8d8SChris Lattner              CommandInterpreter *interpreter,
778*30fdc8d8SChris Lattner              CommandReturnObject &result)
779*30fdc8d8SChris Lattner     {
780*30fdc8d8SChris Lattner         Process *process = context->GetExecutionContext().process;
781*30fdc8d8SChris Lattner         if (process == NULL)
782*30fdc8d8SChris Lattner         {
783*30fdc8d8SChris Lattner             result.AppendError ("no process to kill");
784*30fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
785*30fdc8d8SChris Lattner             return false;
786*30fdc8d8SChris Lattner         }
787*30fdc8d8SChris Lattner 
788*30fdc8d8SChris Lattner         if (command.GetArgumentCount() == 0)
789*30fdc8d8SChris Lattner         {
790*30fdc8d8SChris Lattner             Error error (process->Destroy());
791*30fdc8d8SChris Lattner             if (error.Success())
792*30fdc8d8SChris Lattner             {
793*30fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusSuccessFinishResult);
794*30fdc8d8SChris Lattner             }
795*30fdc8d8SChris Lattner             else
796*30fdc8d8SChris Lattner             {
797*30fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString());
798*30fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
799*30fdc8d8SChris Lattner             }
800*30fdc8d8SChris Lattner         }
801*30fdc8d8SChris Lattner         else
802*30fdc8d8SChris Lattner         {
803*30fdc8d8SChris Lattner             result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: \n",
804*30fdc8d8SChris Lattner                                         m_cmd_name.c_str(),
805*30fdc8d8SChris Lattner                                         m_cmd_syntax.c_str());
806*30fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
807*30fdc8d8SChris Lattner         }
808*30fdc8d8SChris Lattner         return result.Succeeded();
809*30fdc8d8SChris Lattner     }
810*30fdc8d8SChris Lattner };
811*30fdc8d8SChris Lattner 
812*30fdc8d8SChris Lattner //-------------------------------------------------------------------------
813*30fdc8d8SChris Lattner // CommandObjectMultiwordProcess
814*30fdc8d8SChris Lattner //-------------------------------------------------------------------------
815*30fdc8d8SChris Lattner 
816*30fdc8d8SChris Lattner CommandObjectMultiwordProcess::CommandObjectMultiwordProcess (CommandInterpreter *interpreter) :
817*30fdc8d8SChris Lattner     CommandObjectMultiword ("process",
818*30fdc8d8SChris Lattner                               "A set of commands for operating on a process.",
819*30fdc8d8SChris Lattner                               "process <subcommand> [<subcommand-options>]")
820*30fdc8d8SChris Lattner {
821*30fdc8d8SChris Lattner     LoadSubCommand (CommandObjectSP (new CommandObjectProcessAttach ()), "attach", interpreter);
822*30fdc8d8SChris Lattner     LoadSubCommand (CommandObjectSP (new CommandObjectProcessLaunch ()), "launch", interpreter);
823*30fdc8d8SChris Lattner     LoadSubCommand (CommandObjectSP (new CommandObjectProcessContinue ()), "continue", interpreter);
824*30fdc8d8SChris Lattner     LoadSubCommand (CommandObjectSP (new CommandObjectProcessDetach ()), "detach", interpreter);
825*30fdc8d8SChris Lattner     LoadSubCommand (CommandObjectSP (new CommandObjectProcessSignal ()), "signal", interpreter);
826*30fdc8d8SChris Lattner     LoadSubCommand (CommandObjectSP (new CommandObjectProcessInterrupt ()), "interrupt", interpreter);
827*30fdc8d8SChris Lattner     LoadSubCommand (CommandObjectSP (new CommandObjectProcessKill ()), "kill", interpreter);
828*30fdc8d8SChris Lattner }
829*30fdc8d8SChris Lattner 
830*30fdc8d8SChris Lattner CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess ()
831*30fdc8d8SChris Lattner {
832*30fdc8d8SChris Lattner }
833*30fdc8d8SChris Lattner 
834