blob: 2221514d902218df63677c22aa9689ac23b9dfcc [file] [log] [blame]
Chris Lattner24943d22010-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 Malead891f9b2012-12-05 00:20:57 +000010#include "lldb/lldb-python.h"
11
Chris Lattner24943d22010-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 Ingham124e6902012-08-11 01:27:55 +000018#include "lldb/Breakpoint/Breakpoint.h"
19#include "lldb/Breakpoint/BreakpointLocation.h"
20#include "lldb/Breakpoint/BreakpointSite.h"
Chris Lattner24943d22010-06-08 16:52:24 +000021#include "lldb/Core/State.h"
Greg Clayton49ce8962012-08-29 21:13:06 +000022#include "lldb/Core/Module.h"
Greg Claytonabe0fed2011-04-18 08:33:37 +000023#include "lldb/Host/Host.h"
Jim Ingham124e6902012-08-11 01:27:55 +000024#include "lldb/Interpreter/Args.h"
25#include "lldb/Interpreter/Options.h"
Chris Lattner24943d22010-06-08 16:52:24 +000026#include "lldb/Interpreter/CommandInterpreter.h"
27#include "lldb/Interpreter/CommandReturnObject.h"
Greg Claytone4b9c1f2011-03-08 22:40:15 +000028#include "lldb/Target/Platform.h"
Chris Lattner24943d22010-06-08 16:52:24 +000029#include "lldb/Target/Process.h"
Jim Ingham124e6902012-08-11 01:27:55 +000030#include "lldb/Target/StopInfo.h"
Chris Lattner24943d22010-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 Inghamd3b4bd52013-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
52 StopProcessIfNecessary (Process *&process, StateType &state, CommandReturnObject &result)
53 {
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 {
78 Error detach_error (process->Detach());
79 if (detach_error.Success())
80 {
81 result.SetStatus (eReturnStatusSuccessFinishResult);
82 process = NULL;
83 }
84 else
85 {
86 result.AppendErrorWithFormat ("Failed to detach from process: %s\n", detach_error.AsCString());
87 result.SetStatus (eReturnStatusFailed);
88 }
89 }
90 else
91 {
92 Error destroy_error (process->Destroy());
93 if (destroy_error.Success())
94 {
95 result.SetStatus (eReturnStatusSuccessFinishResult);
96 process = NULL;
97 }
98 else
99 {
100 result.AppendErrorWithFormat ("Failed to kill process: %s\n", destroy_error.AsCString());
101 result.SetStatus (eReturnStatusFailed);
102 }
103 }
104 }
105 }
106 }
107 return result.Succeeded();
108 }
109 std::string m_new_process_action;
110};
Chris Lattner24943d22010-06-08 16:52:24 +0000111//-------------------------------------------------------------------------
112// CommandObjectProcessLaunch
113//-------------------------------------------------------------------------
Jim Ingham5a15e692012-02-16 06:50:00 +0000114#pragma mark CommandObjectProcessLaunch
Jim Inghamd3b4bd52013-03-29 00:56:30 +0000115class CommandObjectProcessLaunch : public CommandObjectProcessLaunchOrAttach
Chris Lattner24943d22010-06-08 16:52:24 +0000116{
117public:
118
Greg Clayton238c0a12010-09-18 01:14:36 +0000119 CommandObjectProcessLaunch (CommandInterpreter &interpreter) :
Jim Inghamd3b4bd52013-03-29 00:56:30 +0000120 CommandObjectProcessLaunchOrAttach (interpreter,
121 "process launch",
122 "Launch the executable in the debugger.",
123 NULL,
124 eFlagRequiresTarget,
125 "restart"),
Greg Claytonf15996e2011-04-07 22:46:35 +0000126 m_options (interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000127 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000128 CommandArgumentEntry arg;
129 CommandArgumentData run_args_arg;
130
131 // Define the first (and only) variant of this arg.
132 run_args_arg.arg_type = eArgTypeRunArgs;
133 run_args_arg.arg_repetition = eArgRepeatOptional;
134
135 // There is only one variant this argument could be; put it into the argument entry.
136 arg.push_back (run_args_arg);
137
138 // Push the data for the first argument into the m_arguments vector.
139 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000140 }
141
142
143 ~CommandObjectProcessLaunch ()
144 {
145 }
146
Greg Clayton36da2aa2013-01-25 18:06:21 +0000147 virtual int
Jim Ingham392d9e02012-08-10 21:48:41 +0000148 HandleArgumentCompletion (Args &input,
149 int &cursor_index,
150 int &cursor_char_position,
151 OptionElementVector &opt_element_vector,
152 int match_start_point,
153 int max_return_elements,
154 bool &word_complete,
155 StringList &matches)
156 {
157 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
158 completion_str.erase (cursor_char_position);
159
160 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
161 CommandCompletions::eDiskFileCompletion,
162 completion_str.c_str(),
163 match_start_point,
164 max_return_elements,
165 NULL,
166 word_complete,
167 matches);
168 return matches.GetSize();
169 }
170
Chris Lattner24943d22010-06-08 16:52:24 +0000171 Options *
172 GetOptions ()
173 {
174 return &m_options;
175 }
176
Jim Inghamda26bd22012-06-08 21:56:10 +0000177 virtual const char *GetRepeatCommand (Args &current_command_args, uint32_t index)
178 {
179 // No repeat for "process launch"...
180 return "";
181 }
182
183protected:
Chris Lattner24943d22010-06-08 16:52:24 +0000184 bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000185 DoExecute (Args& launch_args, CommandReturnObject &result)
Chris Lattner24943d22010-06-08 16:52:24 +0000186 {
Greg Claytonabb33022011-11-08 02:43:13 +0000187 Debugger &debugger = m_interpreter.GetDebugger();
188 Target *target = debugger.GetSelectedTarget().get();
189 Error error;
Chris Lattner24943d22010-06-08 16:52:24 +0000190 // If our listener is NULL, users aren't allows to launch
Chris Lattner24943d22010-06-08 16:52:24 +0000191 char filename[PATH_MAX];
Greg Clayton5beb99d2011-08-11 02:48:45 +0000192 const Module *exe_module = target->GetExecutableModulePointer();
Greg Claytona2f74232011-02-24 22:24:29 +0000193
194 if (exe_module == NULL)
195 {
Greg Claytone1f50b92011-05-03 22:09:39 +0000196 result.AppendError ("no file in target, create a debug target using the 'target create' command");
Greg Claytona2f74232011-02-24 22:24:29 +0000197 result.SetStatus (eReturnStatusFailed);
198 return false;
199 }
200
Greg Claytona2f74232011-02-24 22:24:29 +0000201 StateType state = eStateInvalid;
Greg Claytonea0bb4d2013-01-09 19:44:40 +0000202 Process *process = m_exe_ctx.GetProcessPtr();
Greg Claytona2f74232011-02-24 22:24:29 +0000203
Jim Inghamd3b4bd52013-03-29 00:56:30 +0000204 if (!StopProcessIfNecessary(process, state, result))
205 return false;
Jim Ingham22dc9722010-12-09 18:58:16 +0000206
Greg Clayton0c8446c2012-10-17 22:57:12 +0000207 const char *target_settings_argv0 = target->GetArg0();
208
209 exe_module->GetFileSpec().GetPath (filename, sizeof(filename));
210
211 if (target_settings_argv0)
212 {
213 m_options.launch_info.GetArguments().AppendArgument (target_settings_argv0);
214 m_options.launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), false);
215 }
216 else
217 {
218 m_options.launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), true);
219 }
220
Greg Clayton527154d2011-11-15 03:53:30 +0000221 if (launch_args.GetArgumentCount() == 0)
222 {
Greg Clayton73844aa2012-08-22 17:17:09 +0000223 Args target_setting_args;
Greg Clayton0c8446c2012-10-17 22:57:12 +0000224 if (target->GetRunArguments(target_setting_args))
Greg Clayton73844aa2012-08-22 17:17:09 +0000225 m_options.launch_info.GetArguments().AppendArguments (target_setting_args);
Greg Clayton527154d2011-11-15 03:53:30 +0000226 }
227 else
Greg Claytonabb33022011-11-08 02:43:13 +0000228 {
Greg Clayton0c8446c2012-10-17 22:57:12 +0000229 m_options.launch_info.GetArguments().AppendArguments (launch_args);
230
Greg Clayton3e6f2cc2011-11-21 21:51:18 +0000231 // Save the arguments for subsequent runs in the current target.
232 target->SetRunArguments (launch_args);
Greg Claytonabb33022011-11-08 02:43:13 +0000233 }
Greg Claytonabb33022011-11-08 02:43:13 +0000234
Greg Clayton527154d2011-11-15 03:53:30 +0000235 if (target->GetDisableASLR())
236 m_options.launch_info.GetFlags().Set (eLaunchFlagDisableASLR);
237
238 if (target->GetDisableSTDIO())
239 m_options.launch_info.GetFlags().Set (eLaunchFlagDisableSTDIO);
240
241 m_options.launch_info.GetFlags().Set (eLaunchFlagDebug);
242
243 Args environment;
244 target->GetEnvironmentAsArgs (environment);
245 if (environment.GetArgumentCount() > 0)
246 m_options.launch_info.GetEnvironmentEntries ().AppendArguments (environment);
247
Jim Ingham89e248f2013-02-09 01:29:05 +0000248 // Get the value of synchronous execution here. If you wait till after you have started to
249 // run, then you could have hit a breakpoint, whose command might switch the value, and
250 // then you'll pick up that incorrect value.
251 bool synchronous_execution = m_interpreter.GetSynchronous ();
252
Greg Clayton464c6162011-11-17 22:14:31 +0000253 // Finalize the file actions, and if none were given, default to opening
254 // up a pseudo terminal
255 const bool default_to_use_pty = true;
256 m_options.launch_info.FinalizeFileActions (target, default_to_use_pty);
Greg Clayton527154d2011-11-15 03:53:30 +0000257
Greg Claytonabb33022011-11-08 02:43:13 +0000258 if (state == eStateConnected)
259 {
260 if (m_options.launch_info.GetFlags().Test (eLaunchFlagLaunchInTTY))
261 {
262 result.AppendWarning("can't launch in tty when launching through a remote connection");
263 m_options.launch_info.GetFlags().Clear (eLaunchFlagLaunchInTTY);
264 }
265 }
Jim Inghamd3b4bd52013-03-29 00:56:30 +0000266
267 if (!m_options.launch_info.GetArchitecture().IsValid())
268 m_options.launch_info.GetArchitecture() = target->GetArchitecture();
269
270 PlatformSP platform_sp (target->GetPlatform());
271
272 if (platform_sp && platform_sp->CanDebugProcess ())
273 {
274 process = target->GetPlatform()->DebugProcess (m_options.launch_info,
275 debugger,
276 target,
277 debugger.GetListener(),
278 error).get();
279 }
Greg Claytonabb33022011-11-08 02:43:13 +0000280 else
Caroline Tice6e4c5ce2010-09-04 00:03:46 +0000281 {
Jim Inghamd3b4bd52013-03-29 00:56:30 +0000282 const char *plugin_name = m_options.launch_info.GetProcessPluginName();
283 process = target->CreateProcess (debugger.GetListener(), plugin_name, NULL).get();
284 if (process)
285 error = process->Launch (m_options.launch_info);
Chris Lattner24943d22010-06-08 16:52:24 +0000286 }
Jim Inghamd3b4bd52013-03-29 00:56:30 +0000287
288 if (process == NULL)
289 {
290 result.SetError (error, "failed to launch or debug process");
291 return false;
292 }
293
Greg Claytonabb33022011-11-08 02:43:13 +0000294
Greg Clayton238c0a12010-09-18 01:14:36 +0000295 if (error.Success())
296 {
Greg Clayton940b1032011-02-23 00:35:02 +0000297 const char *archname = exe_module->GetArchitecture().GetArchitectureName();
Greg Claytonc1d37752010-10-18 01:45:30 +0000298
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000299 result.AppendMessageWithFormat ("Process %" PRIu64 " launched: '%s' (%s)\n", process->GetID(), filename, archname);
Greg Claytond8c62532010-10-07 04:19:01 +0000300 result.SetDidChangeProcessState (true);
Greg Clayton36bc5ea2011-11-03 21:22:33 +0000301 if (m_options.launch_info.GetFlags().Test(eLaunchFlagStopAtEntry) == false)
Greg Clayton238c0a12010-09-18 01:14:36 +0000302 {
Greg Claytond8c62532010-10-07 04:19:01 +0000303 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
Greg Clayton238c0a12010-09-18 01:14:36 +0000304 StateType state = process->WaitForProcessToStop (NULL);
305
306 if (state == eStateStopped)
307 {
Greg Claytond8c62532010-10-07 04:19:01 +0000308 error = process->Resume();
309 if (error.Success())
310 {
Greg Claytond8c62532010-10-07 04:19:01 +0000311 if (synchronous_execution)
312 {
313 state = process->WaitForProcessToStop (NULL);
Greg Clayton20206082011-11-17 01:23:07 +0000314 const bool must_be_alive = true;
315 if (!StateIsStoppedState(state, must_be_alive))
Greg Clayton395fc332011-02-15 21:59:32 +0000316 {
Greg Clayton527154d2011-11-15 03:53:30 +0000317 result.AppendErrorWithFormat ("process isn't stopped: %s", StateAsCString(state));
Greg Clayton395fc332011-02-15 21:59:32 +0000318 }
Greg Claytond8c62532010-10-07 04:19:01 +0000319 result.SetDidChangeProcessState (true);
320 result.SetStatus (eReturnStatusSuccessFinishResult);
321 }
322 else
323 {
324 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
325 }
326 }
Greg Clayton395fc332011-02-15 21:59:32 +0000327 else
328 {
Greg Clayton527154d2011-11-15 03:53:30 +0000329 result.AppendErrorWithFormat ("process resume at entry point failed: %s", error.AsCString());
Greg Clayton395fc332011-02-15 21:59:32 +0000330 result.SetStatus (eReturnStatusFailed);
331 }
Greg Clayton238c0a12010-09-18 01:14:36 +0000332 }
Greg Clayton395fc332011-02-15 21:59:32 +0000333 else
334 {
Greg Clayton527154d2011-11-15 03:53:30 +0000335 result.AppendErrorWithFormat ("initial process state wasn't stopped: %s", StateAsCString(state));
Greg Clayton395fc332011-02-15 21:59:32 +0000336 result.SetStatus (eReturnStatusFailed);
337 }
Greg Clayton238c0a12010-09-18 01:14:36 +0000338 }
339 }
Greg Clayton395fc332011-02-15 21:59:32 +0000340 else
341 {
Greg Claytona9eb8272011-07-02 21:07:54 +0000342 result.AppendErrorWithFormat ("process launch failed: %s", error.AsCString());
Greg Clayton395fc332011-02-15 21:59:32 +0000343 result.SetStatus (eReturnStatusFailed);
344 }
Greg Clayton238c0a12010-09-18 01:14:36 +0000345
Chris Lattner24943d22010-06-08 16:52:24 +0000346 return result.Succeeded();
347 }
348
349protected:
Greg Clayton36bc5ea2011-11-03 21:22:33 +0000350 ProcessLaunchCommandOptions m_options;
Chris Lattner24943d22010-06-08 16:52:24 +0000351};
352
353
Greg Clayton36bc5ea2011-11-03 21:22:33 +0000354//#define SET1 LLDB_OPT_SET_1
355//#define SET2 LLDB_OPT_SET_2
356//#define SET3 LLDB_OPT_SET_3
357//
358//OptionDefinition
359//CommandObjectProcessLaunch::CommandOptions::g_option_table[] =
360//{
361//{ SET1 | SET2 | SET3, false, "stop-at-entry", 's', no_argument, NULL, 0, eArgTypeNone, "Stop at the entry point of the program when launching a process."},
Sean Callanan9a91ef62012-10-24 01:12:14 +0000362//{ SET1 , false, "stdin", 'i', required_argument, NULL, 0, eArgTypeDirectoryName, "Redirect stdin for the process to <path>."},
363//{ SET1 , false, "stdout", 'o', required_argument, NULL, 0, eArgTypeDirectoryName, "Redirect stdout for the process to <path>."},
364//{ SET1 , false, "stderr", 'e', required_argument, NULL, 0, eArgTypeDirectoryName, "Redirect stderr for the process to <path>."},
Greg Clayton36bc5ea2011-11-03 21:22:33 +0000365//{ SET1 | SET2 | SET3, false, "plugin", 'p', required_argument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."},
Sean Callanan9a91ef62012-10-24 01:12:14 +0000366//{ SET2 , false, "tty", 't', optional_argument, NULL, 0, eArgTypeDirectoryName, "Start the process in a terminal. If <path> is specified, look for a terminal whose name contains <path>, else start the process in a new terminal."},
Greg Clayton36bc5ea2011-11-03 21:22:33 +0000367//{ SET3, false, "no-stdio", 'n', no_argument, NULL, 0, eArgTypeNone, "Do not set up for terminal I/O to go to running process."},
Sean Callanan9a91ef62012-10-24 01:12:14 +0000368//{ SET1 | SET2 | SET3, false, "working-dir", 'w', required_argument, NULL, 0, eArgTypeDirectoryName, "Set the current working directory to <path> when running the inferior."},
Greg Clayton36bc5ea2011-11-03 21:22:33 +0000369//{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
370//};
371//
372//#undef SET1
373//#undef SET2
374//#undef SET3
Chris Lattner24943d22010-06-08 16:52:24 +0000375
376//-------------------------------------------------------------------------
377// CommandObjectProcessAttach
378//-------------------------------------------------------------------------
Jim Ingham22dc9722010-12-09 18:58:16 +0000379#pragma mark CommandObjectProcessAttach
Jim Inghamd3b4bd52013-03-29 00:56:30 +0000380class CommandObjectProcessAttach : public CommandObjectProcessLaunchOrAttach
Chris Lattner24943d22010-06-08 16:52:24 +0000381{
382public:
383
Chris Lattner24943d22010-06-08 16:52:24 +0000384 class CommandOptions : public Options
385 {
386 public:
387
Greg Claytonf15996e2011-04-07 22:46:35 +0000388 CommandOptions (CommandInterpreter &interpreter) :
389 Options(interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000390 {
Greg Clayton143fcc32011-04-13 00:18:08 +0000391 // Keep default values of all options in one place: OptionParsingStarting ()
392 OptionParsingStarting ();
Chris Lattner24943d22010-06-08 16:52:24 +0000393 }
394
395 ~CommandOptions ()
396 {
397 }
398
399 Error
Greg Clayton143fcc32011-04-13 00:18:08 +0000400 SetOptionValue (uint32_t option_idx, const char *option_arg)
Chris Lattner24943d22010-06-08 16:52:24 +0000401 {
402 Error error;
Greg Clayton6475c422012-12-04 00:32:51 +0000403 const int short_option = m_getopt_table[option_idx].val;
Chris Lattner24943d22010-06-08 16:52:24 +0000404 bool success = false;
405 switch (short_option)
406 {
Johnny Chen7c099972012-05-24 00:43:00 +0000407 case 'c':
408 attach_info.SetContinueOnceAttached(true);
409 break;
410
Chris Lattner24943d22010-06-08 16:52:24 +0000411 case 'p':
Chris Lattner24943d22010-06-08 16:52:24 +0000412 {
Greg Clayton527154d2011-11-15 03:53:30 +0000413 lldb::pid_t pid = Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success);
414 if (!success || pid == LLDB_INVALID_PROCESS_ID)
415 {
416 error.SetErrorStringWithFormat("invalid process ID '%s'", option_arg);
417 }
418 else
419 {
420 attach_info.SetProcessID (pid);
421 }
Chris Lattner24943d22010-06-08 16:52:24 +0000422 }
423 break;
424
425 case 'P':
Greg Clayton527154d2011-11-15 03:53:30 +0000426 attach_info.SetProcessPluginName (option_arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000427 break;
428
429 case 'n':
Greg Clayton527154d2011-11-15 03:53:30 +0000430 attach_info.GetExecutableFile().SetFile(option_arg, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000431 break;
432
433 case 'w':
Greg Clayton527154d2011-11-15 03:53:30 +0000434 attach_info.SetWaitForLaunch(true);
Chris Lattner24943d22010-06-08 16:52:24 +0000435 break;
Jim Ingham3a458eb2012-07-20 21:37:13 +0000436
437 case 'i':
438 attach_info.SetIgnoreExisting(false);
439 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000440
441 default:
Greg Clayton9c236732011-10-26 00:56:27 +0000442 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Chris Lattner24943d22010-06-08 16:52:24 +0000443 break;
444 }
445 return error;
446 }
447
448 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000449 OptionParsingStarting ()
Chris Lattner24943d22010-06-08 16:52:24 +0000450 {
Greg Clayton527154d2011-11-15 03:53:30 +0000451 attach_info.Clear();
Chris Lattner24943d22010-06-08 16:52:24 +0000452 }
453
Greg Claytonb3448432011-03-24 21:19:54 +0000454 const OptionDefinition*
Chris Lattner24943d22010-06-08 16:52:24 +0000455 GetDefinitions ()
456 {
457 return g_option_table;
458 }
459
Jim Ingham7508e732010-08-09 23:31:02 +0000460 virtual bool
Greg Claytonf15996e2011-04-07 22:46:35 +0000461 HandleOptionArgumentCompletion (Args &input,
Jim Ingham7508e732010-08-09 23:31:02 +0000462 int cursor_index,
463 int char_pos,
464 OptionElementVector &opt_element_vector,
465 int opt_element_index,
466 int match_start_point,
467 int max_return_elements,
468 bool &word_complete,
469 StringList &matches)
470 {
471 int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
472 int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
473
474 // We are only completing the name option for now...
475
Greg Claytonb3448432011-03-24 21:19:54 +0000476 const OptionDefinition *opt_defs = GetDefinitions();
Jim Ingham7508e732010-08-09 23:31:02 +0000477 if (opt_defs[opt_defs_index].short_option == 'n')
478 {
479 // Are we in the name?
480
481 // Look to see if there is a -P argument provided, and if so use that plugin, otherwise
482 // use the default plugin.
Jim Ingham7508e732010-08-09 23:31:02 +0000483
484 const char *partial_name = NULL;
485 partial_name = input.GetArgumentAtIndex(opt_arg_pos);
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000486
Greg Claytonb72d0f02011-04-12 05:54:46 +0000487 PlatformSP platform_sp (m_interpreter.GetPlatform (true));
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000488 if (platform_sp)
Jim Ingham7508e732010-08-09 23:31:02 +0000489 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000490 ProcessInstanceInfoList process_infos;
491 ProcessInstanceInfoMatch match_info;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000492 if (partial_name)
493 {
Greg Clayton527154d2011-11-15 03:53:30 +0000494 match_info.GetProcessInfo().GetExecutableFile().SetFile(partial_name, false);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000495 match_info.SetNameMatchType(eNameMatchStartsWith);
496 }
497 platform_sp->FindProcesses (match_info, process_infos);
Greg Clayton36da2aa2013-01-25 18:06:21 +0000498 const size_t num_matches = process_infos.GetSize();
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000499 if (num_matches > 0)
500 {
Greg Clayton36da2aa2013-01-25 18:06:21 +0000501 for (size_t i=0; i<num_matches; ++i)
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000502 {
503 matches.AppendString (process_infos.GetProcessNameAtIndex(i),
504 process_infos.GetProcessNameLengthAtIndex(i));
505 }
506 }
Jim Ingham7508e732010-08-09 23:31:02 +0000507 }
508 }
509
510 return false;
511 }
512
Chris Lattner24943d22010-06-08 16:52:24 +0000513 // Options table: Required for subclasses of Options.
514
Greg Claytonb3448432011-03-24 21:19:54 +0000515 static OptionDefinition g_option_table[];
Chris Lattner24943d22010-06-08 16:52:24 +0000516
517 // Instance variables to hold the values for command options.
518
Greg Clayton527154d2011-11-15 03:53:30 +0000519 ProcessAttachInfo attach_info;
Chris Lattner24943d22010-06-08 16:52:24 +0000520 };
521
Greg Clayton238c0a12010-09-18 01:14:36 +0000522 CommandObjectProcessAttach (CommandInterpreter &interpreter) :
Jim Inghamd3b4bd52013-03-29 00:56:30 +0000523 CommandObjectProcessLaunchOrAttach (interpreter,
524 "process attach",
525 "Attach to a process.",
526 "process attach <cmd-options>",
527 0,
528 "attach"),
Greg Claytonf15996e2011-04-07 22:46:35 +0000529 m_options (interpreter)
Jim Ingham7508e732010-08-09 23:31:02 +0000530 {
Jim Ingham7508e732010-08-09 23:31:02 +0000531 }
532
533 ~CommandObjectProcessAttach ()
534 {
535 }
536
Jim Inghamda26bd22012-06-08 21:56:10 +0000537 Options *
538 GetOptions ()
539 {
540 return &m_options;
541 }
542
543protected:
Jim Ingham7508e732010-08-09 23:31:02 +0000544 bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000545 DoExecute (Args& command,
Jim Ingham7508e732010-08-09 23:31:02 +0000546 CommandReturnObject &result)
547 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000548 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Jim Inghamee940e22011-09-15 01:08:57 +0000549 // N.B. The attach should be synchronous. It doesn't help much to get the prompt back between initiating the attach
550 // and the target actually stopping. So even if the interpreter is set to be asynchronous, we wait for the stop
551 // ourselves here.
Jim Inghamc2dc7c82011-01-29 01:49:25 +0000552
Greg Claytona2f74232011-02-24 22:24:29 +0000553 StateType state = eStateInvalid;
Jim Inghamd3b4bd52013-03-29 00:56:30 +0000554 Process *process = m_exe_ctx.GetProcessPtr();
555
556 if (!StopProcessIfNecessary (process, state, result))
557 return false;
558
Jim Ingham7508e732010-08-09 23:31:02 +0000559 if (target == NULL)
560 {
561 // If there isn't a current target create one.
562 TargetSP new_target_sp;
Jim Ingham7508e732010-08-09 23:31:02 +0000563 Error error;
564
Greg Clayton238c0a12010-09-18 01:14:36 +0000565 error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(),
Greg Claytoned0a0fb2012-10-18 16:33:33 +0000566 NULL,
Greg Clayton3e8c25f2011-09-24 00:52:29 +0000567 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +0000568 false,
Greg Clayton3e8c25f2011-09-24 00:52:29 +0000569 NULL, // No platform options
Greg Clayton238c0a12010-09-18 01:14:36 +0000570 new_target_sp);
Jim Ingham7508e732010-08-09 23:31:02 +0000571 target = new_target_sp.get();
572 if (target == NULL || error.Fail())
573 {
Greg Claytone71e2582011-02-04 01:58:07 +0000574 result.AppendError(error.AsCString("Error creating target"));
Jim Ingham7508e732010-08-09 23:31:02 +0000575 return false;
576 }
Greg Clayton238c0a12010-09-18 01:14:36 +0000577 m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target);
Jim Ingham7508e732010-08-09 23:31:02 +0000578 }
579
580 // Record the old executable module, we want to issue a warning if the process of attaching changed the
581 // current executable (like somebody said "file foo" then attached to a PID whose executable was bar.)
582
583 ModuleSP old_exec_module_sp = target->GetExecutableModule();
584 ArchSpec old_arch_spec = target->GetArchitecture();
585
586 if (command.GetArgumentCount())
587 {
Jason Molenda7e5fa7f2011-09-20 21:44:10 +0000588 result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
Jim Ingham7508e732010-08-09 23:31:02 +0000589 result.SetStatus (eReturnStatusFailed);
590 }
591 else
592 {
Greg Claytona2f74232011-02-24 22:24:29 +0000593 if (state != eStateConnected)
594 {
Greg Clayton527154d2011-11-15 03:53:30 +0000595 const char *plugin_name = m_options.attach_info.GetProcessPluginName();
Greg Clayton46c9a352012-02-09 06:16:32 +0000596 process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name, NULL).get();
Greg Claytona2f74232011-02-24 22:24:29 +0000597 }
Jim Ingham7508e732010-08-09 23:31:02 +0000598
599 if (process)
600 {
601 Error error;
Greg Clayton527154d2011-11-15 03:53:30 +0000602 // If no process info was specified, then use the target executable
603 // name as the process to attach to by default
604 if (!m_options.attach_info.ProcessInfoSpecified ())
Jim Ingham4805a1c2010-09-15 01:34:14 +0000605 {
606 if (old_exec_module_sp)
Greg Clayton1d1f39e2011-11-29 04:03:30 +0000607 m_options.attach_info.GetExecutableFile().GetFilename() = old_exec_module_sp->GetPlatformFileSpec().GetFilename();
Jim Ingham4805a1c2010-09-15 01:34:14 +0000608
Greg Clayton527154d2011-11-15 03:53:30 +0000609 if (!m_options.attach_info.ProcessInfoSpecified ())
610 {
611 error.SetErrorString ("no process specified, create a target with a file, or specify the --pid or --name command option");
612 }
613 }
614
615 if (error.Success())
616 {
617 error = process->Attach (m_options.attach_info);
618
Jim Ingham4805a1c2010-09-15 01:34:14 +0000619 if (error.Success())
620 {
621 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
622 }
Jim Ingham7508e732010-08-09 23:31:02 +0000623 else
624 {
Greg Clayton527154d2011-11-15 03:53:30 +0000625 result.AppendErrorWithFormat ("attach failed: %s\n", error.AsCString());
Jim Ingham4805a1c2010-09-15 01:34:14 +0000626 result.SetStatus (eReturnStatusFailed);
627 return false;
Jim Ingham7508e732010-08-09 23:31:02 +0000628 }
Jim Inghamc2dc7c82011-01-29 01:49:25 +0000629 // If we're synchronous, wait for the stopped event and report that.
630 // Otherwise just return.
631 // FIXME: in the async case it will now be possible to get to the command
632 // interpreter with a state eStateAttaching. Make sure we handle that correctly.
Jim Inghamee940e22011-09-15 01:08:57 +0000633 StateType state = process->WaitForProcessToStop (NULL);
Greg Clayton527154d2011-11-15 03:53:30 +0000634
Jim Inghamee940e22011-09-15 01:08:57 +0000635 result.SetDidChangeProcessState (true);
Johnny Chen9986a3b2012-05-18 00:51:36 +0000636
637 if (state == eStateStopped)
638 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000639 result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
Johnny Chen9986a3b2012-05-18 00:51:36 +0000640 result.SetStatus (eReturnStatusSuccessFinishNoResult);
641 }
642 else
643 {
644 result.AppendError ("attach failed: process did not stop (no such process or permission problem?)");
Jim Ingham5d90ade2012-07-27 23:57:19 +0000645 process->Destroy();
Johnny Chen9986a3b2012-05-18 00:51:36 +0000646 result.SetStatus (eReturnStatusFailed);
647 return false;
648 }
Jim Ingham7508e732010-08-09 23:31:02 +0000649 }
Jim Ingham7508e732010-08-09 23:31:02 +0000650 }
651 }
652
653 if (result.Succeeded())
654 {
655 // Okay, we're done. Last step is to warn if the executable module has changed:
Greg Clayton7e2f91c2011-01-29 07:10:55 +0000656 char new_path[PATH_MAX];
Greg Clayton5beb99d2011-08-11 02:48:45 +0000657 ModuleSP new_exec_module_sp (target->GetExecutableModule());
Jim Ingham7508e732010-08-09 23:31:02 +0000658 if (!old_exec_module_sp)
659 {
Greg Clayton7e2f91c2011-01-29 07:10:55 +0000660 // We might not have a module if we attached to a raw pid...
Greg Clayton5beb99d2011-08-11 02:48:45 +0000661 if (new_exec_module_sp)
Greg Clayton7e2f91c2011-01-29 07:10:55 +0000662 {
Greg Clayton5beb99d2011-08-11 02:48:45 +0000663 new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX);
Greg Clayton7e2f91c2011-01-29 07:10:55 +0000664 result.AppendMessageWithFormat("Executable module set to \"%s\".\n", new_path);
665 }
Jim Ingham7508e732010-08-09 23:31:02 +0000666 }
Greg Clayton5beb99d2011-08-11 02:48:45 +0000667 else if (old_exec_module_sp->GetFileSpec() != new_exec_module_sp->GetFileSpec())
Jim Ingham7508e732010-08-09 23:31:02 +0000668 {
Greg Clayton7e2f91c2011-01-29 07:10:55 +0000669 char old_path[PATH_MAX];
Jim Ingham7508e732010-08-09 23:31:02 +0000670
Greg Clayton5beb99d2011-08-11 02:48:45 +0000671 old_exec_module_sp->GetFileSpec().GetPath (old_path, PATH_MAX);
672 new_exec_module_sp->GetFileSpec().GetPath (new_path, PATH_MAX);
Jim Ingham7508e732010-08-09 23:31:02 +0000673
674 result.AppendWarningWithFormat("Executable module changed from \"%s\" to \"%s\".\n",
675 old_path, new_path);
676 }
677
678 if (!old_arch_spec.IsValid())
679 {
Greg Clayton92cb9a92012-09-14 02:41:36 +0000680 result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().GetTriple().getTriple().c_str());
Jim Ingham7508e732010-08-09 23:31:02 +0000681 }
Sean Callanan40e278c2012-12-13 22:07:14 +0000682 else if (!old_arch_spec.IsExactMatch(target->GetArchitecture()))
Jim Ingham7508e732010-08-09 23:31:02 +0000683 {
684 result.AppendWarningWithFormat("Architecture changed from %s to %s.\n",
Greg Clayton92cb9a92012-09-14 02:41:36 +0000685 old_arch_spec.GetTriple().getTriple().c_str(),
686 target->GetArchitecture().GetTriple().getTriple().c_str());
Jim Ingham7508e732010-08-09 23:31:02 +0000687 }
Johnny Chen7c099972012-05-24 00:43:00 +0000688
689 // This supports the use-case scenario of immediately continuing the process once attached.
690 if (m_options.attach_info.GetContinueOnceAttached())
Sean Callanan4336d932012-05-31 01:30:08 +0000691 m_interpreter.HandleCommand("process continue", eLazyBoolNo, result);
Jim Ingham7508e732010-08-09 23:31:02 +0000692 }
693 return result.Succeeded();
694 }
695
Chris Lattner24943d22010-06-08 16:52:24 +0000696 CommandOptions m_options;
697};
698
699
Greg Claytonb3448432011-03-24 21:19:54 +0000700OptionDefinition
Chris Lattner24943d22010-06-08 16:52:24 +0000701CommandObjectProcessAttach::CommandOptions::g_option_table[] =
702{
Jim Ingham3a458eb2012-07-20 21:37:13 +0000703{ LLDB_OPT_SET_ALL, false, "continue",'c', no_argument, NULL, 0, eArgTypeNone, "Immediately continue the process once attached."},
704{ LLDB_OPT_SET_ALL, false, "plugin", 'P', required_argument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."},
705{ LLDB_OPT_SET_1, false, "pid", 'p', required_argument, NULL, 0, eArgTypePid, "The process ID of an existing process to attach to."},
706{ LLDB_OPT_SET_2, false, "name", 'n', required_argument, NULL, 0, eArgTypeProcessName, "The name of the process to attach to."},
707{ LLDB_OPT_SET_2, false, "include-existing", 'i', no_argument, NULL, 0, eArgTypeNone, "Include existing processes when doing attach -w."},
708{ LLDB_OPT_SET_2, false, "waitfor", 'w', no_argument, NULL, 0, eArgTypeNone, "Wait for the process with <process-name> to launch."},
Caroline Tice4d6675c2010-10-01 19:59:14 +0000709{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +0000710};
711
712//-------------------------------------------------------------------------
713// CommandObjectProcessContinue
714//-------------------------------------------------------------------------
Jim Ingham22dc9722010-12-09 18:58:16 +0000715#pragma mark CommandObjectProcessContinue
Chris Lattner24943d22010-06-08 16:52:24 +0000716
Jim Inghamda26bd22012-06-08 21:56:10 +0000717class CommandObjectProcessContinue : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +0000718{
719public:
720
Greg Clayton238c0a12010-09-18 01:14:36 +0000721 CommandObjectProcessContinue (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000722 CommandObjectParsed (interpreter,
723 "process continue",
724 "Continue execution of all threads in the current process.",
725 "process continue",
Greg Claytonea0bb4d2013-01-09 19:44:40 +0000726 eFlagRequiresProcess |
727 eFlagTryTargetAPILock |
728 eFlagProcessMustBeLaunched |
729 eFlagProcessMustBePaused ),
Jim Ingham124e6902012-08-11 01:27:55 +0000730 m_options(interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000731 {
732 }
733
734
735 ~CommandObjectProcessContinue ()
736 {
737 }
738
Jim Inghamda26bd22012-06-08 21:56:10 +0000739protected:
Jim Ingham124e6902012-08-11 01:27:55 +0000740
741 class CommandOptions : public Options
742 {
743 public:
744
745 CommandOptions (CommandInterpreter &interpreter) :
746 Options(interpreter)
747 {
748 // Keep default values of all options in one place: OptionParsingStarting ()
749 OptionParsingStarting ();
750 }
751
752 ~CommandOptions ()
753 {
754 }
755
756 Error
757 SetOptionValue (uint32_t option_idx, const char *option_arg)
758 {
759 Error error;
Greg Clayton6475c422012-12-04 00:32:51 +0000760 const int short_option = m_getopt_table[option_idx].val;
Jim Ingham124e6902012-08-11 01:27:55 +0000761 bool success = false;
762 switch (short_option)
763 {
764 case 'i':
765 m_ignore = Args::StringToUInt32 (option_arg, 0, 0, &success);
766 if (!success)
767 error.SetErrorStringWithFormat ("invalid value for ignore option: \"%s\", should be a number.", option_arg);
768 break;
769
770 default:
771 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
772 break;
773 }
774 return error;
775 }
776
777 void
778 OptionParsingStarting ()
779 {
780 m_ignore = 0;
781 }
782
783 const OptionDefinition*
784 GetDefinitions ()
785 {
786 return g_option_table;
787 }
788
789 // Options table: Required for subclasses of Options.
790
791 static OptionDefinition g_option_table[];
792
793 uint32_t m_ignore;
794 };
795
Chris Lattner24943d22010-06-08 16:52:24 +0000796 bool
Greg Claytonea0bb4d2013-01-09 19:44:40 +0000797 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner24943d22010-06-08 16:52:24 +0000798 {
Greg Claytonea0bb4d2013-01-09 19:44:40 +0000799 Process *process = m_exe_ctx.GetProcessPtr();
Greg Clayton238c0a12010-09-18 01:14:36 +0000800 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner24943d22010-06-08 16:52:24 +0000801 StateType state = process->GetState();
802 if (state == eStateStopped)
803 {
804 if (command.GetArgumentCount() != 0)
805 {
806 result.AppendErrorWithFormat ("The '%s' command does not take any arguments.\n", m_cmd_name.c_str());
807 result.SetStatus (eReturnStatusFailed);
808 return false;
809 }
810
Jim Ingham124e6902012-08-11 01:27:55 +0000811 if (m_options.m_ignore > 0)
812 {
813 ThreadSP sel_thread_sp(process->GetThreadList().GetSelectedThread());
814 if (sel_thread_sp)
815 {
816 StopInfoSP stop_info_sp = sel_thread_sp->GetStopInfo();
817 if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonBreakpoint)
818 {
Greg Clayton36da2aa2013-01-25 18:06:21 +0000819 lldb::break_id_t bp_site_id = (lldb::break_id_t)stop_info_sp->GetValue();
Jim Ingham124e6902012-08-11 01:27:55 +0000820 BreakpointSiteSP bp_site_sp(process->GetBreakpointSiteList().FindByID(bp_site_id));
821 if (bp_site_sp)
822 {
Greg Clayton36da2aa2013-01-25 18:06:21 +0000823 const size_t num_owners = bp_site_sp->GetNumberOfOwners();
824 for (size_t i = 0; i < num_owners; i++)
Jim Ingham124e6902012-08-11 01:27:55 +0000825 {
826 Breakpoint &bp_ref = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
827 if (!bp_ref.IsInternal())
828 {
829 bp_ref.SetIgnoreCount(m_options.m_ignore);
830 }
831 }
832 }
833 }
834 }
835 }
836
Jim Inghamb9950592012-09-10 20:50:15 +0000837 { // Scope for thread list mutex:
838 Mutex::Locker locker (process->GetThreadList().GetMutex());
839 const uint32_t num_threads = process->GetThreadList().GetSize();
Chris Lattner24943d22010-06-08 16:52:24 +0000840
Jim Inghamb9950592012-09-10 20:50:15 +0000841 // Set the actions that the threads should each take when resuming
842 for (uint32_t idx=0; idx<num_threads; ++idx)
843 {
844 process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState (eStateRunning);
845 }
Chris Lattner24943d22010-06-08 16:52:24 +0000846 }
Jim Inghamb9950592012-09-10 20:50:15 +0000847
Chris Lattner24943d22010-06-08 16:52:24 +0000848 Error error(process->Resume());
849 if (error.Success())
850 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000851 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000852 if (synchronous_execution)
853 {
Greg Claytonbef15832010-07-14 00:18:15 +0000854 state = process->WaitForProcessToStop (NULL);
Chris Lattner24943d22010-06-08 16:52:24 +0000855
856 result.SetDidChangeProcessState (true);
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000857 result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
Chris Lattner24943d22010-06-08 16:52:24 +0000858 result.SetStatus (eReturnStatusSuccessFinishNoResult);
859 }
860 else
861 {
862 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
863 }
864 }
865 else
866 {
867 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
868 result.SetStatus (eReturnStatusFailed);
869 }
870 }
871 else
872 {
873 result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
874 StateAsCString(state));
875 result.SetStatus (eReturnStatusFailed);
876 }
877 return result.Succeeded();
878 }
Jim Ingham124e6902012-08-11 01:27:55 +0000879
880 Options *
881 GetOptions ()
882 {
883 return &m_options;
884 }
885
886 CommandOptions m_options;
887
888};
889
890OptionDefinition
891CommandObjectProcessContinue::CommandOptions::g_option_table[] =
892{
893{ LLDB_OPT_SET_ALL, false, "ignore-count",'i', required_argument, NULL, 0, eArgTypeUnsignedInteger,
894 "Ignore <N> crossings of the breakpoint (if it exists) for the currently selected thread."},
895{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +0000896};
897
898//-------------------------------------------------------------------------
899// CommandObjectProcessDetach
900//-------------------------------------------------------------------------
Jim Ingham22dc9722010-12-09 18:58:16 +0000901#pragma mark CommandObjectProcessDetach
Chris Lattner24943d22010-06-08 16:52:24 +0000902
Jim Inghamda26bd22012-06-08 21:56:10 +0000903class CommandObjectProcessDetach : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +0000904{
905public:
906
Greg Clayton238c0a12010-09-18 01:14:36 +0000907 CommandObjectProcessDetach (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000908 CommandObjectParsed (interpreter,
909 "process detach",
910 "Detach from the current process being debugged.",
911 "process detach",
Greg Claytonea0bb4d2013-01-09 19:44:40 +0000912 eFlagRequiresProcess |
913 eFlagTryTargetAPILock |
Jim Inghamda26bd22012-06-08 21:56:10 +0000914 eFlagProcessMustBeLaunched)
Chris Lattner24943d22010-06-08 16:52:24 +0000915 {
916 }
917
918 ~CommandObjectProcessDetach ()
919 {
920 }
921
Jim Inghamda26bd22012-06-08 21:56:10 +0000922protected:
Chris Lattner24943d22010-06-08 16:52:24 +0000923 bool
Greg Claytonea0bb4d2013-01-09 19:44:40 +0000924 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner24943d22010-06-08 16:52:24 +0000925 {
Greg Claytonea0bb4d2013-01-09 19:44:40 +0000926 Process *process = m_exe_ctx.GetProcessPtr();
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000927 result.AppendMessageWithFormat ("Detaching from process %" PRIu64 "\n", process->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000928 Error error (process->Detach());
929 if (error.Success())
930 {
931 result.SetStatus (eReturnStatusSuccessFinishResult);
932 }
933 else
934 {
935 result.AppendErrorWithFormat ("Detach failed: %s\n", error.AsCString());
936 result.SetStatus (eReturnStatusFailed);
937 return false;
938 }
939 return result.Succeeded();
940 }
941};
942
943//-------------------------------------------------------------------------
Greg Claytone71e2582011-02-04 01:58:07 +0000944// CommandObjectProcessConnect
945//-------------------------------------------------------------------------
946#pragma mark CommandObjectProcessConnect
947
Jim Inghamda26bd22012-06-08 21:56:10 +0000948class CommandObjectProcessConnect : public CommandObjectParsed
Greg Claytone71e2582011-02-04 01:58:07 +0000949{
950public:
951
952 class CommandOptions : public Options
953 {
954 public:
955
Greg Claytonf15996e2011-04-07 22:46:35 +0000956 CommandOptions (CommandInterpreter &interpreter) :
957 Options(interpreter)
Greg Claytone71e2582011-02-04 01:58:07 +0000958 {
Greg Clayton143fcc32011-04-13 00:18:08 +0000959 // Keep default values of all options in one place: OptionParsingStarting ()
960 OptionParsingStarting ();
Greg Claytone71e2582011-02-04 01:58:07 +0000961 }
962
963 ~CommandOptions ()
964 {
965 }
966
967 Error
Greg Clayton143fcc32011-04-13 00:18:08 +0000968 SetOptionValue (uint32_t option_idx, const char *option_arg)
Greg Claytone71e2582011-02-04 01:58:07 +0000969 {
970 Error error;
Greg Clayton6475c422012-12-04 00:32:51 +0000971 const int short_option = m_getopt_table[option_idx].val;
Greg Claytone71e2582011-02-04 01:58:07 +0000972
973 switch (short_option)
974 {
975 case 'p':
976 plugin_name.assign (option_arg);
977 break;
978
979 default:
Greg Clayton9c236732011-10-26 00:56:27 +0000980 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Greg Claytone71e2582011-02-04 01:58:07 +0000981 break;
982 }
983 return error;
984 }
985
986 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000987 OptionParsingStarting ()
Greg Claytone71e2582011-02-04 01:58:07 +0000988 {
Greg Claytone71e2582011-02-04 01:58:07 +0000989 plugin_name.clear();
990 }
991
Greg Claytonb3448432011-03-24 21:19:54 +0000992 const OptionDefinition*
Greg Claytone71e2582011-02-04 01:58:07 +0000993 GetDefinitions ()
994 {
995 return g_option_table;
996 }
997
998 // Options table: Required for subclasses of Options.
999
Greg Claytonb3448432011-03-24 21:19:54 +00001000 static OptionDefinition g_option_table[];
Greg Claytone71e2582011-02-04 01:58:07 +00001001
1002 // Instance variables to hold the values for command options.
1003
1004 std::string plugin_name;
1005 };
1006
1007 CommandObjectProcessConnect (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001008 CommandObjectParsed (interpreter,
1009 "process connect",
1010 "Connect to a remote debug service.",
1011 "process connect <remote-url>",
1012 0),
Greg Claytonf15996e2011-04-07 22:46:35 +00001013 m_options (interpreter)
Greg Claytone71e2582011-02-04 01:58:07 +00001014 {
1015 }
1016
1017 ~CommandObjectProcessConnect ()
1018 {
1019 }
1020
1021
Jim Inghamda26bd22012-06-08 21:56:10 +00001022 Options *
1023 GetOptions ()
1024 {
1025 return &m_options;
1026 }
1027
1028protected:
Greg Claytone71e2582011-02-04 01:58:07 +00001029 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001030 DoExecute (Args& command,
Greg Claytone71e2582011-02-04 01:58:07 +00001031 CommandReturnObject &result)
1032 {
1033
1034 TargetSP target_sp (m_interpreter.GetDebugger().GetSelectedTarget());
1035 Error error;
Greg Claytonea0bb4d2013-01-09 19:44:40 +00001036 Process *process = m_exe_ctx.GetProcessPtr();
Greg Claytone71e2582011-02-04 01:58:07 +00001037 if (process)
1038 {
1039 if (process->IsAlive())
1040 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001041 result.AppendErrorWithFormat ("Process %" PRIu64 " is currently being debugged, kill the process before connecting.\n",
Greg Claytone71e2582011-02-04 01:58:07 +00001042 process->GetID());
1043 result.SetStatus (eReturnStatusFailed);
1044 return false;
1045 }
1046 }
1047
1048 if (!target_sp)
1049 {
1050 // If there isn't a current target create one.
Greg Claytone71e2582011-02-04 01:58:07 +00001051
1052 error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(),
Greg Claytoned0a0fb2012-10-18 16:33:33 +00001053 NULL,
Greg Clayton3e8c25f2011-09-24 00:52:29 +00001054 NULL,
Greg Claytone71e2582011-02-04 01:58:07 +00001055 false,
Greg Clayton3e8c25f2011-09-24 00:52:29 +00001056 NULL, // No platform options
Greg Claytone71e2582011-02-04 01:58:07 +00001057 target_sp);
1058 if (!target_sp || error.Fail())
1059 {
1060 result.AppendError(error.AsCString("Error creating target"));
1061 result.SetStatus (eReturnStatusFailed);
1062 return false;
1063 }
1064 m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target_sp.get());
1065 }
1066
1067 if (command.GetArgumentCount() == 1)
1068 {
1069 const char *plugin_name = NULL;
1070 if (!m_options.plugin_name.empty())
1071 plugin_name = m_options.plugin_name.c_str();
1072
1073 const char *remote_url = command.GetArgumentAtIndex(0);
Greg Clayton46c9a352012-02-09 06:16:32 +00001074 process = target_sp->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name, NULL).get();
Greg Claytone71e2582011-02-04 01:58:07 +00001075
1076 if (process)
1077 {
Jason Molendafac2e622012-09-29 04:02:01 +00001078 error = process->ConnectRemote (&process->GetTarget().GetDebugger().GetOutputStream(), remote_url);
Greg Claytone71e2582011-02-04 01:58:07 +00001079
1080 if (error.Fail())
1081 {
1082 result.AppendError(error.AsCString("Remote connect failed"));
1083 result.SetStatus (eReturnStatusFailed);
Greg Clayton0cbb93b2012-03-31 00:10:30 +00001084 target_sp->DeleteCurrentProcess();
Greg Claytone71e2582011-02-04 01:58:07 +00001085 return false;
1086 }
1087 }
1088 else
1089 {
Jason Molenda7e5fa7f2011-09-20 21:44:10 +00001090 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 Maleadd068882012-12-18 20:00:40 +00001091 remote_url);
Greg Claytone71e2582011-02-04 01:58:07 +00001092 result.SetStatus (eReturnStatusFailed);
1093 }
1094 }
1095 else
1096 {
Jason Molenda7e5fa7f2011-09-20 21:44:10 +00001097 result.AppendErrorWithFormat ("'%s' takes exactly one argument:\nUsage: %s\n",
Greg Claytone71e2582011-02-04 01:58:07 +00001098 m_cmd_name.c_str(),
1099 m_cmd_syntax.c_str());
1100 result.SetStatus (eReturnStatusFailed);
1101 }
1102 return result.Succeeded();
1103 }
Greg Claytone71e2582011-02-04 01:58:07 +00001104
1105 CommandOptions m_options;
1106};
1107
Greg Claytonb3448432011-03-24 21:19:54 +00001108OptionDefinition
Greg Claytone71e2582011-02-04 01:58:07 +00001109CommandObjectProcessConnect::CommandOptions::g_option_table[] =
1110{
1111 { LLDB_OPT_SET_ALL, false, "plugin", 'p', required_argument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."},
1112 { 0, false, NULL, 0 , 0, NULL, 0, eArgTypeNone, NULL }
1113};
1114
1115//-------------------------------------------------------------------------
Greg Clayton13193d52012-10-13 02:07:45 +00001116// CommandObjectProcessPlugin
1117//-------------------------------------------------------------------------
1118#pragma mark CommandObjectProcessPlugin
1119
1120class CommandObjectProcessPlugin : public CommandObjectProxy
1121{
1122public:
1123
1124 CommandObjectProcessPlugin (CommandInterpreter &interpreter) :
1125 CommandObjectProxy (interpreter,
1126 "process plugin",
1127 "Send a custom command to the current process plug-in.",
1128 "process plugin <args>",
1129 0)
1130 {
1131 }
1132
1133 ~CommandObjectProcessPlugin ()
1134 {
1135 }
1136
1137 virtual CommandObject *
1138 GetProxyCommandObject()
1139 {
Greg Clayton5ebdb032013-01-09 22:58:18 +00001140 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Greg Clayton13193d52012-10-13 02:07:45 +00001141 if (process)
1142 return process->GetPluginCommandObject();
1143 return NULL;
1144 }
1145};
1146
1147
1148//-------------------------------------------------------------------------
Greg Clayton0baa3942010-11-04 01:54:29 +00001149// CommandObjectProcessLoad
1150//-------------------------------------------------------------------------
Jim Ingham22dc9722010-12-09 18:58:16 +00001151#pragma mark CommandObjectProcessLoad
Greg Clayton0baa3942010-11-04 01:54:29 +00001152
Jim Inghamda26bd22012-06-08 21:56:10 +00001153class CommandObjectProcessLoad : public CommandObjectParsed
Greg Clayton0baa3942010-11-04 01:54:29 +00001154{
1155public:
1156
1157 CommandObjectProcessLoad (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001158 CommandObjectParsed (interpreter,
1159 "process load",
1160 "Load a shared library into the current process.",
1161 "process load <filename> [<filename> ...]",
Greg Claytonea0bb4d2013-01-09 19:44:40 +00001162 eFlagRequiresProcess |
1163 eFlagTryTargetAPILock |
1164 eFlagProcessMustBeLaunched |
1165 eFlagProcessMustBePaused )
Greg Clayton0baa3942010-11-04 01:54:29 +00001166 {
1167 }
1168
1169 ~CommandObjectProcessLoad ()
1170 {
1171 }
1172
Jim Inghamda26bd22012-06-08 21:56:10 +00001173protected:
Greg Clayton0baa3942010-11-04 01:54:29 +00001174 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001175 DoExecute (Args& command,
Greg Clayton0baa3942010-11-04 01:54:29 +00001176 CommandReturnObject &result)
1177 {
Greg Claytonea0bb4d2013-01-09 19:44:40 +00001178 Process *process = m_exe_ctx.GetProcessPtr();
Greg Clayton0baa3942010-11-04 01:54:29 +00001179
Greg Clayton36da2aa2013-01-25 18:06:21 +00001180 const size_t argc = command.GetArgumentCount();
Greg Clayton0baa3942010-11-04 01:54:29 +00001181
1182 for (uint32_t i=0; i<argc; ++i)
1183 {
1184 Error error;
1185 const char *image_path = command.GetArgumentAtIndex(i);
1186 FileSpec image_spec (image_path, false);
Greg Claytonf2bf8702011-08-11 16:25:18 +00001187 process->GetTarget().GetPlatform()->ResolveRemotePath(image_spec, image_spec);
Greg Clayton0baa3942010-11-04 01:54:29 +00001188 uint32_t image_token = process->LoadImage(image_spec, error);
1189 if (image_token != LLDB_INVALID_IMAGE_TOKEN)
1190 {
1191 result.AppendMessageWithFormat ("Loading \"%s\"...ok\nImage %u loaded.\n", image_path, image_token);
1192 result.SetStatus (eReturnStatusSuccessFinishResult);
1193 }
1194 else
1195 {
1196 result.AppendErrorWithFormat ("failed to load '%s': %s", image_path, error.AsCString());
1197 result.SetStatus (eReturnStatusFailed);
1198 }
1199 }
1200 return result.Succeeded();
1201 }
1202};
1203
1204
1205//-------------------------------------------------------------------------
1206// CommandObjectProcessUnload
1207//-------------------------------------------------------------------------
Jim Ingham22dc9722010-12-09 18:58:16 +00001208#pragma mark CommandObjectProcessUnload
Greg Clayton0baa3942010-11-04 01:54:29 +00001209
Jim Inghamda26bd22012-06-08 21:56:10 +00001210class CommandObjectProcessUnload : public CommandObjectParsed
Greg Clayton0baa3942010-11-04 01:54:29 +00001211{
1212public:
1213
1214 CommandObjectProcessUnload (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001215 CommandObjectParsed (interpreter,
1216 "process unload",
1217 "Unload a shared library from the current process using the index returned by a previous call to \"process load\".",
1218 "process unload <index>",
Greg Claytonea0bb4d2013-01-09 19:44:40 +00001219 eFlagRequiresProcess |
1220 eFlagTryTargetAPILock |
1221 eFlagProcessMustBeLaunched |
1222 eFlagProcessMustBePaused )
Greg Clayton0baa3942010-11-04 01:54:29 +00001223 {
1224 }
1225
1226 ~CommandObjectProcessUnload ()
1227 {
1228 }
1229
Jim Inghamda26bd22012-06-08 21:56:10 +00001230protected:
Greg Clayton0baa3942010-11-04 01:54:29 +00001231 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001232 DoExecute (Args& command,
Greg Clayton0baa3942010-11-04 01:54:29 +00001233 CommandReturnObject &result)
1234 {
Greg Claytonea0bb4d2013-01-09 19:44:40 +00001235 Process *process = m_exe_ctx.GetProcessPtr();
Greg Clayton0baa3942010-11-04 01:54:29 +00001236
Greg Clayton36da2aa2013-01-25 18:06:21 +00001237 const size_t argc = command.GetArgumentCount();
Greg Clayton0baa3942010-11-04 01:54:29 +00001238
1239 for (uint32_t i=0; i<argc; ++i)
1240 {
1241 const char *image_token_cstr = command.GetArgumentAtIndex(i);
1242 uint32_t image_token = Args::StringToUInt32(image_token_cstr, LLDB_INVALID_IMAGE_TOKEN, 0);
1243 if (image_token == LLDB_INVALID_IMAGE_TOKEN)
1244 {
1245 result.AppendErrorWithFormat ("invalid image index argument '%s'", image_token_cstr);
1246 result.SetStatus (eReturnStatusFailed);
1247 break;
1248 }
1249 else
1250 {
1251 Error error (process->UnloadImage(image_token));
1252 if (error.Success())
1253 {
1254 result.AppendMessageWithFormat ("Unloading shared library with index %u...ok\n", image_token);
1255 result.SetStatus (eReturnStatusSuccessFinishResult);
1256 }
1257 else
1258 {
1259 result.AppendErrorWithFormat ("failed to unload image: %s", error.AsCString());
1260 result.SetStatus (eReturnStatusFailed);
1261 break;
1262 }
1263 }
1264 }
1265 return result.Succeeded();
1266 }
1267};
1268
1269//-------------------------------------------------------------------------
Chris Lattner24943d22010-06-08 16:52:24 +00001270// CommandObjectProcessSignal
1271//-------------------------------------------------------------------------
Jim Ingham22dc9722010-12-09 18:58:16 +00001272#pragma mark CommandObjectProcessSignal
Chris Lattner24943d22010-06-08 16:52:24 +00001273
Jim Inghamda26bd22012-06-08 21:56:10 +00001274class CommandObjectProcessSignal : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +00001275{
1276public:
1277
Greg Clayton238c0a12010-09-18 01:14:36 +00001278 CommandObjectProcessSignal (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001279 CommandObjectParsed (interpreter,
1280 "process signal",
1281 "Send a UNIX signal to the current process being debugged.",
Greg Claytonea0bb4d2013-01-09 19:44:40 +00001282 NULL,
1283 eFlagRequiresProcess | eFlagTryTargetAPILock)
Chris Lattner24943d22010-06-08 16:52:24 +00001284 {
Caroline Tice43b014a2010-10-04 22:28:36 +00001285 CommandArgumentEntry arg;
1286 CommandArgumentData signal_arg;
1287
1288 // Define the first (and only) variant of this arg.
Caroline Tice3a62e6d2010-10-18 22:56:57 +00001289 signal_arg.arg_type = eArgTypeUnixSignal;
Caroline Tice43b014a2010-10-04 22:28:36 +00001290 signal_arg.arg_repetition = eArgRepeatPlain;
1291
1292 // There is only one variant this argument could be; put it into the argument entry.
1293 arg.push_back (signal_arg);
1294
1295 // Push the data for the first argument into the m_arguments vector.
1296 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +00001297 }
1298
1299 ~CommandObjectProcessSignal ()
1300 {
1301 }
1302
Jim Inghamda26bd22012-06-08 21:56:10 +00001303protected:
Chris Lattner24943d22010-06-08 16:52:24 +00001304 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001305 DoExecute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +00001306 CommandReturnObject &result)
1307 {
Greg Claytonea0bb4d2013-01-09 19:44:40 +00001308 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001309
1310 if (command.GetArgumentCount() == 1)
1311 {
Greg Clayton8f6be2a2010-10-09 01:40:57 +00001312 int signo = LLDB_INVALID_SIGNAL_NUMBER;
1313
1314 const char *signal_name = command.GetArgumentAtIndex(0);
1315 if (::isxdigit (signal_name[0]))
1316 signo = Args::StringToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0);
1317 else
1318 signo = process->GetUnixSignals().GetSignalNumberFromName (signal_name);
1319
1320 if (signo == LLDB_INVALID_SIGNAL_NUMBER)
Chris Lattner24943d22010-06-08 16:52:24 +00001321 {
1322 result.AppendErrorWithFormat ("Invalid signal argument '%s'.\n", command.GetArgumentAtIndex(0));
1323 result.SetStatus (eReturnStatusFailed);
1324 }
1325 else
1326 {
1327 Error error (process->Signal (signo));
1328 if (error.Success())
1329 {
1330 result.SetStatus (eReturnStatusSuccessFinishResult);
1331 }
1332 else
1333 {
1334 result.AppendErrorWithFormat ("Failed to send signal %i: %s\n", signo, error.AsCString());
1335 result.SetStatus (eReturnStatusFailed);
1336 }
1337 }
1338 }
1339 else
1340 {
Jason Molenda7e5fa7f2011-09-20 21:44:10 +00001341 result.AppendErrorWithFormat("'%s' takes exactly one signal number argument:\nUsage: %s\n", m_cmd_name.c_str(),
Chris Lattner24943d22010-06-08 16:52:24 +00001342 m_cmd_syntax.c_str());
1343 result.SetStatus (eReturnStatusFailed);
1344 }
1345 return result.Succeeded();
1346 }
1347};
1348
1349
1350//-------------------------------------------------------------------------
1351// CommandObjectProcessInterrupt
1352//-------------------------------------------------------------------------
Jim Ingham22dc9722010-12-09 18:58:16 +00001353#pragma mark CommandObjectProcessInterrupt
Chris Lattner24943d22010-06-08 16:52:24 +00001354
Jim Inghamda26bd22012-06-08 21:56:10 +00001355class CommandObjectProcessInterrupt : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +00001356{
1357public:
1358
1359
Greg Clayton238c0a12010-09-18 01:14:36 +00001360 CommandObjectProcessInterrupt (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001361 CommandObjectParsed (interpreter,
1362 "process interrupt",
1363 "Interrupt the current process being debugged.",
1364 "process interrupt",
Greg Claytonea0bb4d2013-01-09 19:44:40 +00001365 eFlagRequiresProcess |
1366 eFlagTryTargetAPILock |
Jim Inghamda26bd22012-06-08 21:56:10 +00001367 eFlagProcessMustBeLaunched)
Chris Lattner24943d22010-06-08 16:52:24 +00001368 {
1369 }
1370
1371 ~CommandObjectProcessInterrupt ()
1372 {
1373 }
1374
Jim Inghamda26bd22012-06-08 21:56:10 +00001375protected:
Chris Lattner24943d22010-06-08 16:52:24 +00001376 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001377 DoExecute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +00001378 CommandReturnObject &result)
1379 {
Greg Claytonea0bb4d2013-01-09 19:44:40 +00001380 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001381 if (process == NULL)
1382 {
1383 result.AppendError ("no process to halt");
1384 result.SetStatus (eReturnStatusFailed);
1385 return false;
1386 }
1387
1388 if (command.GetArgumentCount() == 0)
1389 {
1390 Error error(process->Halt ());
1391 if (error.Success())
1392 {
1393 result.SetStatus (eReturnStatusSuccessFinishResult);
1394
1395 // Maybe we should add a "SuspendThreadPlans so we
1396 // can halt, and keep in place all the current thread plans.
1397 process->GetThreadList().DiscardThreadPlans();
1398 }
1399 else
1400 {
1401 result.AppendErrorWithFormat ("Failed to halt process: %s\n", error.AsCString());
1402 result.SetStatus (eReturnStatusFailed);
1403 }
1404 }
1405 else
1406 {
Jason Molenda7e5fa7f2011-09-20 21:44:10 +00001407 result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n",
Chris Lattner24943d22010-06-08 16:52:24 +00001408 m_cmd_name.c_str(),
1409 m_cmd_syntax.c_str());
1410 result.SetStatus (eReturnStatusFailed);
1411 }
1412 return result.Succeeded();
1413 }
1414};
1415
1416//-------------------------------------------------------------------------
1417// CommandObjectProcessKill
1418//-------------------------------------------------------------------------
Jim Ingham22dc9722010-12-09 18:58:16 +00001419#pragma mark CommandObjectProcessKill
Chris Lattner24943d22010-06-08 16:52:24 +00001420
Jim Inghamda26bd22012-06-08 21:56:10 +00001421class CommandObjectProcessKill : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +00001422{
1423public:
1424
Greg Clayton238c0a12010-09-18 01:14:36 +00001425 CommandObjectProcessKill (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001426 CommandObjectParsed (interpreter,
1427 "process kill",
1428 "Terminate the current process being debugged.",
1429 "process kill",
Greg Claytonea0bb4d2013-01-09 19:44:40 +00001430 eFlagRequiresProcess |
1431 eFlagTryTargetAPILock |
Jim Inghamda26bd22012-06-08 21:56:10 +00001432 eFlagProcessMustBeLaunched)
Chris Lattner24943d22010-06-08 16:52:24 +00001433 {
1434 }
1435
1436 ~CommandObjectProcessKill ()
1437 {
1438 }
1439
Jim Inghamda26bd22012-06-08 21:56:10 +00001440protected:
Chris Lattner24943d22010-06-08 16:52:24 +00001441 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001442 DoExecute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +00001443 CommandReturnObject &result)
1444 {
Greg Claytonea0bb4d2013-01-09 19:44:40 +00001445 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001446 if (process == NULL)
1447 {
1448 result.AppendError ("no process to kill");
1449 result.SetStatus (eReturnStatusFailed);
1450 return false;
1451 }
1452
1453 if (command.GetArgumentCount() == 0)
1454 {
1455 Error error (process->Destroy());
1456 if (error.Success())
1457 {
1458 result.SetStatus (eReturnStatusSuccessFinishResult);
1459 }
1460 else
1461 {
1462 result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString());
1463 result.SetStatus (eReturnStatusFailed);
1464 }
1465 }
1466 else
1467 {
Jason Molenda7e5fa7f2011-09-20 21:44:10 +00001468 result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n",
Chris Lattner24943d22010-06-08 16:52:24 +00001469 m_cmd_name.c_str(),
1470 m_cmd_syntax.c_str());
1471 result.SetStatus (eReturnStatusFailed);
1472 }
1473 return result.Succeeded();
1474 }
1475};
1476
1477//-------------------------------------------------------------------------
Jim Ingham41313fc2010-06-18 01:23:09 +00001478// CommandObjectProcessStatus
1479//-------------------------------------------------------------------------
Jim Ingham22dc9722010-12-09 18:58:16 +00001480#pragma mark CommandObjectProcessStatus
1481
Jim Inghamda26bd22012-06-08 21:56:10 +00001482class CommandObjectProcessStatus : public CommandObjectParsed
Jim Ingham41313fc2010-06-18 01:23:09 +00001483{
1484public:
Greg Clayton238c0a12010-09-18 01:14:36 +00001485 CommandObjectProcessStatus (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001486 CommandObjectParsed (interpreter,
1487 "process status",
1488 "Show the current status and location of executing process.",
1489 "process status",
Greg Claytonea0bb4d2013-01-09 19:44:40 +00001490 eFlagRequiresProcess | eFlagTryTargetAPILock)
Jim Ingham41313fc2010-06-18 01:23:09 +00001491 {
1492 }
1493
1494 ~CommandObjectProcessStatus()
1495 {
1496 }
1497
1498
1499 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001500 DoExecute (Args& command, CommandReturnObject &result)
Jim Ingham41313fc2010-06-18 01:23:09 +00001501 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001502 Stream &strm = result.GetOutputStream();
Jim Ingham41313fc2010-06-18 01:23:09 +00001503 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Greg Claytonea0bb4d2013-01-09 19:44:40 +00001504 // No need to check "process" for validity as eFlagRequiresProcess ensures it is valid
1505 Process *process = m_exe_ctx.GetProcessPtr();
1506 const bool only_threads_with_stop_reason = true;
1507 const uint32_t start_frame = 0;
1508 const uint32_t num_frames = 1;
1509 const uint32_t num_frames_with_source = 1;
1510 process->GetStatus(strm);
1511 process->GetThreadStatus (strm,
1512 only_threads_with_stop_reason,
1513 start_frame,
1514 num_frames,
1515 num_frames_with_source);
Jim Ingham41313fc2010-06-18 01:23:09 +00001516 return result.Succeeded();
1517 }
1518};
1519
1520//-------------------------------------------------------------------------
Caroline Tice23d6f272010-10-13 20:44:39 +00001521// CommandObjectProcessHandle
1522//-------------------------------------------------------------------------
Jim Ingham22dc9722010-12-09 18:58:16 +00001523#pragma mark CommandObjectProcessHandle
Caroline Tice23d6f272010-10-13 20:44:39 +00001524
Jim Inghamda26bd22012-06-08 21:56:10 +00001525class CommandObjectProcessHandle : public CommandObjectParsed
Caroline Tice23d6f272010-10-13 20:44:39 +00001526{
1527public:
1528
1529 class CommandOptions : public Options
1530 {
1531 public:
1532
Greg Claytonf15996e2011-04-07 22:46:35 +00001533 CommandOptions (CommandInterpreter &interpreter) :
1534 Options (interpreter)
Caroline Tice23d6f272010-10-13 20:44:39 +00001535 {
Greg Clayton143fcc32011-04-13 00:18:08 +00001536 OptionParsingStarting ();
Caroline Tice23d6f272010-10-13 20:44:39 +00001537 }
1538
1539 ~CommandOptions ()
1540 {
1541 }
1542
1543 Error
Greg Clayton143fcc32011-04-13 00:18:08 +00001544 SetOptionValue (uint32_t option_idx, const char *option_arg)
Caroline Tice23d6f272010-10-13 20:44:39 +00001545 {
1546 Error error;
Greg Clayton6475c422012-12-04 00:32:51 +00001547 const int short_option = m_getopt_table[option_idx].val;
Caroline Tice23d6f272010-10-13 20:44:39 +00001548
1549 switch (short_option)
1550 {
1551 case 's':
1552 stop = option_arg;
1553 break;
1554 case 'n':
1555 notify = option_arg;
1556 break;
1557 case 'p':
1558 pass = option_arg;
1559 break;
1560 default:
Greg Clayton9c236732011-10-26 00:56:27 +00001561 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Caroline Tice23d6f272010-10-13 20:44:39 +00001562 break;
1563 }
1564 return error;
1565 }
1566
1567 void
Greg Clayton143fcc32011-04-13 00:18:08 +00001568 OptionParsingStarting ()
Caroline Tice23d6f272010-10-13 20:44:39 +00001569 {
Caroline Tice23d6f272010-10-13 20:44:39 +00001570 stop.clear();
1571 notify.clear();
1572 pass.clear();
1573 }
1574
Greg Claytonb3448432011-03-24 21:19:54 +00001575 const OptionDefinition*
Caroline Tice23d6f272010-10-13 20:44:39 +00001576 GetDefinitions ()
1577 {
1578 return g_option_table;
1579 }
1580
1581 // Options table: Required for subclasses of Options.
1582
Greg Claytonb3448432011-03-24 21:19:54 +00001583 static OptionDefinition g_option_table[];
Caroline Tice23d6f272010-10-13 20:44:39 +00001584
1585 // Instance variables to hold the values for command options.
1586
1587 std::string stop;
1588 std::string notify;
1589 std::string pass;
1590 };
1591
1592
1593 CommandObjectProcessHandle (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001594 CommandObjectParsed (interpreter,
1595 "process handle",
1596 "Show or update what the process and debugger should do with various signals received from the OS.",
1597 NULL),
Greg Claytonf15996e2011-04-07 22:46:35 +00001598 m_options (interpreter)
Caroline Tice23d6f272010-10-13 20:44:39 +00001599 {
Caroline Ticee7471982010-10-14 21:31:13 +00001600 SetHelpLong ("If no signals are specified, update them all. If no update option is specified, list the current values.\n");
Caroline Tice23d6f272010-10-13 20:44:39 +00001601 CommandArgumentEntry arg;
Caroline Tice3a62e6d2010-10-18 22:56:57 +00001602 CommandArgumentData signal_arg;
Caroline Tice23d6f272010-10-13 20:44:39 +00001603
Caroline Tice3a62e6d2010-10-18 22:56:57 +00001604 signal_arg.arg_type = eArgTypeUnixSignal;
1605 signal_arg.arg_repetition = eArgRepeatStar;
Caroline Tice23d6f272010-10-13 20:44:39 +00001606
Caroline Tice3a62e6d2010-10-18 22:56:57 +00001607 arg.push_back (signal_arg);
Caroline Tice23d6f272010-10-13 20:44:39 +00001608
1609 m_arguments.push_back (arg);
1610 }
1611
1612 ~CommandObjectProcessHandle ()
1613 {
1614 }
1615
1616 Options *
1617 GetOptions ()
1618 {
1619 return &m_options;
1620 }
1621
1622 bool
Caroline Ticee7471982010-10-14 21:31:13 +00001623 VerifyCommandOptionValue (const std::string &option, int &real_value)
Caroline Tice23d6f272010-10-13 20:44:39 +00001624 {
1625 bool okay = true;
1626
Caroline Ticee7471982010-10-14 21:31:13 +00001627 bool success = false;
1628 bool tmp_value = Args::StringToBoolean (option.c_str(), false, &success);
1629
1630 if (success && tmp_value)
1631 real_value = 1;
1632 else if (success && !tmp_value)
1633 real_value = 0;
Caroline Tice23d6f272010-10-13 20:44:39 +00001634 else
1635 {
1636 // If the value isn't 'true' or 'false', it had better be 0 or 1.
Caroline Ticee7471982010-10-14 21:31:13 +00001637 real_value = Args::StringToUInt32 (option.c_str(), 3);
1638 if (real_value != 0 && real_value != 1)
Caroline Tice23d6f272010-10-13 20:44:39 +00001639 okay = false;
1640 }
1641
1642 return okay;
1643 }
1644
Caroline Ticee7471982010-10-14 21:31:13 +00001645 void
1646 PrintSignalHeader (Stream &str)
1647 {
1648 str.Printf ("NAME PASS STOP NOTIFY\n");
1649 str.Printf ("========== ===== ===== ======\n");
1650 }
1651
1652 void
1653 PrintSignal (Stream &str, int32_t signo, const char *sig_name, UnixSignals &signals)
1654 {
1655 bool stop;
1656 bool suppress;
1657 bool notify;
1658
1659 str.Printf ("%-10s ", sig_name);
1660 if (signals.GetSignalInfo (signo, suppress, stop, notify))
1661 {
1662 bool pass = !suppress;
1663 str.Printf ("%s %s %s",
1664 (pass ? "true " : "false"),
1665 (stop ? "true " : "false"),
1666 (notify ? "true " : "false"));
1667 }
1668 str.Printf ("\n");
1669 }
1670
1671 void
1672 PrintSignalInformation (Stream &str, Args &signal_args, int num_valid_signals, UnixSignals &signals)
1673 {
1674 PrintSignalHeader (str);
1675
1676 if (num_valid_signals > 0)
1677 {
1678 size_t num_args = signal_args.GetArgumentCount();
1679 for (size_t i = 0; i < num_args; ++i)
1680 {
1681 int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i));
1682 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
1683 PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals);
1684 }
1685 }
1686 else // Print info for ALL signals
1687 {
1688 int32_t signo = signals.GetFirstSignalNumber();
1689 while (signo != LLDB_INVALID_SIGNAL_NUMBER)
1690 {
1691 PrintSignal (str, signo, signals.GetSignalAsCString (signo), signals);
1692 signo = signals.GetNextSignalNumber (signo);
1693 }
1694 }
1695 }
1696
Jim Inghamda26bd22012-06-08 21:56:10 +00001697protected:
Caroline Tice23d6f272010-10-13 20:44:39 +00001698 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001699 DoExecute (Args &signal_args, CommandReturnObject &result)
Caroline Tice23d6f272010-10-13 20:44:39 +00001700 {
1701 TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
1702
1703 if (!target_sp)
1704 {
1705 result.AppendError ("No current target;"
1706 " cannot handle signals until you have a valid target and process.\n");
1707 result.SetStatus (eReturnStatusFailed);
1708 return false;
1709 }
1710
1711 ProcessSP process_sp = target_sp->GetProcessSP();
1712
1713 if (!process_sp)
1714 {
1715 result.AppendError ("No current process; cannot handle signals until you have a valid process.\n");
1716 result.SetStatus (eReturnStatusFailed);
1717 return false;
1718 }
1719
Caroline Tice23d6f272010-10-13 20:44:39 +00001720 int stop_action = -1; // -1 means leave the current setting alone
Caroline Ticee7471982010-10-14 21:31:13 +00001721 int pass_action = -1; // -1 means leave the current setting alone
Caroline Tice23d6f272010-10-13 20:44:39 +00001722 int notify_action = -1; // -1 means leave the current setting alone
1723
1724 if (! m_options.stop.empty()
Caroline Ticee7471982010-10-14 21:31:13 +00001725 && ! VerifyCommandOptionValue (m_options.stop, stop_action))
Caroline Tice23d6f272010-10-13 20:44:39 +00001726 {
1727 result.AppendError ("Invalid argument for command option --stop; must be true or false.\n");
1728 result.SetStatus (eReturnStatusFailed);
1729 return false;
1730 }
1731
1732 if (! m_options.notify.empty()
Caroline Ticee7471982010-10-14 21:31:13 +00001733 && ! VerifyCommandOptionValue (m_options.notify, notify_action))
Caroline Tice23d6f272010-10-13 20:44:39 +00001734 {
1735 result.AppendError ("Invalid argument for command option --notify; must be true or false.\n");
1736 result.SetStatus (eReturnStatusFailed);
1737 return false;
1738 }
1739
1740 if (! m_options.pass.empty()
Caroline Ticee7471982010-10-14 21:31:13 +00001741 && ! VerifyCommandOptionValue (m_options.pass, pass_action))
Caroline Tice23d6f272010-10-13 20:44:39 +00001742 {
1743 result.AppendError ("Invalid argument for command option --pass; must be true or false.\n");
1744 result.SetStatus (eReturnStatusFailed);
1745 return false;
1746 }
1747
1748 size_t num_args = signal_args.GetArgumentCount();
1749 UnixSignals &signals = process_sp->GetUnixSignals();
1750 int num_signals_set = 0;
1751
Caroline Ticee7471982010-10-14 21:31:13 +00001752 if (num_args > 0)
Caroline Tice23d6f272010-10-13 20:44:39 +00001753 {
Caroline Ticee7471982010-10-14 21:31:13 +00001754 for (size_t i = 0; i < num_args; ++i)
Caroline Tice23d6f272010-10-13 20:44:39 +00001755 {
Caroline Ticee7471982010-10-14 21:31:13 +00001756 int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i));
1757 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
Caroline Tice23d6f272010-10-13 20:44:39 +00001758 {
Caroline Ticee7471982010-10-14 21:31:13 +00001759 // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees
1760 // the value is either 0 or 1.
1761 if (stop_action != -1)
1762 signals.SetShouldStop (signo, (bool) stop_action);
1763 if (pass_action != -1)
1764 {
1765 bool suppress = ! ((bool) pass_action);
1766 signals.SetShouldSuppress (signo, suppress);
1767 }
1768 if (notify_action != -1)
1769 signals.SetShouldNotify (signo, (bool) notify_action);
1770 ++num_signals_set;
Caroline Tice23d6f272010-10-13 20:44:39 +00001771 }
Caroline Ticee7471982010-10-14 21:31:13 +00001772 else
1773 {
1774 result.AppendErrorWithFormat ("Invalid signal name '%s'\n", signal_args.GetArgumentAtIndex (i));
1775 }
Caroline Tice23d6f272010-10-13 20:44:39 +00001776 }
1777 }
Caroline Ticee7471982010-10-14 21:31:13 +00001778 else
1779 {
1780 // No signal specified, if any command options were specified, update ALL signals.
1781 if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1))
1782 {
1783 if (m_interpreter.Confirm ("Do you really want to update all the signals?", false))
1784 {
1785 int32_t signo = signals.GetFirstSignalNumber();
1786 while (signo != LLDB_INVALID_SIGNAL_NUMBER)
1787 {
1788 if (notify_action != -1)
1789 signals.SetShouldNotify (signo, (bool) notify_action);
1790 if (stop_action != -1)
1791 signals.SetShouldStop (signo, (bool) stop_action);
1792 if (pass_action != -1)
1793 {
1794 bool suppress = ! ((bool) pass_action);
1795 signals.SetShouldSuppress (signo, suppress);
1796 }
1797 signo = signals.GetNextSignalNumber (signo);
1798 }
1799 }
1800 }
1801 }
1802
1803 PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals);
Caroline Tice23d6f272010-10-13 20:44:39 +00001804
1805 if (num_signals_set > 0)
1806 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1807 else
1808 result.SetStatus (eReturnStatusFailed);
1809
1810 return result.Succeeded();
1811 }
1812
Caroline Tice23d6f272010-10-13 20:44:39 +00001813 CommandOptions m_options;
1814};
1815
Greg Claytonb3448432011-03-24 21:19:54 +00001816OptionDefinition
Caroline Tice23d6f272010-10-13 20:44:39 +00001817CommandObjectProcessHandle::CommandOptions::g_option_table[] =
1818{
1819{ LLDB_OPT_SET_1, false, "stop", 's', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the process should be stopped if the signal is received." },
1820{ LLDB_OPT_SET_1, false, "notify", 'n', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the debugger should notify the user if the signal is received." },
1821{ LLDB_OPT_SET_1, false, "pass", 'p', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." },
1822{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1823};
1824
1825//-------------------------------------------------------------------------
Chris Lattner24943d22010-06-08 16:52:24 +00001826// CommandObjectMultiwordProcess
1827//-------------------------------------------------------------------------
1828
Greg Clayton63094e02010-06-23 01:19:29 +00001829CommandObjectMultiwordProcess::CommandObjectMultiwordProcess (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001830 CommandObjectMultiword (interpreter,
1831 "process",
1832 "A set of commands for operating on a process.",
1833 "process <subcommand> [<subcommand-options>]")
Chris Lattner24943d22010-06-08 16:52:24 +00001834{
Greg Claytona9eb8272011-07-02 21:07:54 +00001835 LoadSubCommand ("attach", CommandObjectSP (new CommandObjectProcessAttach (interpreter)));
1836 LoadSubCommand ("launch", CommandObjectSP (new CommandObjectProcessLaunch (interpreter)));
1837 LoadSubCommand ("continue", CommandObjectSP (new CommandObjectProcessContinue (interpreter)));
1838 LoadSubCommand ("connect", CommandObjectSP (new CommandObjectProcessConnect (interpreter)));
1839 LoadSubCommand ("detach", CommandObjectSP (new CommandObjectProcessDetach (interpreter)));
1840 LoadSubCommand ("load", CommandObjectSP (new CommandObjectProcessLoad (interpreter)));
1841 LoadSubCommand ("unload", CommandObjectSP (new CommandObjectProcessUnload (interpreter)));
1842 LoadSubCommand ("signal", CommandObjectSP (new CommandObjectProcessSignal (interpreter)));
1843 LoadSubCommand ("handle", CommandObjectSP (new CommandObjectProcessHandle (interpreter)));
1844 LoadSubCommand ("status", CommandObjectSP (new CommandObjectProcessStatus (interpreter)));
Greg Clayton238c0a12010-09-18 01:14:36 +00001845 LoadSubCommand ("interrupt", CommandObjectSP (new CommandObjectProcessInterrupt (interpreter)));
Greg Claytona9eb8272011-07-02 21:07:54 +00001846 LoadSubCommand ("kill", CommandObjectSP (new CommandObjectProcessKill (interpreter)));
Greg Clayton13193d52012-10-13 02:07:45 +00001847 LoadSubCommand ("plugin", CommandObjectSP (new CommandObjectProcessPlugin (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +00001848}
1849
1850CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess ()
1851{
1852}
1853