blob: 7c72ab8c3471271bfbd92e883094e8202f542812 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- CommandObjectProcess.cpp --------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Daniel Malea93a64302012-12-05 00:20:57 +000010#include "lldb/lldb-python.h"
11
Chris Lattner30fdc8d2010-06-08 16:52:24 +000012#include "CommandObjectProcess.h"
13
14// C Includes
15// C++ Includes
16// Other libraries and framework includes
17// Project includes
Jim Ingham0e410842012-08-11 01:27:55 +000018#include "lldb/Breakpoint/Breakpoint.h"
19#include "lldb/Breakpoint/BreakpointLocation.h"
20#include "lldb/Breakpoint/BreakpointSite.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000021#include "lldb/Core/State.h"
Greg Clayton1f746072012-08-29 21:13:06 +000022#include "lldb/Core/Module.h"
Greg Clayton7260f622011-04-18 08:33:37 +000023#include "lldb/Host/Host.h"
Jim Ingham0e410842012-08-11 01:27:55 +000024#include "lldb/Interpreter/Args.h"
25#include "lldb/Interpreter/Options.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000026#include "lldb/Interpreter/CommandInterpreter.h"
27#include "lldb/Interpreter/CommandReturnObject.h"
Greg Claytone996fd32011-03-08 22:40:15 +000028#include "lldb/Target/Platform.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000029#include "lldb/Target/Process.h"
Jim Ingham0e410842012-08-11 01:27:55 +000030#include "lldb/Target/StopInfo.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000031#include "lldb/Target/Target.h"
32#include "lldb/Target/Thread.h"
33
34using namespace lldb;
35using namespace lldb_private;
36
Jim Inghamdcb1d852013-03-29 00:56:30 +000037class CommandObjectProcessLaunchOrAttach : public CommandObjectParsed
38{
39public:
40 CommandObjectProcessLaunchOrAttach (CommandInterpreter &interpreter,
41 const char *name,
42 const char *help,
43 const char *syntax,
44 uint32_t flags,
45 const char *new_process_action) :
46 CommandObjectParsed (interpreter, name, help, syntax, flags),
47 m_new_process_action (new_process_action) {}
48
49 virtual ~CommandObjectProcessLaunchOrAttach () {}
50protected:
51 bool
Greg Claytonb09c5382013-12-13 17:20:18 +000052 StopProcessIfNecessary (Process *process, StateType &state, CommandReturnObject &result)
Jim Inghamdcb1d852013-03-29 00:56:30 +000053 {
54 state = eStateInvalid;
55 if (process)
56 {
57 state = process->GetState();
58
59 if (process->IsAlive() && state != eStateConnected)
60 {
61 char message[1024];
62 if (process->GetState() == eStateAttaching)
63 ::snprintf (message, sizeof(message), "There is a pending attach, abort it and %s?", m_new_process_action.c_str());
64 else if (process->GetShouldDetach())
65 ::snprintf (message, sizeof(message), "There is a running process, detach from it and %s?", m_new_process_action.c_str());
66 else
67 ::snprintf (message, sizeof(message), "There is a running process, kill it and %s?", m_new_process_action.c_str());
68
69 if (!m_interpreter.Confirm (message, true))
70 {
71 result.SetStatus (eReturnStatusFailed);
72 return false;
73 }
74 else
75 {
76 if (process->GetShouldDetach())
77 {
Jim Inghamacff8952013-05-02 00:27:30 +000078 bool keep_stopped = false;
79 Error detach_error (process->Detach(keep_stopped));
Jim Inghamdcb1d852013-03-29 00:56:30 +000080 if (detach_error.Success())
81 {
82 result.SetStatus (eReturnStatusSuccessFinishResult);
83 process = NULL;
84 }
85 else
86 {
87 result.AppendErrorWithFormat ("Failed to detach from process: %s\n", detach_error.AsCString());
88 result.SetStatus (eReturnStatusFailed);
89 }
90 }
91 else
92 {
93 Error destroy_error (process->Destroy());
94 if (destroy_error.Success())
95 {
96 result.SetStatus (eReturnStatusSuccessFinishResult);
97 process = NULL;
98 }
99 else
100 {
101 result.AppendErrorWithFormat ("Failed to kill process: %s\n", destroy_error.AsCString());
102 result.SetStatus (eReturnStatusFailed);
103 }
104 }
105 }
106 }
107 }
108 return result.Succeeded();
109 }
110 std::string m_new_process_action;
111};
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000112//-------------------------------------------------------------------------
113// CommandObjectProcessLaunch
114//-------------------------------------------------------------------------
Jim Ingham4bddaeb2012-02-16 06:50:00 +0000115#pragma mark CommandObjectProcessLaunch
Jim Inghamdcb1d852013-03-29 00:56:30 +0000116class CommandObjectProcessLaunch : public CommandObjectProcessLaunchOrAttach
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000117{
118public:
119
Greg Claytona7015092010-09-18 01:14:36 +0000120 CommandObjectProcessLaunch (CommandInterpreter &interpreter) :
Jim Inghamdcb1d852013-03-29 00:56:30 +0000121 CommandObjectProcessLaunchOrAttach (interpreter,
122 "process launch",
123 "Launch the executable in the debugger.",
124 NULL,
125 eFlagRequiresTarget,
126 "restart"),
Greg Claytoneb0103f2011-04-07 22:46:35 +0000127 m_options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000128 {
Caroline Tice405fe672010-10-04 22:28:36 +0000129 CommandArgumentEntry arg;
130 CommandArgumentData run_args_arg;
131
132 // Define the first (and only) variant of this arg.
133 run_args_arg.arg_type = eArgTypeRunArgs;
134 run_args_arg.arg_repetition = eArgRepeatOptional;
135
136 // There is only one variant this argument could be; put it into the argument entry.
137 arg.push_back (run_args_arg);
138
139 // Push the data for the first argument into the m_arguments vector.
140 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000141 }
142
143
144 ~CommandObjectProcessLaunch ()
145 {
146 }
147
Greg Claytonc7bece562013-01-25 18:06:21 +0000148 virtual int
Jim Inghame9ce62b2012-08-10 21:48:41 +0000149 HandleArgumentCompletion (Args &input,
150 int &cursor_index,
151 int &cursor_char_position,
152 OptionElementVector &opt_element_vector,
153 int match_start_point,
154 int max_return_elements,
155 bool &word_complete,
156 StringList &matches)
157 {
158 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
159 completion_str.erase (cursor_char_position);
160
161 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
162 CommandCompletions::eDiskFileCompletion,
163 completion_str.c_str(),
164 match_start_point,
165 max_return_elements,
166 NULL,
167 word_complete,
168 matches);
169 return matches.GetSize();
170 }
171
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000172 Options *
173 GetOptions ()
174 {
175 return &m_options;
176 }
177
Jim Ingham5a988412012-06-08 21:56:10 +0000178 virtual const char *GetRepeatCommand (Args &current_command_args, uint32_t index)
179 {
180 // No repeat for "process launch"...
181 return "";
182 }
183
184protected:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000185 bool
Jim Ingham5a988412012-06-08 21:56:10 +0000186 DoExecute (Args& launch_args, CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000187 {
Greg Clayton1d885962011-11-08 02:43:13 +0000188 Debugger &debugger = m_interpreter.GetDebugger();
189 Target *target = debugger.GetSelectedTarget().get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000190 // If our listener is NULL, users aren't allows to launch
Greg Claytonb09c5382013-12-13 17:20:18 +0000191 ModuleSP exe_module_sp = target->GetExecutableModule();
Greg Clayton71337622011-02-24 22:24:29 +0000192
Greg Claytonb09c5382013-12-13 17:20:18 +0000193 if (exe_module_sp == NULL)
Greg Clayton71337622011-02-24 22:24:29 +0000194 {
Greg Claytoneffe5c92011-05-03 22:09:39 +0000195 result.AppendError ("no file in target, create a debug target using the 'target create' command");
Greg Clayton71337622011-02-24 22:24:29 +0000196 result.SetStatus (eReturnStatusFailed);
197 return false;
198 }
199
Greg Clayton71337622011-02-24 22:24:29 +0000200 StateType state = eStateInvalid;
Greg Clayton71337622011-02-24 22:24:29 +0000201
Greg Claytonb09c5382013-12-13 17:20:18 +0000202 if (!StopProcessIfNecessary(m_exe_ctx.GetProcessPtr(), state, result))
Jim Inghamdcb1d852013-03-29 00:56:30 +0000203 return false;
Jim Inghambb9caf72010-12-09 18:58:16 +0000204
Greg Clayton45392552012-10-17 22:57:12 +0000205 const char *target_settings_argv0 = target->GetArg0();
206
Greg Claytonb09c5382013-12-13 17:20:18 +0000207 if (target->GetDisableASLR())
208 m_options.launch_info.GetFlags().Set (eLaunchFlagDisableASLR);
Greg Clayton45392552012-10-17 22:57:12 +0000209
Greg Claytonb09c5382013-12-13 17:20:18 +0000210 if (target->GetDisableSTDIO())
211 m_options.launch_info.GetFlags().Set (eLaunchFlagDisableSTDIO);
212
213 Args environment;
214 target->GetEnvironmentAsArgs (environment);
215 if (environment.GetArgumentCount() > 0)
216 m_options.launch_info.GetEnvironmentEntries ().AppendArguments (environment);
217
Greg Clayton45392552012-10-17 22:57:12 +0000218 if (target_settings_argv0)
219 {
220 m_options.launch_info.GetArguments().AppendArgument (target_settings_argv0);
Greg Claytonb09c5382013-12-13 17:20:18 +0000221 m_options.launch_info.SetExecutableFile(exe_module_sp->GetPlatformFileSpec(), false);
Greg Clayton45392552012-10-17 22:57:12 +0000222 }
223 else
224 {
Greg Claytonb09c5382013-12-13 17:20:18 +0000225 m_options.launch_info.SetExecutableFile(exe_module_sp->GetPlatformFileSpec(), true);
Greg Clayton45392552012-10-17 22:57:12 +0000226 }
227
Greg Clayton144f3a92011-11-15 03:53:30 +0000228 if (launch_args.GetArgumentCount() == 0)
229 {
Greg Clayton67cc0632012-08-22 17:17:09 +0000230 Args target_setting_args;
Greg Clayton45392552012-10-17 22:57:12 +0000231 if (target->GetRunArguments(target_setting_args))
Greg Clayton67cc0632012-08-22 17:17:09 +0000232 m_options.launch_info.GetArguments().AppendArguments (target_setting_args);
Greg Clayton144f3a92011-11-15 03:53:30 +0000233 }
234 else
Greg Clayton1d885962011-11-08 02:43:13 +0000235 {
Greg Clayton45392552012-10-17 22:57:12 +0000236 m_options.launch_info.GetArguments().AppendArguments (launch_args);
Greg Clayton162b5972011-11-21 21:51:18 +0000237 // Save the arguments for subsequent runs in the current target.
238 target->SetRunArguments (launch_args);
Greg Clayton1d885962011-11-08 02:43:13 +0000239 }
Greg Clayton1d885962011-11-08 02:43:13 +0000240
Greg Claytonb09c5382013-12-13 17:20:18 +0000241 Error error = target->Launch(debugger.GetListener(), m_options.launch_info);
Jim Inghamdcb1d852013-03-29 00:56:30 +0000242
Greg Claytona7015092010-09-18 01:14:36 +0000243 if (error.Success())
244 {
Greg Claytonb09c5382013-12-13 17:20:18 +0000245 const char *archname = exe_module_sp->GetArchitecture().GetArchitectureName();
246 ProcessSP process_sp (target->GetProcessSP());
247 if (process_sp)
Greg Claytona7015092010-09-18 01:14:36 +0000248 {
Greg Claytonb09c5382013-12-13 17:20:18 +0000249 result.AppendMessageWithFormat ("Process %" PRIu64 " launched: '%s' (%s)\n", process_sp->GetID(), exe_module_sp->GetFileSpec().GetPath().c_str(), archname);
250 result.SetStatus (eReturnStatusSuccessFinishResult);
251 result.SetDidChangeProcessState (true);
252 }
253 else
254 {
255 result.AppendError("no error returned from Target::Launch, and target has no process");
256 result.SetStatus (eReturnStatusFailed);
Greg Claytona7015092010-09-18 01:14:36 +0000257 }
258 }
Greg Clayton514487e2011-02-15 21:59:32 +0000259 else
260 {
Greg Claytonb09c5382013-12-13 17:20:18 +0000261 result.AppendError(error.AsCString());
Greg Clayton514487e2011-02-15 21:59:32 +0000262 result.SetStatus (eReturnStatusFailed);
263 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000264 return result.Succeeded();
265 }
266
267protected:
Greg Clayton982c9762011-11-03 21:22:33 +0000268 ProcessLaunchCommandOptions m_options;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000269};
270
271
Greg Clayton982c9762011-11-03 21:22:33 +0000272//#define SET1 LLDB_OPT_SET_1
273//#define SET2 LLDB_OPT_SET_2
274//#define SET3 LLDB_OPT_SET_3
275//
276//OptionDefinition
277//CommandObjectProcessLaunch::CommandOptions::g_option_table[] =
278//{
Virgile Belloe2607b52013-09-05 16:42:23 +0000279//{ 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."},
280//{ SET1 , false, "stdin", 'i', OptionParser::eRequiredArgument, NULL, 0, eArgTypeDirectoryName, "Redirect stdin for the process to <path>."},
281//{ SET1 , false, "stdout", 'o', OptionParser::eRequiredArgument, NULL, 0, eArgTypeDirectoryName, "Redirect stdout for the process to <path>."},
282//{ SET1 , false, "stderr", 'e', OptionParser::eRequiredArgument, NULL, 0, eArgTypeDirectoryName, "Redirect stderr for the process to <path>."},
283//{ SET1 | SET2 | SET3, false, "plugin", 'p', OptionParser::eRequiredArgument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."},
284//{ 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."},
285//{ SET3, false, "no-stdio", 'n', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Do not set up for terminal I/O to go to running process."},
286//{ SET1 | SET2 | SET3, false, "working-dir", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeDirectoryName, "Set the current working directory to <path> when running the inferior."},
Greg Clayton982c9762011-11-03 21:22:33 +0000287//{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
288//};
289//
290//#undef SET1
291//#undef SET2
292//#undef SET3
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000293
294//-------------------------------------------------------------------------
295// CommandObjectProcessAttach
296//-------------------------------------------------------------------------
Jim Inghambb9caf72010-12-09 18:58:16 +0000297#pragma mark CommandObjectProcessAttach
Jim Inghamdcb1d852013-03-29 00:56:30 +0000298class CommandObjectProcessAttach : public CommandObjectProcessLaunchOrAttach
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000299{
300public:
301
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000302 class CommandOptions : public Options
303 {
304 public:
305
Greg Claytoneb0103f2011-04-07 22:46:35 +0000306 CommandOptions (CommandInterpreter &interpreter) :
307 Options(interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000308 {
Greg Claytonf6b8b582011-04-13 00:18:08 +0000309 // Keep default values of all options in one place: OptionParsingStarting ()
310 OptionParsingStarting ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000311 }
312
313 ~CommandOptions ()
314 {
315 }
316
317 Error
Greg Claytonf6b8b582011-04-13 00:18:08 +0000318 SetOptionValue (uint32_t option_idx, const char *option_arg)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000319 {
320 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000321 const int short_option = m_getopt_table[option_idx].val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000322 bool success = false;
323 switch (short_option)
324 {
Johnny Chena95ce622012-05-24 00:43:00 +0000325 case 'c':
326 attach_info.SetContinueOnceAttached(true);
327 break;
328
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000329 case 'p':
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000330 {
Greg Clayton144f3a92011-11-15 03:53:30 +0000331 lldb::pid_t pid = Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success);
332 if (!success || pid == LLDB_INVALID_PROCESS_ID)
333 {
334 error.SetErrorStringWithFormat("invalid process ID '%s'", option_arg);
335 }
336 else
337 {
338 attach_info.SetProcessID (pid);
339 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000340 }
341 break;
342
343 case 'P':
Greg Clayton144f3a92011-11-15 03:53:30 +0000344 attach_info.SetProcessPluginName (option_arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000345 break;
346
347 case 'n':
Greg Clayton144f3a92011-11-15 03:53:30 +0000348 attach_info.GetExecutableFile().SetFile(option_arg, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000349 break;
350
351 case 'w':
Greg Clayton144f3a92011-11-15 03:53:30 +0000352 attach_info.SetWaitForLaunch(true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000353 break;
Jim Inghamcd16df92012-07-20 21:37:13 +0000354
355 case 'i':
356 attach_info.SetIgnoreExisting(false);
357 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000358
359 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000360 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000361 break;
362 }
363 return error;
364 }
365
366 void
Greg Claytonf6b8b582011-04-13 00:18:08 +0000367 OptionParsingStarting ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000368 {
Greg Clayton144f3a92011-11-15 03:53:30 +0000369 attach_info.Clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000370 }
371
Greg Claytone0d378b2011-03-24 21:19:54 +0000372 const OptionDefinition*
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000373 GetDefinitions ()
374 {
375 return g_option_table;
376 }
377
Jim Ingham5aee1622010-08-09 23:31:02 +0000378 virtual bool
Greg Claytoneb0103f2011-04-07 22:46:35 +0000379 HandleOptionArgumentCompletion (Args &input,
Jim Ingham5aee1622010-08-09 23:31:02 +0000380 int cursor_index,
381 int char_pos,
382 OptionElementVector &opt_element_vector,
383 int opt_element_index,
384 int match_start_point,
385 int max_return_elements,
386 bool &word_complete,
387 StringList &matches)
388 {
389 int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
390 int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
391
392 // We are only completing the name option for now...
393
Greg Claytone0d378b2011-03-24 21:19:54 +0000394 const OptionDefinition *opt_defs = GetDefinitions();
Jim Ingham5aee1622010-08-09 23:31:02 +0000395 if (opt_defs[opt_defs_index].short_option == 'n')
396 {
397 // Are we in the name?
398
399 // Look to see if there is a -P argument provided, and if so use that plugin, otherwise
400 // use the default plugin.
Jim Ingham5aee1622010-08-09 23:31:02 +0000401
402 const char *partial_name = NULL;
403 partial_name = input.GetArgumentAtIndex(opt_arg_pos);
Greg Claytone996fd32011-03-08 22:40:15 +0000404
Greg Clayton8b82f082011-04-12 05:54:46 +0000405 PlatformSP platform_sp (m_interpreter.GetPlatform (true));
Greg Claytone996fd32011-03-08 22:40:15 +0000406 if (platform_sp)
Jim Ingham5aee1622010-08-09 23:31:02 +0000407 {
Greg Clayton8b82f082011-04-12 05:54:46 +0000408 ProcessInstanceInfoList process_infos;
409 ProcessInstanceInfoMatch match_info;
Greg Clayton32e0a752011-03-30 18:16:51 +0000410 if (partial_name)
411 {
Greg Clayton144f3a92011-11-15 03:53:30 +0000412 match_info.GetProcessInfo().GetExecutableFile().SetFile(partial_name, false);
Greg Clayton32e0a752011-03-30 18:16:51 +0000413 match_info.SetNameMatchType(eNameMatchStartsWith);
414 }
415 platform_sp->FindProcesses (match_info, process_infos);
Greg Claytonc7bece562013-01-25 18:06:21 +0000416 const size_t num_matches = process_infos.GetSize();
Greg Claytone996fd32011-03-08 22:40:15 +0000417 if (num_matches > 0)
418 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000419 for (size_t i=0; i<num_matches; ++i)
Greg Claytone996fd32011-03-08 22:40:15 +0000420 {
421 matches.AppendString (process_infos.GetProcessNameAtIndex(i),
422 process_infos.GetProcessNameLengthAtIndex(i));
423 }
424 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000425 }
426 }
427
428 return false;
429 }
430
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000431 // Options table: Required for subclasses of Options.
432
Greg Claytone0d378b2011-03-24 21:19:54 +0000433 static OptionDefinition g_option_table[];
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000434
435 // Instance variables to hold the values for command options.
436
Greg Clayton144f3a92011-11-15 03:53:30 +0000437 ProcessAttachInfo attach_info;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000438 };
439
Greg Claytona7015092010-09-18 01:14:36 +0000440 CommandObjectProcessAttach (CommandInterpreter &interpreter) :
Jim Inghamdcb1d852013-03-29 00:56:30 +0000441 CommandObjectProcessLaunchOrAttach (interpreter,
442 "process attach",
443 "Attach to a process.",
444 "process attach <cmd-options>",
445 0,
446 "attach"),
Greg Claytoneb0103f2011-04-07 22:46:35 +0000447 m_options (interpreter)
Jim Ingham5aee1622010-08-09 23:31:02 +0000448 {
Jim Ingham5aee1622010-08-09 23:31:02 +0000449 }
450
451 ~CommandObjectProcessAttach ()
452 {
453 }
454
Jim Ingham5a988412012-06-08 21:56:10 +0000455 Options *
456 GetOptions ()
457 {
458 return &m_options;
459 }
460
461protected:
Jim Ingham5aee1622010-08-09 23:31:02 +0000462 bool
Jim Ingham5a988412012-06-08 21:56:10 +0000463 DoExecute (Args& command,
Jim Ingham5aee1622010-08-09 23:31:02 +0000464 CommandReturnObject &result)
465 {
Greg Claytona7015092010-09-18 01:14:36 +0000466 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Jim Ingham31412642011-09-15 01:08:57 +0000467 // N.B. The attach should be synchronous. It doesn't help much to get the prompt back between initiating the attach
468 // and the target actually stopping. So even if the interpreter is set to be asynchronous, we wait for the stop
469 // ourselves here.
Jim Inghambb3a2832011-01-29 01:49:25 +0000470
Greg Clayton71337622011-02-24 22:24:29 +0000471 StateType state = eStateInvalid;
Jim Inghamdcb1d852013-03-29 00:56:30 +0000472 Process *process = m_exe_ctx.GetProcessPtr();
473
474 if (!StopProcessIfNecessary (process, state, result))
475 return false;
476
Jim Ingham5aee1622010-08-09 23:31:02 +0000477 if (target == NULL)
478 {
479 // If there isn't a current target create one.
480 TargetSP new_target_sp;
Jim Ingham5aee1622010-08-09 23:31:02 +0000481 Error error;
482
Greg Claytona7015092010-09-18 01:14:36 +0000483 error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(),
Greg Claytona0ca6602012-10-18 16:33:33 +0000484 NULL,
Greg Claytoncac9c5f2011-09-24 00:52:29 +0000485 NULL,
Greg Claytona7015092010-09-18 01:14:36 +0000486 false,
Greg Claytoncac9c5f2011-09-24 00:52:29 +0000487 NULL, // No platform options
Greg Claytona7015092010-09-18 01:14:36 +0000488 new_target_sp);
Jim Ingham5aee1622010-08-09 23:31:02 +0000489 target = new_target_sp.get();
490 if (target == NULL || error.Fail())
491 {
Greg Claytonb766a732011-02-04 01:58:07 +0000492 result.AppendError(error.AsCString("Error creating target"));
Jim Ingham5aee1622010-08-09 23:31:02 +0000493 return false;
494 }
Greg Claytona7015092010-09-18 01:14:36 +0000495 m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target);
Jim Ingham5aee1622010-08-09 23:31:02 +0000496 }
497
498 // Record the old executable module, we want to issue a warning if the process of attaching changed the
499 // current executable (like somebody said "file foo" then attached to a PID whose executable was bar.)
500
501 ModuleSP old_exec_module_sp = target->GetExecutableModule();
502 ArchSpec old_arch_spec = target->GetArchitecture();
503
504 if (command.GetArgumentCount())
505 {
Jason Molendafd54b362011-09-20 21:44:10 +0000506 result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
Jim Ingham5aee1622010-08-09 23:31:02 +0000507 result.SetStatus (eReturnStatusFailed);
508 }
509 else
510 {
Greg Clayton71337622011-02-24 22:24:29 +0000511 if (state != eStateConnected)
512 {
Greg Clayton144f3a92011-11-15 03:53:30 +0000513 const char *plugin_name = m_options.attach_info.GetProcessPluginName();
Greg Claytonc3776bf2012-02-09 06:16:32 +0000514 process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name, NULL).get();
Greg Clayton71337622011-02-24 22:24:29 +0000515 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000516
517 if (process)
518 {
519 Error error;
Greg Clayton144f3a92011-11-15 03:53:30 +0000520 // If no process info was specified, then use the target executable
521 // name as the process to attach to by default
522 if (!m_options.attach_info.ProcessInfoSpecified ())
Jim Ingham3a0b9cd2010-09-15 01:34:14 +0000523 {
524 if (old_exec_module_sp)
Greg Claytonad9e8282011-11-29 04:03:30 +0000525 m_options.attach_info.GetExecutableFile().GetFilename() = old_exec_module_sp->GetPlatformFileSpec().GetFilename();
Jim Ingham3a0b9cd2010-09-15 01:34:14 +0000526
Greg Clayton144f3a92011-11-15 03:53:30 +0000527 if (!m_options.attach_info.ProcessInfoSpecified ())
528 {
529 error.SetErrorString ("no process specified, create a target with a file, or specify the --pid or --name command option");
530 }
531 }
532
533 if (error.Success())
534 {
535 error = process->Attach (m_options.attach_info);
536
Jim Ingham3a0b9cd2010-09-15 01:34:14 +0000537 if (error.Success())
538 {
539 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
540 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000541 else
542 {
Greg Clayton144f3a92011-11-15 03:53:30 +0000543 result.AppendErrorWithFormat ("attach failed: %s\n", error.AsCString());
Jim Ingham3a0b9cd2010-09-15 01:34:14 +0000544 result.SetStatus (eReturnStatusFailed);
545 return false;
Jim Ingham5aee1622010-08-09 23:31:02 +0000546 }
Jim Inghambb3a2832011-01-29 01:49:25 +0000547 // If we're synchronous, wait for the stopped event and report that.
548 // Otherwise just return.
549 // FIXME: in the async case it will now be possible to get to the command
550 // interpreter with a state eStateAttaching. Make sure we handle that correctly.
Jim Ingham31412642011-09-15 01:08:57 +0000551 StateType state = process->WaitForProcessToStop (NULL);
Greg Clayton144f3a92011-11-15 03:53:30 +0000552
Jim Ingham31412642011-09-15 01:08:57 +0000553 result.SetDidChangeProcessState (true);
Johnny Chenaa739092012-05-18 00:51:36 +0000554
555 if (state == eStateStopped)
556 {
Daniel Malead01b2952012-11-29 21:49:15 +0000557 result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
Johnny Chenaa739092012-05-18 00:51:36 +0000558 result.SetStatus (eReturnStatusSuccessFinishNoResult);
559 }
560 else
561 {
562 result.AppendError ("attach failed: process did not stop (no such process or permission problem?)");
Jim Inghamcfc09352012-07-27 23:57:19 +0000563 process->Destroy();
Johnny Chenaa739092012-05-18 00:51:36 +0000564 result.SetStatus (eReturnStatusFailed);
565 return false;
566 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000567 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000568 }
569 }
570
571 if (result.Succeeded())
572 {
573 // Okay, we're done. Last step is to warn if the executable module has changed:
Greg Clayton513c26c2011-01-29 07:10:55 +0000574 char new_path[PATH_MAX];
Greg Claytonaa149cb2011-08-11 02:48:45 +0000575 ModuleSP new_exec_module_sp (target->GetExecutableModule());
Jim Ingham5aee1622010-08-09 23:31:02 +0000576 if (!old_exec_module_sp)
577 {
Greg Clayton513c26c2011-01-29 07:10:55 +0000578 // We might not have a module if we attached to a raw pid...
Greg Claytonaa149cb2011-08-11 02:48:45 +0000579 if (new_exec_module_sp)
Greg Clayton513c26c2011-01-29 07:10:55 +0000580 {
Greg Claytonaa149cb2011-08-11 02:48:45 +0000581 new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX);
Greg Clayton513c26c2011-01-29 07:10:55 +0000582 result.AppendMessageWithFormat("Executable module set to \"%s\".\n", new_path);
583 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000584 }
Greg Claytonaa149cb2011-08-11 02:48:45 +0000585 else if (old_exec_module_sp->GetFileSpec() != new_exec_module_sp->GetFileSpec())
Jim Ingham5aee1622010-08-09 23:31:02 +0000586 {
Greg Clayton513c26c2011-01-29 07:10:55 +0000587 char old_path[PATH_MAX];
Jim Ingham5aee1622010-08-09 23:31:02 +0000588
Greg Claytonaa149cb2011-08-11 02:48:45 +0000589 old_exec_module_sp->GetFileSpec().GetPath (old_path, PATH_MAX);
590 new_exec_module_sp->GetFileSpec().GetPath (new_path, PATH_MAX);
Jim Ingham5aee1622010-08-09 23:31:02 +0000591
592 result.AppendWarningWithFormat("Executable module changed from \"%s\" to \"%s\".\n",
593 old_path, new_path);
594 }
595
596 if (!old_arch_spec.IsValid())
597 {
Greg Claytonc1b1f1e2012-09-14 02:41:36 +0000598 result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().GetTriple().getTriple().c_str());
Jim Ingham5aee1622010-08-09 23:31:02 +0000599 }
Sean Callananbf4b7be2012-12-13 22:07:14 +0000600 else if (!old_arch_spec.IsExactMatch(target->GetArchitecture()))
Jim Ingham5aee1622010-08-09 23:31:02 +0000601 {
602 result.AppendWarningWithFormat("Architecture changed from %s to %s.\n",
Greg Claytonc1b1f1e2012-09-14 02:41:36 +0000603 old_arch_spec.GetTriple().getTriple().c_str(),
604 target->GetArchitecture().GetTriple().getTriple().c_str());
Jim Ingham5aee1622010-08-09 23:31:02 +0000605 }
Johnny Chena95ce622012-05-24 00:43:00 +0000606
607 // This supports the use-case scenario of immediately continuing the process once attached.
608 if (m_options.attach_info.GetContinueOnceAttached())
Sean Callanan5bcaf582012-05-31 01:30:08 +0000609 m_interpreter.HandleCommand("process continue", eLazyBoolNo, result);
Jim Ingham5aee1622010-08-09 23:31:02 +0000610 }
611 return result.Succeeded();
612 }
613
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000614 CommandOptions m_options;
615};
616
617
Greg Claytone0d378b2011-03-24 21:19:54 +0000618OptionDefinition
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000619CommandObjectProcessAttach::CommandOptions::g_option_table[] =
620{
Virgile Belloe2607b52013-09-05 16:42:23 +0000621{ LLDB_OPT_SET_ALL, false, "continue",'c', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Immediately continue the process once attached."},
622{ LLDB_OPT_SET_ALL, false, "plugin", 'P', OptionParser::eRequiredArgument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."},
623{ LLDB_OPT_SET_1, false, "pid", 'p', OptionParser::eRequiredArgument, NULL, 0, eArgTypePid, "The process ID of an existing process to attach to."},
624{ LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, NULL, 0, eArgTypeProcessName, "The name of the process to attach to."},
625{ LLDB_OPT_SET_2, false, "include-existing", 'i', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Include existing processes when doing attach -w."},
626{ LLDB_OPT_SET_2, false, "waitfor", 'w', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Wait for the process with <process-name> to launch."},
Caroline Ticedeaab222010-10-01 19:59:14 +0000627{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000628};
629
630//-------------------------------------------------------------------------
631// CommandObjectProcessContinue
632//-------------------------------------------------------------------------
Jim Inghambb9caf72010-12-09 18:58:16 +0000633#pragma mark CommandObjectProcessContinue
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000634
Jim Ingham5a988412012-06-08 21:56:10 +0000635class CommandObjectProcessContinue : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000636{
637public:
638
Greg Claytona7015092010-09-18 01:14:36 +0000639 CommandObjectProcessContinue (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000640 CommandObjectParsed (interpreter,
641 "process continue",
642 "Continue execution of all threads in the current process.",
643 "process continue",
Greg Claytonf9fc6092013-01-09 19:44:40 +0000644 eFlagRequiresProcess |
645 eFlagTryTargetAPILock |
646 eFlagProcessMustBeLaunched |
647 eFlagProcessMustBePaused ),
Jim Ingham0e410842012-08-11 01:27:55 +0000648 m_options(interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000649 {
650 }
651
652
653 ~CommandObjectProcessContinue ()
654 {
655 }
656
Jim Ingham5a988412012-06-08 21:56:10 +0000657protected:
Jim Ingham0e410842012-08-11 01:27:55 +0000658
659 class CommandOptions : public Options
660 {
661 public:
662
663 CommandOptions (CommandInterpreter &interpreter) :
664 Options(interpreter)
665 {
666 // Keep default values of all options in one place: OptionParsingStarting ()
667 OptionParsingStarting ();
668 }
669
670 ~CommandOptions ()
671 {
672 }
673
674 Error
675 SetOptionValue (uint32_t option_idx, const char *option_arg)
676 {
677 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000678 const int short_option = m_getopt_table[option_idx].val;
Jim Ingham0e410842012-08-11 01:27:55 +0000679 bool success = false;
680 switch (short_option)
681 {
682 case 'i':
683 m_ignore = Args::StringToUInt32 (option_arg, 0, 0, &success);
684 if (!success)
685 error.SetErrorStringWithFormat ("invalid value for ignore option: \"%s\", should be a number.", option_arg);
686 break;
687
688 default:
689 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
690 break;
691 }
692 return error;
693 }
694
695 void
696 OptionParsingStarting ()
697 {
698 m_ignore = 0;
699 }
700
701 const OptionDefinition*
702 GetDefinitions ()
703 {
704 return g_option_table;
705 }
706
707 // Options table: Required for subclasses of Options.
708
709 static OptionDefinition g_option_table[];
710
711 uint32_t m_ignore;
712 };
713
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000714 bool
Greg Claytonf9fc6092013-01-09 19:44:40 +0000715 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000716 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000717 Process *process = m_exe_ctx.GetProcessPtr();
Greg Claytona7015092010-09-18 01:14:36 +0000718 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000719 StateType state = process->GetState();
720 if (state == eStateStopped)
721 {
722 if (command.GetArgumentCount() != 0)
723 {
724 result.AppendErrorWithFormat ("The '%s' command does not take any arguments.\n", m_cmd_name.c_str());
725 result.SetStatus (eReturnStatusFailed);
726 return false;
727 }
728
Jim Ingham0e410842012-08-11 01:27:55 +0000729 if (m_options.m_ignore > 0)
730 {
731 ThreadSP sel_thread_sp(process->GetThreadList().GetSelectedThread());
732 if (sel_thread_sp)
733 {
734 StopInfoSP stop_info_sp = sel_thread_sp->GetStopInfo();
735 if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonBreakpoint)
736 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000737 lldb::break_id_t bp_site_id = (lldb::break_id_t)stop_info_sp->GetValue();
Jim Ingham0e410842012-08-11 01:27:55 +0000738 BreakpointSiteSP bp_site_sp(process->GetBreakpointSiteList().FindByID(bp_site_id));
739 if (bp_site_sp)
740 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000741 const size_t num_owners = bp_site_sp->GetNumberOfOwners();
742 for (size_t i = 0; i < num_owners; i++)
Jim Ingham0e410842012-08-11 01:27:55 +0000743 {
744 Breakpoint &bp_ref = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
745 if (!bp_ref.IsInternal())
746 {
747 bp_ref.SetIgnoreCount(m_options.m_ignore);
748 }
749 }
750 }
751 }
752 }
753 }
754
Jim Ingham41f2b942012-09-10 20:50:15 +0000755 { // Scope for thread list mutex:
756 Mutex::Locker locker (process->GetThreadList().GetMutex());
757 const uint32_t num_threads = process->GetThreadList().GetSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000758
Jim Ingham41f2b942012-09-10 20:50:15 +0000759 // Set the actions that the threads should each take when resuming
760 for (uint32_t idx=0; idx<num_threads; ++idx)
761 {
762 process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState (eStateRunning);
763 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000764 }
Jim Ingham41f2b942012-09-10 20:50:15 +0000765
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000766 Error error(process->Resume());
767 if (error.Success())
768 {
Daniel Malead01b2952012-11-29 21:49:15 +0000769 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000770 if (synchronous_execution)
771 {
Greg Claytonb1320972010-07-14 00:18:15 +0000772 state = process->WaitForProcessToStop (NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000773
774 result.SetDidChangeProcessState (true);
Daniel Malead01b2952012-11-29 21:49:15 +0000775 result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000776 result.SetStatus (eReturnStatusSuccessFinishNoResult);
777 }
778 else
779 {
780 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
781 }
782 }
783 else
784 {
785 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
786 result.SetStatus (eReturnStatusFailed);
787 }
788 }
789 else
790 {
791 result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
792 StateAsCString(state));
793 result.SetStatus (eReturnStatusFailed);
794 }
795 return result.Succeeded();
796 }
Jim Ingham0e410842012-08-11 01:27:55 +0000797
798 Options *
799 GetOptions ()
800 {
801 return &m_options;
802 }
803
804 CommandOptions m_options;
805
806};
807
808OptionDefinition
809CommandObjectProcessContinue::CommandOptions::g_option_table[] =
810{
Virgile Belloe2607b52013-09-05 16:42:23 +0000811{ LLDB_OPT_SET_ALL, false, "ignore-count",'i', OptionParser::eRequiredArgument, NULL, 0, eArgTypeUnsignedInteger,
Jim Ingham0e410842012-08-11 01:27:55 +0000812 "Ignore <N> crossings of the breakpoint (if it exists) for the currently selected thread."},
813{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000814};
815
816//-------------------------------------------------------------------------
817// CommandObjectProcessDetach
818//-------------------------------------------------------------------------
Jim Inghambb9caf72010-12-09 18:58:16 +0000819#pragma mark CommandObjectProcessDetach
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000820
Jim Ingham5a988412012-06-08 21:56:10 +0000821class CommandObjectProcessDetach : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000822{
823public:
Jim Inghamacff8952013-05-02 00:27:30 +0000824 class CommandOptions : public Options
825 {
826 public:
827
828 CommandOptions (CommandInterpreter &interpreter) :
829 Options (interpreter)
830 {
831 OptionParsingStarting ();
832 }
833
834 ~CommandOptions ()
835 {
836 }
837
838 Error
839 SetOptionValue (uint32_t option_idx, const char *option_arg)
840 {
841 Error error;
842 const int short_option = m_getopt_table[option_idx].val;
843
844 switch (short_option)
845 {
846 case 's':
847 bool tmp_result;
848 bool success;
849 tmp_result = Args::StringToBoolean(option_arg, false, &success);
850 if (!success)
851 error.SetErrorStringWithFormat("invalid boolean option: \"%s\"", option_arg);
852 else
853 {
854 if (tmp_result)
855 m_keep_stopped = eLazyBoolYes;
856 else
857 m_keep_stopped = eLazyBoolNo;
858 }
859 break;
860 default:
861 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
862 break;
863 }
864 return error;
865 }
866
867 void
868 OptionParsingStarting ()
869 {
870 m_keep_stopped = eLazyBoolCalculate;
871 }
872
873 const OptionDefinition*
874 GetDefinitions ()
875 {
876 return g_option_table;
877 }
878
879 // Options table: Required for subclasses of Options.
880
881 static OptionDefinition g_option_table[];
882
883 // Instance variables to hold the values for command options.
884 LazyBool m_keep_stopped;
885 };
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000886
Greg Claytona7015092010-09-18 01:14:36 +0000887 CommandObjectProcessDetach (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000888 CommandObjectParsed (interpreter,
889 "process detach",
890 "Detach from the current process being debugged.",
891 "process detach",
Greg Claytonf9fc6092013-01-09 19:44:40 +0000892 eFlagRequiresProcess |
893 eFlagTryTargetAPILock |
Jim Inghamacff8952013-05-02 00:27:30 +0000894 eFlagProcessMustBeLaunched),
895 m_options(interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000896 {
897 }
898
899 ~CommandObjectProcessDetach ()
900 {
901 }
902
Jim Inghamacff8952013-05-02 00:27:30 +0000903 Options *
904 GetOptions ()
905 {
906 return &m_options;
907 }
908
909
Jim Ingham5a988412012-06-08 21:56:10 +0000910protected:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000911 bool
Greg Claytonf9fc6092013-01-09 19:44:40 +0000912 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000913 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000914 Process *process = m_exe_ctx.GetProcessPtr();
Daniel Malead01b2952012-11-29 21:49:15 +0000915 result.AppendMessageWithFormat ("Detaching from process %" PRIu64 "\n", process->GetID());
Jim Inghamacff8952013-05-02 00:27:30 +0000916 // FIXME: This will be a Command Option:
917 bool keep_stopped;
918 if (m_options.m_keep_stopped == eLazyBoolCalculate)
919 {
920 // Check the process default:
921 if (process->GetDetachKeepsStopped())
922 keep_stopped = true;
923 else
924 keep_stopped = false;
925 }
926 else if (m_options.m_keep_stopped == eLazyBoolYes)
927 keep_stopped = true;
928 else
929 keep_stopped = false;
930
931 Error error (process->Detach(keep_stopped));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000932 if (error.Success())
933 {
934 result.SetStatus (eReturnStatusSuccessFinishResult);
935 }
936 else
937 {
938 result.AppendErrorWithFormat ("Detach failed: %s\n", error.AsCString());
939 result.SetStatus (eReturnStatusFailed);
940 return false;
941 }
942 return result.Succeeded();
943 }
Jim Inghamacff8952013-05-02 00:27:30 +0000944
945 CommandOptions m_options;
946};
947
948OptionDefinition
949CommandObjectProcessDetach::CommandOptions::g_option_table[] =
950{
Virgile Belloe2607b52013-09-05 16:42:23 +0000951{ LLDB_OPT_SET_1, false, "keep-stopped", 's', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "Whether or not the process should be kept stopped on detach (if possible)." },
Jim Inghamacff8952013-05-02 00:27:30 +0000952{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000953};
954
955//-------------------------------------------------------------------------
Greg Claytonb766a732011-02-04 01:58:07 +0000956// CommandObjectProcessConnect
957//-------------------------------------------------------------------------
958#pragma mark CommandObjectProcessConnect
959
Jim Ingham5a988412012-06-08 21:56:10 +0000960class CommandObjectProcessConnect : public CommandObjectParsed
Greg Claytonb766a732011-02-04 01:58:07 +0000961{
962public:
963
964 class CommandOptions : public Options
965 {
966 public:
967
Greg Claytoneb0103f2011-04-07 22:46:35 +0000968 CommandOptions (CommandInterpreter &interpreter) :
969 Options(interpreter)
Greg Claytonb766a732011-02-04 01:58:07 +0000970 {
Greg Claytonf6b8b582011-04-13 00:18:08 +0000971 // Keep default values of all options in one place: OptionParsingStarting ()
972 OptionParsingStarting ();
Greg Claytonb766a732011-02-04 01:58:07 +0000973 }
974
975 ~CommandOptions ()
976 {
977 }
978
979 Error
Greg Claytonf6b8b582011-04-13 00:18:08 +0000980 SetOptionValue (uint32_t option_idx, const char *option_arg)
Greg Claytonb766a732011-02-04 01:58:07 +0000981 {
982 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000983 const int short_option = m_getopt_table[option_idx].val;
Greg Claytonb766a732011-02-04 01:58:07 +0000984
985 switch (short_option)
986 {
987 case 'p':
988 plugin_name.assign (option_arg);
989 break;
990
991 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000992 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Greg Claytonb766a732011-02-04 01:58:07 +0000993 break;
994 }
995 return error;
996 }
997
998 void
Greg Claytonf6b8b582011-04-13 00:18:08 +0000999 OptionParsingStarting ()
Greg Claytonb766a732011-02-04 01:58:07 +00001000 {
Greg Claytonb766a732011-02-04 01:58:07 +00001001 plugin_name.clear();
1002 }
1003
Greg Claytone0d378b2011-03-24 21:19:54 +00001004 const OptionDefinition*
Greg Claytonb766a732011-02-04 01:58:07 +00001005 GetDefinitions ()
1006 {
1007 return g_option_table;
1008 }
1009
1010 // Options table: Required for subclasses of Options.
1011
Greg Claytone0d378b2011-03-24 21:19:54 +00001012 static OptionDefinition g_option_table[];
Greg Claytonb766a732011-02-04 01:58:07 +00001013
1014 // Instance variables to hold the values for command options.
1015
1016 std::string plugin_name;
1017 };
1018
1019 CommandObjectProcessConnect (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001020 CommandObjectParsed (interpreter,
1021 "process connect",
1022 "Connect to a remote debug service.",
1023 "process connect <remote-url>",
1024 0),
Greg Claytoneb0103f2011-04-07 22:46:35 +00001025 m_options (interpreter)
Greg Claytonb766a732011-02-04 01:58:07 +00001026 {
1027 }
1028
1029 ~CommandObjectProcessConnect ()
1030 {
1031 }
1032
1033
Jim Ingham5a988412012-06-08 21:56:10 +00001034 Options *
1035 GetOptions ()
1036 {
1037 return &m_options;
1038 }
1039
1040protected:
Greg Claytonb766a732011-02-04 01:58:07 +00001041 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001042 DoExecute (Args& command,
Greg Claytonb766a732011-02-04 01:58:07 +00001043 CommandReturnObject &result)
1044 {
1045
1046 TargetSP target_sp (m_interpreter.GetDebugger().GetSelectedTarget());
1047 Error error;
Greg Claytonf9fc6092013-01-09 19:44:40 +00001048 Process *process = m_exe_ctx.GetProcessPtr();
Greg Claytonb766a732011-02-04 01:58:07 +00001049 if (process)
1050 {
1051 if (process->IsAlive())
1052 {
Daniel Malead01b2952012-11-29 21:49:15 +00001053 result.AppendErrorWithFormat ("Process %" PRIu64 " is currently being debugged, kill the process before connecting.\n",
Greg Claytonb766a732011-02-04 01:58:07 +00001054 process->GetID());
1055 result.SetStatus (eReturnStatusFailed);
1056 return false;
1057 }
1058 }
1059
1060 if (!target_sp)
1061 {
1062 // If there isn't a current target create one.
Greg Claytonb766a732011-02-04 01:58:07 +00001063
1064 error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(),
Greg Claytona0ca6602012-10-18 16:33:33 +00001065 NULL,
Greg Claytoncac9c5f2011-09-24 00:52:29 +00001066 NULL,
Greg Claytonb766a732011-02-04 01:58:07 +00001067 false,
Greg Claytoncac9c5f2011-09-24 00:52:29 +00001068 NULL, // No platform options
Greg Claytonb766a732011-02-04 01:58:07 +00001069 target_sp);
1070 if (!target_sp || error.Fail())
1071 {
1072 result.AppendError(error.AsCString("Error creating target"));
1073 result.SetStatus (eReturnStatusFailed);
1074 return false;
1075 }
1076 m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target_sp.get());
1077 }
1078
1079 if (command.GetArgumentCount() == 1)
1080 {
1081 const char *plugin_name = NULL;
1082 if (!m_options.plugin_name.empty())
1083 plugin_name = m_options.plugin_name.c_str();
1084
1085 const char *remote_url = command.GetArgumentAtIndex(0);
Greg Claytonc3776bf2012-02-09 06:16:32 +00001086 process = target_sp->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name, NULL).get();
Greg Claytonb766a732011-02-04 01:58:07 +00001087
1088 if (process)
1089 {
Jason Molenda4bd4e7e2012-09-29 04:02:01 +00001090 error = process->ConnectRemote (&process->GetTarget().GetDebugger().GetOutputStream(), remote_url);
Greg Claytonb766a732011-02-04 01:58:07 +00001091
1092 if (error.Fail())
1093 {
1094 result.AppendError(error.AsCString("Remote connect failed"));
1095 result.SetStatus (eReturnStatusFailed);
Greg Clayton1517dd32012-03-31 00:10:30 +00001096 target_sp->DeleteCurrentProcess();
Greg Claytonb766a732011-02-04 01:58:07 +00001097 return false;
1098 }
1099 }
1100 else
1101 {
Jason Molendafd54b362011-09-20 21:44:10 +00001102 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",
Daniel Maleaf00b7512012-12-18 20:00:40 +00001103 remote_url);
Greg Claytonb766a732011-02-04 01:58:07 +00001104 result.SetStatus (eReturnStatusFailed);
1105 }
1106 }
1107 else
1108 {
Jason Molendafd54b362011-09-20 21:44:10 +00001109 result.AppendErrorWithFormat ("'%s' takes exactly one argument:\nUsage: %s\n",
Greg Claytonb766a732011-02-04 01:58:07 +00001110 m_cmd_name.c_str(),
1111 m_cmd_syntax.c_str());
1112 result.SetStatus (eReturnStatusFailed);
1113 }
1114 return result.Succeeded();
1115 }
Greg Claytonb766a732011-02-04 01:58:07 +00001116
1117 CommandOptions m_options;
1118};
1119
Greg Claytone0d378b2011-03-24 21:19:54 +00001120OptionDefinition
Greg Claytonb766a732011-02-04 01:58:07 +00001121CommandObjectProcessConnect::CommandOptions::g_option_table[] =
1122{
Virgile Belloe2607b52013-09-05 16:42:23 +00001123 { LLDB_OPT_SET_ALL, false, "plugin", 'p', OptionParser::eRequiredArgument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."},
Greg Claytonb766a732011-02-04 01:58:07 +00001124 { 0, false, NULL, 0 , 0, NULL, 0, eArgTypeNone, NULL }
1125};
1126
1127//-------------------------------------------------------------------------
Greg Clayton998255b2012-10-13 02:07:45 +00001128// CommandObjectProcessPlugin
1129//-------------------------------------------------------------------------
1130#pragma mark CommandObjectProcessPlugin
1131
1132class CommandObjectProcessPlugin : public CommandObjectProxy
1133{
1134public:
1135
1136 CommandObjectProcessPlugin (CommandInterpreter &interpreter) :
1137 CommandObjectProxy (interpreter,
1138 "process plugin",
1139 "Send a custom command to the current process plug-in.",
1140 "process plugin <args>",
1141 0)
1142 {
1143 }
1144
1145 ~CommandObjectProcessPlugin ()
1146 {
1147 }
1148
1149 virtual CommandObject *
1150 GetProxyCommandObject()
1151 {
Greg Claytone05b2ef2013-01-09 22:58:18 +00001152 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Greg Clayton998255b2012-10-13 02:07:45 +00001153 if (process)
1154 return process->GetPluginCommandObject();
1155 return NULL;
1156 }
1157};
1158
1159
1160//-------------------------------------------------------------------------
Greg Clayton8f343b02010-11-04 01:54:29 +00001161// CommandObjectProcessLoad
1162//-------------------------------------------------------------------------
Jim Inghambb9caf72010-12-09 18:58:16 +00001163#pragma mark CommandObjectProcessLoad
Greg Clayton8f343b02010-11-04 01:54:29 +00001164
Jim Ingham5a988412012-06-08 21:56:10 +00001165class CommandObjectProcessLoad : public CommandObjectParsed
Greg Clayton8f343b02010-11-04 01:54:29 +00001166{
1167public:
1168
1169 CommandObjectProcessLoad (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001170 CommandObjectParsed (interpreter,
1171 "process load",
1172 "Load a shared library into the current process.",
1173 "process load <filename> [<filename> ...]",
Greg Claytonf9fc6092013-01-09 19:44:40 +00001174 eFlagRequiresProcess |
1175 eFlagTryTargetAPILock |
1176 eFlagProcessMustBeLaunched |
1177 eFlagProcessMustBePaused )
Greg Clayton8f343b02010-11-04 01:54:29 +00001178 {
1179 }
1180
1181 ~CommandObjectProcessLoad ()
1182 {
1183 }
1184
Jim Ingham5a988412012-06-08 21:56:10 +00001185protected:
Greg Clayton8f343b02010-11-04 01:54:29 +00001186 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001187 DoExecute (Args& command,
Greg Clayton8f343b02010-11-04 01:54:29 +00001188 CommandReturnObject &result)
1189 {
Greg Claytonf9fc6092013-01-09 19:44:40 +00001190 Process *process = m_exe_ctx.GetProcessPtr();
Greg Clayton8f343b02010-11-04 01:54:29 +00001191
Greg Claytonc7bece562013-01-25 18:06:21 +00001192 const size_t argc = command.GetArgumentCount();
Greg Clayton8f343b02010-11-04 01:54:29 +00001193
1194 for (uint32_t i=0; i<argc; ++i)
1195 {
1196 Error error;
1197 const char *image_path = command.GetArgumentAtIndex(i);
1198 FileSpec image_spec (image_path, false);
Greg Claytonaa516842011-08-11 16:25:18 +00001199 process->GetTarget().GetPlatform()->ResolveRemotePath(image_spec, image_spec);
Greg Clayton8f343b02010-11-04 01:54:29 +00001200 uint32_t image_token = process->LoadImage(image_spec, error);
1201 if (image_token != LLDB_INVALID_IMAGE_TOKEN)
1202 {
1203 result.AppendMessageWithFormat ("Loading \"%s\"...ok\nImage %u loaded.\n", image_path, image_token);
1204 result.SetStatus (eReturnStatusSuccessFinishResult);
1205 }
1206 else
1207 {
1208 result.AppendErrorWithFormat ("failed to load '%s': %s", image_path, error.AsCString());
1209 result.SetStatus (eReturnStatusFailed);
1210 }
1211 }
1212 return result.Succeeded();
1213 }
1214};
1215
1216
1217//-------------------------------------------------------------------------
1218// CommandObjectProcessUnload
1219//-------------------------------------------------------------------------
Jim Inghambb9caf72010-12-09 18:58:16 +00001220#pragma mark CommandObjectProcessUnload
Greg Clayton8f343b02010-11-04 01:54:29 +00001221
Jim Ingham5a988412012-06-08 21:56:10 +00001222class CommandObjectProcessUnload : public CommandObjectParsed
Greg Clayton8f343b02010-11-04 01:54:29 +00001223{
1224public:
1225
1226 CommandObjectProcessUnload (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001227 CommandObjectParsed (interpreter,
1228 "process unload",
1229 "Unload a shared library from the current process using the index returned by a previous call to \"process load\".",
1230 "process unload <index>",
Greg Claytonf9fc6092013-01-09 19:44:40 +00001231 eFlagRequiresProcess |
1232 eFlagTryTargetAPILock |
1233 eFlagProcessMustBeLaunched |
1234 eFlagProcessMustBePaused )
Greg Clayton8f343b02010-11-04 01:54:29 +00001235 {
1236 }
1237
1238 ~CommandObjectProcessUnload ()
1239 {
1240 }
1241
Jim Ingham5a988412012-06-08 21:56:10 +00001242protected:
Greg Clayton8f343b02010-11-04 01:54:29 +00001243 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001244 DoExecute (Args& command,
Greg Clayton8f343b02010-11-04 01:54:29 +00001245 CommandReturnObject &result)
1246 {
Greg Claytonf9fc6092013-01-09 19:44:40 +00001247 Process *process = m_exe_ctx.GetProcessPtr();
Greg Clayton8f343b02010-11-04 01:54:29 +00001248
Greg Claytonc7bece562013-01-25 18:06:21 +00001249 const size_t argc = command.GetArgumentCount();
Greg Clayton8f343b02010-11-04 01:54:29 +00001250
1251 for (uint32_t i=0; i<argc; ++i)
1252 {
1253 const char *image_token_cstr = command.GetArgumentAtIndex(i);
1254 uint32_t image_token = Args::StringToUInt32(image_token_cstr, LLDB_INVALID_IMAGE_TOKEN, 0);
1255 if (image_token == LLDB_INVALID_IMAGE_TOKEN)
1256 {
1257 result.AppendErrorWithFormat ("invalid image index argument '%s'", image_token_cstr);
1258 result.SetStatus (eReturnStatusFailed);
1259 break;
1260 }
1261 else
1262 {
1263 Error error (process->UnloadImage(image_token));
1264 if (error.Success())
1265 {
1266 result.AppendMessageWithFormat ("Unloading shared library with index %u...ok\n", image_token);
1267 result.SetStatus (eReturnStatusSuccessFinishResult);
1268 }
1269 else
1270 {
1271 result.AppendErrorWithFormat ("failed to unload image: %s", error.AsCString());
1272 result.SetStatus (eReturnStatusFailed);
1273 break;
1274 }
1275 }
1276 }
1277 return result.Succeeded();
1278 }
1279};
1280
1281//-------------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001282// CommandObjectProcessSignal
1283//-------------------------------------------------------------------------
Jim Inghambb9caf72010-12-09 18:58:16 +00001284#pragma mark CommandObjectProcessSignal
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001285
Jim Ingham5a988412012-06-08 21:56:10 +00001286class CommandObjectProcessSignal : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001287{
1288public:
1289
Greg Claytona7015092010-09-18 01:14:36 +00001290 CommandObjectProcessSignal (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001291 CommandObjectParsed (interpreter,
1292 "process signal",
1293 "Send a UNIX signal to the current process being debugged.",
Greg Claytonf9fc6092013-01-09 19:44:40 +00001294 NULL,
1295 eFlagRequiresProcess | eFlagTryTargetAPILock)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001296 {
Caroline Tice405fe672010-10-04 22:28:36 +00001297 CommandArgumentEntry arg;
1298 CommandArgumentData signal_arg;
1299
1300 // Define the first (and only) variant of this arg.
Caroline Ticec0dbdfb2010-10-18 22:56:57 +00001301 signal_arg.arg_type = eArgTypeUnixSignal;
Caroline Tice405fe672010-10-04 22:28:36 +00001302 signal_arg.arg_repetition = eArgRepeatPlain;
1303
1304 // There is only one variant this argument could be; put it into the argument entry.
1305 arg.push_back (signal_arg);
1306
1307 // Push the data for the first argument into the m_arguments vector.
1308 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001309 }
1310
1311 ~CommandObjectProcessSignal ()
1312 {
1313 }
1314
Jim Ingham5a988412012-06-08 21:56:10 +00001315protected:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001316 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001317 DoExecute (Args& command,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001318 CommandReturnObject &result)
1319 {
Greg Claytonf9fc6092013-01-09 19:44:40 +00001320 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001321
1322 if (command.GetArgumentCount() == 1)
1323 {
Greg Clayton237cd902010-10-09 01:40:57 +00001324 int signo = LLDB_INVALID_SIGNAL_NUMBER;
1325
1326 const char *signal_name = command.GetArgumentAtIndex(0);
1327 if (::isxdigit (signal_name[0]))
1328 signo = Args::StringToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0);
1329 else
1330 signo = process->GetUnixSignals().GetSignalNumberFromName (signal_name);
1331
1332 if (signo == LLDB_INVALID_SIGNAL_NUMBER)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001333 {
1334 result.AppendErrorWithFormat ("Invalid signal argument '%s'.\n", command.GetArgumentAtIndex(0));
1335 result.SetStatus (eReturnStatusFailed);
1336 }
1337 else
1338 {
1339 Error error (process->Signal (signo));
1340 if (error.Success())
1341 {
1342 result.SetStatus (eReturnStatusSuccessFinishResult);
1343 }
1344 else
1345 {
1346 result.AppendErrorWithFormat ("Failed to send signal %i: %s\n", signo, error.AsCString());
1347 result.SetStatus (eReturnStatusFailed);
1348 }
1349 }
1350 }
1351 else
1352 {
Jason Molendafd54b362011-09-20 21:44:10 +00001353 result.AppendErrorWithFormat("'%s' takes exactly one signal number argument:\nUsage: %s\n", m_cmd_name.c_str(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001354 m_cmd_syntax.c_str());
1355 result.SetStatus (eReturnStatusFailed);
1356 }
1357 return result.Succeeded();
1358 }
1359};
1360
1361
1362//-------------------------------------------------------------------------
1363// CommandObjectProcessInterrupt
1364//-------------------------------------------------------------------------
Jim Inghambb9caf72010-12-09 18:58:16 +00001365#pragma mark CommandObjectProcessInterrupt
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001366
Jim Ingham5a988412012-06-08 21:56:10 +00001367class CommandObjectProcessInterrupt : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001368{
1369public:
1370
1371
Greg Claytona7015092010-09-18 01:14:36 +00001372 CommandObjectProcessInterrupt (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001373 CommandObjectParsed (interpreter,
1374 "process interrupt",
1375 "Interrupt the current process being debugged.",
1376 "process interrupt",
Greg Claytonf9fc6092013-01-09 19:44:40 +00001377 eFlagRequiresProcess |
1378 eFlagTryTargetAPILock |
Jim Ingham5a988412012-06-08 21:56:10 +00001379 eFlagProcessMustBeLaunched)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001380 {
1381 }
1382
1383 ~CommandObjectProcessInterrupt ()
1384 {
1385 }
1386
Jim Ingham5a988412012-06-08 21:56:10 +00001387protected:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001388 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001389 DoExecute (Args& command,
Greg Claytonf9b57b92013-05-10 23:48:10 +00001390 CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001391 {
Greg Claytonf9fc6092013-01-09 19:44:40 +00001392 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001393 if (process == NULL)
1394 {
1395 result.AppendError ("no process to halt");
1396 result.SetStatus (eReturnStatusFailed);
1397 return false;
1398 }
1399
1400 if (command.GetArgumentCount() == 0)
1401 {
Greg Claytonf9b57b92013-05-10 23:48:10 +00001402 bool clear_thread_plans = true;
1403 Error error(process->Halt (clear_thread_plans));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001404 if (error.Success())
1405 {
1406 result.SetStatus (eReturnStatusSuccessFinishResult);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001407 }
1408 else
1409 {
1410 result.AppendErrorWithFormat ("Failed to halt process: %s\n", error.AsCString());
1411 result.SetStatus (eReturnStatusFailed);
1412 }
1413 }
1414 else
1415 {
Jason Molendafd54b362011-09-20 21:44:10 +00001416 result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n",
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001417 m_cmd_name.c_str(),
1418 m_cmd_syntax.c_str());
1419 result.SetStatus (eReturnStatusFailed);
1420 }
1421 return result.Succeeded();
1422 }
1423};
1424
1425//-------------------------------------------------------------------------
1426// CommandObjectProcessKill
1427//-------------------------------------------------------------------------
Jim Inghambb9caf72010-12-09 18:58:16 +00001428#pragma mark CommandObjectProcessKill
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001429
Jim Ingham5a988412012-06-08 21:56:10 +00001430class CommandObjectProcessKill : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001431{
1432public:
1433
Greg Claytona7015092010-09-18 01:14:36 +00001434 CommandObjectProcessKill (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001435 CommandObjectParsed (interpreter,
1436 "process kill",
1437 "Terminate the current process being debugged.",
1438 "process kill",
Greg Claytonf9fc6092013-01-09 19:44:40 +00001439 eFlagRequiresProcess |
1440 eFlagTryTargetAPILock |
Jim Ingham5a988412012-06-08 21:56:10 +00001441 eFlagProcessMustBeLaunched)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001442 {
1443 }
1444
1445 ~CommandObjectProcessKill ()
1446 {
1447 }
1448
Jim Ingham5a988412012-06-08 21:56:10 +00001449protected:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001450 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001451 DoExecute (Args& command,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001452 CommandReturnObject &result)
1453 {
Greg Claytonf9fc6092013-01-09 19:44:40 +00001454 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001455 if (process == NULL)
1456 {
1457 result.AppendError ("no process to kill");
1458 result.SetStatus (eReturnStatusFailed);
1459 return false;
1460 }
1461
1462 if (command.GetArgumentCount() == 0)
1463 {
1464 Error error (process->Destroy());
1465 if (error.Success())
1466 {
1467 result.SetStatus (eReturnStatusSuccessFinishResult);
1468 }
1469 else
1470 {
1471 result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString());
1472 result.SetStatus (eReturnStatusFailed);
1473 }
1474 }
1475 else
1476 {
Jason Molendafd54b362011-09-20 21:44:10 +00001477 result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n",
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001478 m_cmd_name.c_str(),
1479 m_cmd_syntax.c_str());
1480 result.SetStatus (eReturnStatusFailed);
1481 }
1482 return result.Succeeded();
1483 }
1484};
1485
1486//-------------------------------------------------------------------------
Jim Ingham4b9bea82010-06-18 01:23:09 +00001487// CommandObjectProcessStatus
1488//-------------------------------------------------------------------------
Jim Inghambb9caf72010-12-09 18:58:16 +00001489#pragma mark CommandObjectProcessStatus
1490
Jim Ingham5a988412012-06-08 21:56:10 +00001491class CommandObjectProcessStatus : public CommandObjectParsed
Jim Ingham4b9bea82010-06-18 01:23:09 +00001492{
1493public:
Greg Claytona7015092010-09-18 01:14:36 +00001494 CommandObjectProcessStatus (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001495 CommandObjectParsed (interpreter,
1496 "process status",
1497 "Show the current status and location of executing process.",
1498 "process status",
Greg Claytonf9fc6092013-01-09 19:44:40 +00001499 eFlagRequiresProcess | eFlagTryTargetAPILock)
Jim Ingham4b9bea82010-06-18 01:23:09 +00001500 {
1501 }
1502
1503 ~CommandObjectProcessStatus()
1504 {
1505 }
1506
1507
1508 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001509 DoExecute (Args& command, CommandReturnObject &result)
Jim Ingham4b9bea82010-06-18 01:23:09 +00001510 {
Greg Clayton7260f622011-04-18 08:33:37 +00001511 Stream &strm = result.GetOutputStream();
Jim Ingham4b9bea82010-06-18 01:23:09 +00001512 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Greg Claytonf9fc6092013-01-09 19:44:40 +00001513 // No need to check "process" for validity as eFlagRequiresProcess ensures it is valid
1514 Process *process = m_exe_ctx.GetProcessPtr();
1515 const bool only_threads_with_stop_reason = true;
1516 const uint32_t start_frame = 0;
1517 const uint32_t num_frames = 1;
1518 const uint32_t num_frames_with_source = 1;
1519 process->GetStatus(strm);
1520 process->GetThreadStatus (strm,
1521 only_threads_with_stop_reason,
1522 start_frame,
1523 num_frames,
1524 num_frames_with_source);
Jim Ingham4b9bea82010-06-18 01:23:09 +00001525 return result.Succeeded();
1526 }
1527};
1528
1529//-------------------------------------------------------------------------
Caroline Tice35731352010-10-13 20:44:39 +00001530// CommandObjectProcessHandle
1531//-------------------------------------------------------------------------
Jim Inghambb9caf72010-12-09 18:58:16 +00001532#pragma mark CommandObjectProcessHandle
Caroline Tice35731352010-10-13 20:44:39 +00001533
Jim Ingham5a988412012-06-08 21:56:10 +00001534class CommandObjectProcessHandle : public CommandObjectParsed
Caroline Tice35731352010-10-13 20:44:39 +00001535{
1536public:
1537
1538 class CommandOptions : public Options
1539 {
1540 public:
1541
Greg Claytoneb0103f2011-04-07 22:46:35 +00001542 CommandOptions (CommandInterpreter &interpreter) :
1543 Options (interpreter)
Caroline Tice35731352010-10-13 20:44:39 +00001544 {
Greg Claytonf6b8b582011-04-13 00:18:08 +00001545 OptionParsingStarting ();
Caroline Tice35731352010-10-13 20:44:39 +00001546 }
1547
1548 ~CommandOptions ()
1549 {
1550 }
1551
1552 Error
Greg Claytonf6b8b582011-04-13 00:18:08 +00001553 SetOptionValue (uint32_t option_idx, const char *option_arg)
Caroline Tice35731352010-10-13 20:44:39 +00001554 {
1555 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001556 const int short_option = m_getopt_table[option_idx].val;
Caroline Tice35731352010-10-13 20:44:39 +00001557
1558 switch (short_option)
1559 {
1560 case 's':
1561 stop = option_arg;
1562 break;
1563 case 'n':
1564 notify = option_arg;
1565 break;
1566 case 'p':
1567 pass = option_arg;
1568 break;
1569 default:
Greg Clayton86edbf42011-10-26 00:56:27 +00001570 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Caroline Tice35731352010-10-13 20:44:39 +00001571 break;
1572 }
1573 return error;
1574 }
1575
1576 void
Greg Claytonf6b8b582011-04-13 00:18:08 +00001577 OptionParsingStarting ()
Caroline Tice35731352010-10-13 20:44:39 +00001578 {
Caroline Tice35731352010-10-13 20:44:39 +00001579 stop.clear();
1580 notify.clear();
1581 pass.clear();
1582 }
1583
Greg Claytone0d378b2011-03-24 21:19:54 +00001584 const OptionDefinition*
Caroline Tice35731352010-10-13 20:44:39 +00001585 GetDefinitions ()
1586 {
1587 return g_option_table;
1588 }
1589
1590 // Options table: Required for subclasses of Options.
1591
Greg Claytone0d378b2011-03-24 21:19:54 +00001592 static OptionDefinition g_option_table[];
Caroline Tice35731352010-10-13 20:44:39 +00001593
1594 // Instance variables to hold the values for command options.
1595
1596 std::string stop;
1597 std::string notify;
1598 std::string pass;
1599 };
1600
1601
1602 CommandObjectProcessHandle (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001603 CommandObjectParsed (interpreter,
1604 "process handle",
1605 "Show or update what the process and debugger should do with various signals received from the OS.",
1606 NULL),
Greg Claytoneb0103f2011-04-07 22:46:35 +00001607 m_options (interpreter)
Caroline Tice35731352010-10-13 20:44:39 +00001608 {
Caroline Tice10ad7992010-10-14 21:31:13 +00001609 SetHelpLong ("If no signals are specified, update them all. If no update option is specified, list the current values.\n");
Caroline Tice35731352010-10-13 20:44:39 +00001610 CommandArgumentEntry arg;
Caroline Ticec0dbdfb2010-10-18 22:56:57 +00001611 CommandArgumentData signal_arg;
Caroline Tice35731352010-10-13 20:44:39 +00001612
Caroline Ticec0dbdfb2010-10-18 22:56:57 +00001613 signal_arg.arg_type = eArgTypeUnixSignal;
1614 signal_arg.arg_repetition = eArgRepeatStar;
Caroline Tice35731352010-10-13 20:44:39 +00001615
Caroline Ticec0dbdfb2010-10-18 22:56:57 +00001616 arg.push_back (signal_arg);
Caroline Tice35731352010-10-13 20:44:39 +00001617
1618 m_arguments.push_back (arg);
1619 }
1620
1621 ~CommandObjectProcessHandle ()
1622 {
1623 }
1624
1625 Options *
1626 GetOptions ()
1627 {
1628 return &m_options;
1629 }
1630
1631 bool
Caroline Tice10ad7992010-10-14 21:31:13 +00001632 VerifyCommandOptionValue (const std::string &option, int &real_value)
Caroline Tice35731352010-10-13 20:44:39 +00001633 {
1634 bool okay = true;
1635
Caroline Tice10ad7992010-10-14 21:31:13 +00001636 bool success = false;
1637 bool tmp_value = Args::StringToBoolean (option.c_str(), false, &success);
1638
1639 if (success && tmp_value)
1640 real_value = 1;
1641 else if (success && !tmp_value)
1642 real_value = 0;
Caroline Tice35731352010-10-13 20:44:39 +00001643 else
1644 {
1645 // If the value isn't 'true' or 'false', it had better be 0 or 1.
Caroline Tice10ad7992010-10-14 21:31:13 +00001646 real_value = Args::StringToUInt32 (option.c_str(), 3);
1647 if (real_value != 0 && real_value != 1)
Caroline Tice35731352010-10-13 20:44:39 +00001648 okay = false;
1649 }
1650
1651 return okay;
1652 }
1653
Caroline Tice10ad7992010-10-14 21:31:13 +00001654 void
1655 PrintSignalHeader (Stream &str)
1656 {
1657 str.Printf ("NAME PASS STOP NOTIFY\n");
1658 str.Printf ("========== ===== ===== ======\n");
1659 }
1660
1661 void
1662 PrintSignal (Stream &str, int32_t signo, const char *sig_name, UnixSignals &signals)
1663 {
1664 bool stop;
1665 bool suppress;
1666 bool notify;
1667
1668 str.Printf ("%-10s ", sig_name);
1669 if (signals.GetSignalInfo (signo, suppress, stop, notify))
1670 {
1671 bool pass = !suppress;
1672 str.Printf ("%s %s %s",
1673 (pass ? "true " : "false"),
1674 (stop ? "true " : "false"),
1675 (notify ? "true " : "false"));
1676 }
1677 str.Printf ("\n");
1678 }
1679
1680 void
1681 PrintSignalInformation (Stream &str, Args &signal_args, int num_valid_signals, UnixSignals &signals)
1682 {
1683 PrintSignalHeader (str);
1684
1685 if (num_valid_signals > 0)
1686 {
1687 size_t num_args = signal_args.GetArgumentCount();
1688 for (size_t i = 0; i < num_args; ++i)
1689 {
1690 int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i));
1691 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
1692 PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals);
1693 }
1694 }
1695 else // Print info for ALL signals
1696 {
1697 int32_t signo = signals.GetFirstSignalNumber();
1698 while (signo != LLDB_INVALID_SIGNAL_NUMBER)
1699 {
1700 PrintSignal (str, signo, signals.GetSignalAsCString (signo), signals);
1701 signo = signals.GetNextSignalNumber (signo);
1702 }
1703 }
1704 }
1705
Jim Ingham5a988412012-06-08 21:56:10 +00001706protected:
Caroline Tice35731352010-10-13 20:44:39 +00001707 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001708 DoExecute (Args &signal_args, CommandReturnObject &result)
Caroline Tice35731352010-10-13 20:44:39 +00001709 {
1710 TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
1711
1712 if (!target_sp)
1713 {
1714 result.AppendError ("No current target;"
1715 " cannot handle signals until you have a valid target and process.\n");
1716 result.SetStatus (eReturnStatusFailed);
1717 return false;
1718 }
1719
1720 ProcessSP process_sp = target_sp->GetProcessSP();
1721
1722 if (!process_sp)
1723 {
1724 result.AppendError ("No current process; cannot handle signals until you have a valid process.\n");
1725 result.SetStatus (eReturnStatusFailed);
1726 return false;
1727 }
1728
Caroline Tice35731352010-10-13 20:44:39 +00001729 int stop_action = -1; // -1 means leave the current setting alone
Caroline Tice10ad7992010-10-14 21:31:13 +00001730 int pass_action = -1; // -1 means leave the current setting alone
Caroline Tice35731352010-10-13 20:44:39 +00001731 int notify_action = -1; // -1 means leave the current setting alone
1732
1733 if (! m_options.stop.empty()
Caroline Tice10ad7992010-10-14 21:31:13 +00001734 && ! VerifyCommandOptionValue (m_options.stop, stop_action))
Caroline Tice35731352010-10-13 20:44:39 +00001735 {
1736 result.AppendError ("Invalid argument for command option --stop; must be true or false.\n");
1737 result.SetStatus (eReturnStatusFailed);
1738 return false;
1739 }
1740
1741 if (! m_options.notify.empty()
Caroline Tice10ad7992010-10-14 21:31:13 +00001742 && ! VerifyCommandOptionValue (m_options.notify, notify_action))
Caroline Tice35731352010-10-13 20:44:39 +00001743 {
1744 result.AppendError ("Invalid argument for command option --notify; must be true or false.\n");
1745 result.SetStatus (eReturnStatusFailed);
1746 return false;
1747 }
1748
1749 if (! m_options.pass.empty()
Caroline Tice10ad7992010-10-14 21:31:13 +00001750 && ! VerifyCommandOptionValue (m_options.pass, pass_action))
Caroline Tice35731352010-10-13 20:44:39 +00001751 {
1752 result.AppendError ("Invalid argument for command option --pass; must be true or false.\n");
1753 result.SetStatus (eReturnStatusFailed);
1754 return false;
1755 }
1756
1757 size_t num_args = signal_args.GetArgumentCount();
1758 UnixSignals &signals = process_sp->GetUnixSignals();
1759 int num_signals_set = 0;
1760
Caroline Tice10ad7992010-10-14 21:31:13 +00001761 if (num_args > 0)
Caroline Tice35731352010-10-13 20:44:39 +00001762 {
Caroline Tice10ad7992010-10-14 21:31:13 +00001763 for (size_t i = 0; i < num_args; ++i)
Caroline Tice35731352010-10-13 20:44:39 +00001764 {
Caroline Tice10ad7992010-10-14 21:31:13 +00001765 int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i));
1766 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
Caroline Tice35731352010-10-13 20:44:39 +00001767 {
Caroline Tice10ad7992010-10-14 21:31:13 +00001768 // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees
1769 // the value is either 0 or 1.
1770 if (stop_action != -1)
1771 signals.SetShouldStop (signo, (bool) stop_action);
1772 if (pass_action != -1)
1773 {
1774 bool suppress = ! ((bool) pass_action);
1775 signals.SetShouldSuppress (signo, suppress);
1776 }
1777 if (notify_action != -1)
1778 signals.SetShouldNotify (signo, (bool) notify_action);
1779 ++num_signals_set;
Caroline Tice35731352010-10-13 20:44:39 +00001780 }
Caroline Tice10ad7992010-10-14 21:31:13 +00001781 else
1782 {
1783 result.AppendErrorWithFormat ("Invalid signal name '%s'\n", signal_args.GetArgumentAtIndex (i));
1784 }
Caroline Tice35731352010-10-13 20:44:39 +00001785 }
1786 }
Caroline Tice10ad7992010-10-14 21:31:13 +00001787 else
1788 {
1789 // No signal specified, if any command options were specified, update ALL signals.
1790 if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1))
1791 {
1792 if (m_interpreter.Confirm ("Do you really want to update all the signals?", false))
1793 {
1794 int32_t signo = signals.GetFirstSignalNumber();
1795 while (signo != LLDB_INVALID_SIGNAL_NUMBER)
1796 {
1797 if (notify_action != -1)
1798 signals.SetShouldNotify (signo, (bool) notify_action);
1799 if (stop_action != -1)
1800 signals.SetShouldStop (signo, (bool) stop_action);
1801 if (pass_action != -1)
1802 {
1803 bool suppress = ! ((bool) pass_action);
1804 signals.SetShouldSuppress (signo, suppress);
1805 }
1806 signo = signals.GetNextSignalNumber (signo);
1807 }
1808 }
1809 }
1810 }
1811
1812 PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals);
Caroline Tice35731352010-10-13 20:44:39 +00001813
1814 if (num_signals_set > 0)
1815 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1816 else
1817 result.SetStatus (eReturnStatusFailed);
1818
1819 return result.Succeeded();
1820 }
1821
Caroline Tice35731352010-10-13 20:44:39 +00001822 CommandOptions m_options;
1823};
1824
Greg Claytone0d378b2011-03-24 21:19:54 +00001825OptionDefinition
Caroline Tice35731352010-10-13 20:44:39 +00001826CommandObjectProcessHandle::CommandOptions::g_option_table[] =
1827{
Virgile Belloe2607b52013-09-05 16:42:23 +00001828{ LLDB_OPT_SET_1, false, "stop", 's', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "Whether or not the process should be stopped if the signal is received." },
1829{ LLDB_OPT_SET_1, false, "notify", 'n', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "Whether or not the debugger should notify the user if the signal is received." },
1830{ LLDB_OPT_SET_1, false, "pass", 'p', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." },
Caroline Tice35731352010-10-13 20:44:39 +00001831{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1832};
1833
1834//-------------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001835// CommandObjectMultiwordProcess
1836//-------------------------------------------------------------------------
1837
Greg Clayton66111032010-06-23 01:19:29 +00001838CommandObjectMultiwordProcess::CommandObjectMultiwordProcess (CommandInterpreter &interpreter) :
Greg Claytona7015092010-09-18 01:14:36 +00001839 CommandObjectMultiword (interpreter,
1840 "process",
1841 "A set of commands for operating on a process.",
1842 "process <subcommand> [<subcommand-options>]")
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001843{
Greg Clayton197bacf2011-07-02 21:07:54 +00001844 LoadSubCommand ("attach", CommandObjectSP (new CommandObjectProcessAttach (interpreter)));
1845 LoadSubCommand ("launch", CommandObjectSP (new CommandObjectProcessLaunch (interpreter)));
1846 LoadSubCommand ("continue", CommandObjectSP (new CommandObjectProcessContinue (interpreter)));
1847 LoadSubCommand ("connect", CommandObjectSP (new CommandObjectProcessConnect (interpreter)));
1848 LoadSubCommand ("detach", CommandObjectSP (new CommandObjectProcessDetach (interpreter)));
1849 LoadSubCommand ("load", CommandObjectSP (new CommandObjectProcessLoad (interpreter)));
1850 LoadSubCommand ("unload", CommandObjectSP (new CommandObjectProcessUnload (interpreter)));
1851 LoadSubCommand ("signal", CommandObjectSP (new CommandObjectProcessSignal (interpreter)));
1852 LoadSubCommand ("handle", CommandObjectSP (new CommandObjectProcessHandle (interpreter)));
1853 LoadSubCommand ("status", CommandObjectSP (new CommandObjectProcessStatus (interpreter)));
Greg Claytona7015092010-09-18 01:14:36 +00001854 LoadSubCommand ("interrupt", CommandObjectSP (new CommandObjectProcessInterrupt (interpreter)));
Greg Clayton197bacf2011-07-02 21:07:54 +00001855 LoadSubCommand ("kill", CommandObjectSP (new CommandObjectProcessKill (interpreter)));
Greg Clayton998255b2012-10-13 02:07:45 +00001856 LoadSubCommand ("plugin", CommandObjectSP (new CommandObjectProcessPlugin (interpreter)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001857}
1858
1859CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess ()
1860{
1861}
1862