blob: ab5b8063866754b475c03e67200393d76d1c8d4c [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
10#include "CommandObjectProcess.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
Jim Ingham124e6902012-08-11 01:27:55 +000016#include "lldb/Breakpoint/Breakpoint.h"
17#include "lldb/Breakpoint/BreakpointLocation.h"
18#include "lldb/Breakpoint/BreakpointSite.h"
Chris Lattner24943d22010-06-08 16:52:24 +000019#include "lldb/Core/State.h"
Greg Claytonabe0fed2011-04-18 08:33:37 +000020#include "lldb/Host/Host.h"
Jim Ingham124e6902012-08-11 01:27:55 +000021#include "lldb/Interpreter/Args.h"
22#include "lldb/Interpreter/Options.h"
Chris Lattner24943d22010-06-08 16:52:24 +000023#include "lldb/Interpreter/CommandInterpreter.h"
24#include "lldb/Interpreter/CommandReturnObject.h"
Greg Claytone4b9c1f2011-03-08 22:40:15 +000025#include "lldb/Target/Platform.h"
Chris Lattner24943d22010-06-08 16:52:24 +000026#include "lldb/Target/Process.h"
Jim Ingham124e6902012-08-11 01:27:55 +000027#include "lldb/Target/StopInfo.h"
Chris Lattner24943d22010-06-08 16:52:24 +000028#include "lldb/Target/Target.h"
29#include "lldb/Target/Thread.h"
30
31using namespace lldb;
32using namespace lldb_private;
33
34//-------------------------------------------------------------------------
35// CommandObjectProcessLaunch
36//-------------------------------------------------------------------------
Jim Ingham5a15e692012-02-16 06:50:00 +000037#pragma mark CommandObjectProcessLaunch
Jim Inghamda26bd22012-06-08 21:56:10 +000038class CommandObjectProcessLaunch : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +000039{
40public:
41
Greg Clayton238c0a12010-09-18 01:14:36 +000042 CommandObjectProcessLaunch (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +000043 CommandObjectParsed (interpreter,
44 "process launch",
45 "Launch the executable in the debugger.",
46 NULL),
Greg Claytonf15996e2011-04-07 22:46:35 +000047 m_options (interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +000048 {
Caroline Tice43b014a2010-10-04 22:28:36 +000049 CommandArgumentEntry arg;
50 CommandArgumentData run_args_arg;
51
52 // Define the first (and only) variant of this arg.
53 run_args_arg.arg_type = eArgTypeRunArgs;
54 run_args_arg.arg_repetition = eArgRepeatOptional;
55
56 // There is only one variant this argument could be; put it into the argument entry.
57 arg.push_back (run_args_arg);
58
59 // Push the data for the first argument into the m_arguments vector.
60 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +000061 }
62
63
64 ~CommandObjectProcessLaunch ()
65 {
66 }
67
Jim Ingham392d9e02012-08-10 21:48:41 +000068 int
69 HandleArgumentCompletion (Args &input,
70 int &cursor_index,
71 int &cursor_char_position,
72 OptionElementVector &opt_element_vector,
73 int match_start_point,
74 int max_return_elements,
75 bool &word_complete,
76 StringList &matches)
77 {
78 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
79 completion_str.erase (cursor_char_position);
80
81 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
82 CommandCompletions::eDiskFileCompletion,
83 completion_str.c_str(),
84 match_start_point,
85 max_return_elements,
86 NULL,
87 word_complete,
88 matches);
89 return matches.GetSize();
90 }
91
Chris Lattner24943d22010-06-08 16:52:24 +000092 Options *
93 GetOptions ()
94 {
95 return &m_options;
96 }
97
Jim Inghamda26bd22012-06-08 21:56:10 +000098 virtual const char *GetRepeatCommand (Args &current_command_args, uint32_t index)
99 {
100 // No repeat for "process launch"...
101 return "";
102 }
103
104protected:
Chris Lattner24943d22010-06-08 16:52:24 +0000105 bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000106 DoExecute (Args& launch_args, CommandReturnObject &result)
Chris Lattner24943d22010-06-08 16:52:24 +0000107 {
Greg Claytonabb33022011-11-08 02:43:13 +0000108 Debugger &debugger = m_interpreter.GetDebugger();
109 Target *target = debugger.GetSelectedTarget().get();
110 Error error;
Chris Lattner24943d22010-06-08 16:52:24 +0000111
112 if (target == NULL)
113 {
Greg Claytone1f50b92011-05-03 22:09:39 +0000114 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Chris Lattner24943d22010-06-08 16:52:24 +0000115 result.SetStatus (eReturnStatusFailed);
116 return false;
117 }
Chris Lattner24943d22010-06-08 16:52:24 +0000118 // If our listener is NULL, users aren't allows to launch
Chris Lattner24943d22010-06-08 16:52:24 +0000119 char filename[PATH_MAX];
Greg Clayton5beb99d2011-08-11 02:48:45 +0000120 const Module *exe_module = target->GetExecutableModulePointer();
Greg Claytona2f74232011-02-24 22:24:29 +0000121
122 if (exe_module == NULL)
123 {
Greg Claytone1f50b92011-05-03 22:09:39 +0000124 result.AppendError ("no file in target, create a debug target using the 'target create' command");
Greg Claytona2f74232011-02-24 22:24:29 +0000125 result.SetStatus (eReturnStatusFailed);
126 return false;
127 }
128
Greg Clayton36bc5ea2011-11-03 21:22:33 +0000129 exe_module->GetFileSpec().GetPath (filename, sizeof(filename));
Chris Lattner24943d22010-06-08 16:52:24 +0000130
Greg Clayton36bc5ea2011-11-03 21:22:33 +0000131 const bool add_exe_file_as_first_arg = true;
Greg Clayton1d1f39e2011-11-29 04:03:30 +0000132 m_options.launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), add_exe_file_as_first_arg);
Greg Clayton36bc5ea2011-11-03 21:22:33 +0000133
Greg Claytona2f74232011-02-24 22:24:29 +0000134 StateType state = eStateInvalid;
Greg Clayton567e7f32011-09-22 04:58:26 +0000135 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Greg Claytona2f74232011-02-24 22:24:29 +0000136 if (process)
137 {
138 state = process->GetState();
139
140 if (process->IsAlive() && state != eStateConnected)
141 {
142 char message[1024];
143 if (process->GetState() == eStateAttaching)
144 ::strncpy (message, "There is a pending attach, abort it and launch a new process?", sizeof(message));
145 else
146 ::strncpy (message, "There is a running process, kill it and restart?", sizeof(message));
147
148 if (!m_interpreter.Confirm (message, true))
Jim Ingham22dc9722010-12-09 18:58:16 +0000149 {
Greg Claytona2f74232011-02-24 22:24:29 +0000150 result.SetStatus (eReturnStatusFailed);
151 return false;
Jim Ingham22dc9722010-12-09 18:58:16 +0000152 }
153 else
154 {
Greg Claytonabb33022011-11-08 02:43:13 +0000155 Error destroy_error (process->Destroy());
156 if (destroy_error.Success())
Greg Claytona2f74232011-02-24 22:24:29 +0000157 {
158 result.SetStatus (eReturnStatusSuccessFinishResult);
159 }
160 else
161 {
Greg Claytonabb33022011-11-08 02:43:13 +0000162 result.AppendErrorWithFormat ("Failed to kill process: %s\n", destroy_error.AsCString());
Greg Claytona2f74232011-02-24 22:24:29 +0000163 result.SetStatus (eReturnStatusFailed);
164 }
Jim Ingham22dc9722010-12-09 18:58:16 +0000165 }
166 }
Chris Lattner24943d22010-06-08 16:52:24 +0000167 }
Jim Ingham22dc9722010-12-09 18:58:16 +0000168
Greg Clayton527154d2011-11-15 03:53:30 +0000169 if (launch_args.GetArgumentCount() == 0)
170 {
171 const Args &process_args = target->GetRunArguments();
172 if (process_args.GetArgumentCount() > 0)
173 m_options.launch_info.GetArguments().AppendArguments (process_args);
174 }
175 else
Greg Claytonabb33022011-11-08 02:43:13 +0000176 {
Greg Clayton3e6f2cc2011-11-21 21:51:18 +0000177 // Save the arguments for subsequent runs in the current target.
178 target->SetRunArguments (launch_args);
179
Greg Claytonabb33022011-11-08 02:43:13 +0000180 m_options.launch_info.GetArguments().AppendArguments (launch_args);
181 }
Greg Claytonabb33022011-11-08 02:43:13 +0000182
Greg Clayton527154d2011-11-15 03:53:30 +0000183 if (target->GetDisableASLR())
184 m_options.launch_info.GetFlags().Set (eLaunchFlagDisableASLR);
185
186 if (target->GetDisableSTDIO())
187 m_options.launch_info.GetFlags().Set (eLaunchFlagDisableSTDIO);
188
189 m_options.launch_info.GetFlags().Set (eLaunchFlagDebug);
190
191 Args environment;
192 target->GetEnvironmentAsArgs (environment);
193 if (environment.GetArgumentCount() > 0)
194 m_options.launch_info.GetEnvironmentEntries ().AppendArguments (environment);
195
Greg Clayton464c6162011-11-17 22:14:31 +0000196 // Finalize the file actions, and if none were given, default to opening
197 // up a pseudo terminal
198 const bool default_to_use_pty = true;
199 m_options.launch_info.FinalizeFileActions (target, default_to_use_pty);
Greg Clayton527154d2011-11-15 03:53:30 +0000200
Greg Claytonabb33022011-11-08 02:43:13 +0000201 if (state == eStateConnected)
202 {
203 if (m_options.launch_info.GetFlags().Test (eLaunchFlagLaunchInTTY))
204 {
205 result.AppendWarning("can't launch in tty when launching through a remote connection");
206 m_options.launch_info.GetFlags().Clear (eLaunchFlagLaunchInTTY);
207 }
208 }
209 else
Caroline Tice6e4c5ce2010-09-04 00:03:46 +0000210 {
Greg Clayton527154d2011-11-15 03:53:30 +0000211 if (!m_options.launch_info.GetArchitecture().IsValid())
Greg Clayton2d9adb72011-11-12 02:10:56 +0000212 m_options.launch_info.GetArchitecture() = target->GetArchitecture();
213
Greg Clayton75d8c252011-11-28 01:45:00 +0000214 PlatformSP platform_sp (target->GetPlatform());
215
216 if (platform_sp && platform_sp->CanDebugProcess ())
217 {
218 process = target->GetPlatform()->DebugProcess (m_options.launch_info,
219 debugger,
220 target,
221 debugger.GetListener(),
222 error).get();
223 }
224 else
225 {
226 const char *plugin_name = m_options.launch_info.GetProcessPluginName();
Greg Clayton46c9a352012-02-09 06:16:32 +0000227 process = target->CreateProcess (debugger.GetListener(), plugin_name, NULL).get();
Greg Clayton75d8c252011-11-28 01:45:00 +0000228 if (process)
229 error = process->Launch (m_options.launch_info);
230 }
Greg Claytonabb33022011-11-08 02:43:13 +0000231
Greg Claytona2f74232011-02-24 22:24:29 +0000232 if (process == NULL)
233 {
Greg Clayton527154d2011-11-15 03:53:30 +0000234 result.SetError (error, "failed to launch or debug process");
Greg Claytona2f74232011-02-24 22:24:29 +0000235 return false;
236 }
Chris Lattner24943d22010-06-08 16:52:24 +0000237 }
Greg Claytonabb33022011-11-08 02:43:13 +0000238
Greg Clayton238c0a12010-09-18 01:14:36 +0000239 if (error.Success())
240 {
Greg Clayton940b1032011-02-23 00:35:02 +0000241 const char *archname = exe_module->GetArchitecture().GetArchitectureName();
Greg Claytonc1d37752010-10-18 01:45:30 +0000242
Greg Clayton444e35b2011-10-19 18:09:39 +0000243 result.AppendMessageWithFormat ("Process %llu launched: '%s' (%s)\n", process->GetID(), filename, archname);
Greg Claytond8c62532010-10-07 04:19:01 +0000244 result.SetDidChangeProcessState (true);
Greg Clayton36bc5ea2011-11-03 21:22:33 +0000245 if (m_options.launch_info.GetFlags().Test(eLaunchFlagStopAtEntry) == false)
Greg Clayton238c0a12010-09-18 01:14:36 +0000246 {
Greg Claytond8c62532010-10-07 04:19:01 +0000247 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
Greg Clayton238c0a12010-09-18 01:14:36 +0000248 StateType state = process->WaitForProcessToStop (NULL);
249
250 if (state == eStateStopped)
251 {
Greg Claytond8c62532010-10-07 04:19:01 +0000252 error = process->Resume();
253 if (error.Success())
254 {
255 bool synchronous_execution = m_interpreter.GetSynchronous ();
256 if (synchronous_execution)
257 {
258 state = process->WaitForProcessToStop (NULL);
Greg Clayton20206082011-11-17 01:23:07 +0000259 const bool must_be_alive = true;
260 if (!StateIsStoppedState(state, must_be_alive))
Greg Clayton395fc332011-02-15 21:59:32 +0000261 {
Greg Clayton527154d2011-11-15 03:53:30 +0000262 result.AppendErrorWithFormat ("process isn't stopped: %s", StateAsCString(state));
Greg Clayton395fc332011-02-15 21:59:32 +0000263 }
Greg Claytond8c62532010-10-07 04:19:01 +0000264 result.SetDidChangeProcessState (true);
265 result.SetStatus (eReturnStatusSuccessFinishResult);
266 }
267 else
268 {
269 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
270 }
271 }
Greg Clayton395fc332011-02-15 21:59:32 +0000272 else
273 {
Greg Clayton527154d2011-11-15 03:53:30 +0000274 result.AppendErrorWithFormat ("process resume at entry point failed: %s", error.AsCString());
Greg Clayton395fc332011-02-15 21:59:32 +0000275 result.SetStatus (eReturnStatusFailed);
276 }
Greg Clayton238c0a12010-09-18 01:14:36 +0000277 }
Greg Clayton395fc332011-02-15 21:59:32 +0000278 else
279 {
Greg Clayton527154d2011-11-15 03:53:30 +0000280 result.AppendErrorWithFormat ("initial process state wasn't stopped: %s", StateAsCString(state));
Greg Clayton395fc332011-02-15 21:59:32 +0000281 result.SetStatus (eReturnStatusFailed);
282 }
Greg Clayton238c0a12010-09-18 01:14:36 +0000283 }
284 }
Greg Clayton395fc332011-02-15 21:59:32 +0000285 else
286 {
Greg Claytona9eb8272011-07-02 21:07:54 +0000287 result.AppendErrorWithFormat ("process launch failed: %s", error.AsCString());
Greg Clayton395fc332011-02-15 21:59:32 +0000288 result.SetStatus (eReturnStatusFailed);
289 }
Greg Clayton238c0a12010-09-18 01:14:36 +0000290
Chris Lattner24943d22010-06-08 16:52:24 +0000291 return result.Succeeded();
292 }
293
294protected:
Greg Clayton36bc5ea2011-11-03 21:22:33 +0000295 ProcessLaunchCommandOptions m_options;
Chris Lattner24943d22010-06-08 16:52:24 +0000296};
297
298
Greg Clayton36bc5ea2011-11-03 21:22:33 +0000299//#define SET1 LLDB_OPT_SET_1
300//#define SET2 LLDB_OPT_SET_2
301//#define SET3 LLDB_OPT_SET_3
302//
303//OptionDefinition
304//CommandObjectProcessLaunch::CommandOptions::g_option_table[] =
305//{
306//{ 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."},
307//{ SET1 , false, "stdin", 'i', required_argument, NULL, 0, eArgTypePath, "Redirect stdin for the process to <path>."},
308//{ SET1 , false, "stdout", 'o', required_argument, NULL, 0, eArgTypePath, "Redirect stdout for the process to <path>."},
309//{ SET1 , false, "stderr", 'e', required_argument, NULL, 0, eArgTypePath, "Redirect stderr for the process to <path>."},
310//{ SET1 | SET2 | SET3, false, "plugin", 'p', required_argument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."},
311//{ SET2 , false, "tty", 't', optional_argument, NULL, 0, eArgTypePath, "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."},
312//{ SET3, false, "no-stdio", 'n', no_argument, NULL, 0, eArgTypeNone, "Do not set up for terminal I/O to go to running process."},
313//{ SET1 | SET2 | SET3, false, "working-dir", 'w', required_argument, NULL, 0, eArgTypePath, "Set the current working directory to <path> when running the inferior."},
314//{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
315//};
316//
317//#undef SET1
318//#undef SET2
319//#undef SET3
Chris Lattner24943d22010-06-08 16:52:24 +0000320
321//-------------------------------------------------------------------------
322// CommandObjectProcessAttach
323//-------------------------------------------------------------------------
Jim Ingham22dc9722010-12-09 18:58:16 +0000324#pragma mark CommandObjectProcessAttach
Jim Inghamda26bd22012-06-08 21:56:10 +0000325class CommandObjectProcessAttach : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +0000326{
327public:
328
Chris Lattner24943d22010-06-08 16:52:24 +0000329 class CommandOptions : public Options
330 {
331 public:
332
Greg Claytonf15996e2011-04-07 22:46:35 +0000333 CommandOptions (CommandInterpreter &interpreter) :
334 Options(interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000335 {
Greg Clayton143fcc32011-04-13 00:18:08 +0000336 // Keep default values of all options in one place: OptionParsingStarting ()
337 OptionParsingStarting ();
Chris Lattner24943d22010-06-08 16:52:24 +0000338 }
339
340 ~CommandOptions ()
341 {
342 }
343
344 Error
Greg Clayton143fcc32011-04-13 00:18:08 +0000345 SetOptionValue (uint32_t option_idx, const char *option_arg)
Chris Lattner24943d22010-06-08 16:52:24 +0000346 {
347 Error error;
348 char short_option = (char) m_getopt_table[option_idx].val;
349 bool success = false;
350 switch (short_option)
351 {
Johnny Chen7c099972012-05-24 00:43:00 +0000352 case 'c':
353 attach_info.SetContinueOnceAttached(true);
354 break;
355
Chris Lattner24943d22010-06-08 16:52:24 +0000356 case 'p':
Chris Lattner24943d22010-06-08 16:52:24 +0000357 {
Greg Clayton527154d2011-11-15 03:53:30 +0000358 lldb::pid_t pid = Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success);
359 if (!success || pid == LLDB_INVALID_PROCESS_ID)
360 {
361 error.SetErrorStringWithFormat("invalid process ID '%s'", option_arg);
362 }
363 else
364 {
365 attach_info.SetProcessID (pid);
366 }
Chris Lattner24943d22010-06-08 16:52:24 +0000367 }
368 break;
369
370 case 'P':
Greg Clayton527154d2011-11-15 03:53:30 +0000371 attach_info.SetProcessPluginName (option_arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000372 break;
373
374 case 'n':
Greg Clayton527154d2011-11-15 03:53:30 +0000375 attach_info.GetExecutableFile().SetFile(option_arg, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000376 break;
377
378 case 'w':
Greg Clayton527154d2011-11-15 03:53:30 +0000379 attach_info.SetWaitForLaunch(true);
Chris Lattner24943d22010-06-08 16:52:24 +0000380 break;
Jim Ingham3a458eb2012-07-20 21:37:13 +0000381
382 case 'i':
383 attach_info.SetIgnoreExisting(false);
384 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000385
386 default:
Greg Clayton9c236732011-10-26 00:56:27 +0000387 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Chris Lattner24943d22010-06-08 16:52:24 +0000388 break;
389 }
390 return error;
391 }
392
393 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000394 OptionParsingStarting ()
Chris Lattner24943d22010-06-08 16:52:24 +0000395 {
Greg Clayton527154d2011-11-15 03:53:30 +0000396 attach_info.Clear();
Chris Lattner24943d22010-06-08 16:52:24 +0000397 }
398
Greg Claytonb3448432011-03-24 21:19:54 +0000399 const OptionDefinition*
Chris Lattner24943d22010-06-08 16:52:24 +0000400 GetDefinitions ()
401 {
402 return g_option_table;
403 }
404
Jim Ingham7508e732010-08-09 23:31:02 +0000405 virtual bool
Greg Claytonf15996e2011-04-07 22:46:35 +0000406 HandleOptionArgumentCompletion (Args &input,
Jim Ingham7508e732010-08-09 23:31:02 +0000407 int cursor_index,
408 int char_pos,
409 OptionElementVector &opt_element_vector,
410 int opt_element_index,
411 int match_start_point,
412 int max_return_elements,
413 bool &word_complete,
414 StringList &matches)
415 {
416 int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
417 int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
418
419 // We are only completing the name option for now...
420
Greg Claytonb3448432011-03-24 21:19:54 +0000421 const OptionDefinition *opt_defs = GetDefinitions();
Jim Ingham7508e732010-08-09 23:31:02 +0000422 if (opt_defs[opt_defs_index].short_option == 'n')
423 {
424 // Are we in the name?
425
426 // Look to see if there is a -P argument provided, and if so use that plugin, otherwise
427 // use the default plugin.
Jim Ingham7508e732010-08-09 23:31:02 +0000428
429 const char *partial_name = NULL;
430 partial_name = input.GetArgumentAtIndex(opt_arg_pos);
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000431
Greg Claytonb72d0f02011-04-12 05:54:46 +0000432 PlatformSP platform_sp (m_interpreter.GetPlatform (true));
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000433 if (platform_sp)
Jim Ingham7508e732010-08-09 23:31:02 +0000434 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000435 ProcessInstanceInfoList process_infos;
436 ProcessInstanceInfoMatch match_info;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000437 if (partial_name)
438 {
Greg Clayton527154d2011-11-15 03:53:30 +0000439 match_info.GetProcessInfo().GetExecutableFile().SetFile(partial_name, false);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000440 match_info.SetNameMatchType(eNameMatchStartsWith);
441 }
442 platform_sp->FindProcesses (match_info, process_infos);
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000443 const uint32_t num_matches = process_infos.GetSize();
444 if (num_matches > 0)
445 {
446 for (uint32_t i=0; i<num_matches; ++i)
447 {
448 matches.AppendString (process_infos.GetProcessNameAtIndex(i),
449 process_infos.GetProcessNameLengthAtIndex(i));
450 }
451 }
Jim Ingham7508e732010-08-09 23:31:02 +0000452 }
453 }
454
455 return false;
456 }
457
Chris Lattner24943d22010-06-08 16:52:24 +0000458 // Options table: Required for subclasses of Options.
459
Greg Claytonb3448432011-03-24 21:19:54 +0000460 static OptionDefinition g_option_table[];
Chris Lattner24943d22010-06-08 16:52:24 +0000461
462 // Instance variables to hold the values for command options.
463
Greg Clayton527154d2011-11-15 03:53:30 +0000464 ProcessAttachInfo attach_info;
Chris Lattner24943d22010-06-08 16:52:24 +0000465 };
466
Greg Clayton238c0a12010-09-18 01:14:36 +0000467 CommandObjectProcessAttach (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000468 CommandObjectParsed (interpreter,
469 "process attach",
470 "Attach to a process.",
471 "process attach <cmd-options>"),
Greg Claytonf15996e2011-04-07 22:46:35 +0000472 m_options (interpreter)
Jim Ingham7508e732010-08-09 23:31:02 +0000473 {
Jim Ingham7508e732010-08-09 23:31:02 +0000474 }
475
476 ~CommandObjectProcessAttach ()
477 {
478 }
479
Jim Inghamda26bd22012-06-08 21:56:10 +0000480 Options *
481 GetOptions ()
482 {
483 return &m_options;
484 }
485
486protected:
Jim Ingham7508e732010-08-09 23:31:02 +0000487 bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000488 DoExecute (Args& command,
Jim Ingham7508e732010-08-09 23:31:02 +0000489 CommandReturnObject &result)
490 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000491 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Jim Inghamee940e22011-09-15 01:08:57 +0000492 // N.B. The attach should be synchronous. It doesn't help much to get the prompt back between initiating the attach
493 // and the target actually stopping. So even if the interpreter is set to be asynchronous, we wait for the stop
494 // ourselves here.
Jim Inghamc2dc7c82011-01-29 01:49:25 +0000495
Greg Clayton567e7f32011-09-22 04:58:26 +0000496 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Greg Claytona2f74232011-02-24 22:24:29 +0000497 StateType state = eStateInvalid;
Jim Ingham7508e732010-08-09 23:31:02 +0000498 if (process)
499 {
Greg Claytona2f74232011-02-24 22:24:29 +0000500 state = process->GetState();
501 if (process->IsAlive() && state != eStateConnected)
Jim Ingham7508e732010-08-09 23:31:02 +0000502 {
Greg Clayton444e35b2011-10-19 18:09:39 +0000503 result.AppendErrorWithFormat ("Process %llu is currently being debugged, kill the process before attaching.\n",
Jim Ingham7508e732010-08-09 23:31:02 +0000504 process->GetID());
505 result.SetStatus (eReturnStatusFailed);
506 return false;
507 }
508 }
509
510 if (target == NULL)
511 {
512 // If there isn't a current target create one.
513 TargetSP new_target_sp;
514 FileSpec emptyFileSpec;
Jim Ingham7508e732010-08-09 23:31:02 +0000515 Error error;
516
Greg Clayton238c0a12010-09-18 01:14:36 +0000517 error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(),
518 emptyFileSpec,
Greg Clayton3e8c25f2011-09-24 00:52:29 +0000519 NULL,
Greg Clayton238c0a12010-09-18 01:14:36 +0000520 false,
Greg Clayton3e8c25f2011-09-24 00:52:29 +0000521 NULL, // No platform options
Greg Clayton238c0a12010-09-18 01:14:36 +0000522 new_target_sp);
Jim Ingham7508e732010-08-09 23:31:02 +0000523 target = new_target_sp.get();
524 if (target == NULL || error.Fail())
525 {
Greg Claytone71e2582011-02-04 01:58:07 +0000526 result.AppendError(error.AsCString("Error creating target"));
Jim Ingham7508e732010-08-09 23:31:02 +0000527 return false;
528 }
Greg Clayton238c0a12010-09-18 01:14:36 +0000529 m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target);
Jim Ingham7508e732010-08-09 23:31:02 +0000530 }
531
532 // Record the old executable module, we want to issue a warning if the process of attaching changed the
533 // current executable (like somebody said "file foo" then attached to a PID whose executable was bar.)
534
535 ModuleSP old_exec_module_sp = target->GetExecutableModule();
536 ArchSpec old_arch_spec = target->GetArchitecture();
537
538 if (command.GetArgumentCount())
539 {
Jason Molenda7e5fa7f2011-09-20 21:44:10 +0000540 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 +0000541 result.SetStatus (eReturnStatusFailed);
542 }
543 else
544 {
Greg Claytona2f74232011-02-24 22:24:29 +0000545 if (state != eStateConnected)
546 {
Greg Clayton527154d2011-11-15 03:53:30 +0000547 const char *plugin_name = m_options.attach_info.GetProcessPluginName();
Greg Clayton46c9a352012-02-09 06:16:32 +0000548 process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name, NULL).get();
Greg Claytona2f74232011-02-24 22:24:29 +0000549 }
Jim Ingham7508e732010-08-09 23:31:02 +0000550
551 if (process)
552 {
553 Error error;
Greg Clayton527154d2011-11-15 03:53:30 +0000554 // If no process info was specified, then use the target executable
555 // name as the process to attach to by default
556 if (!m_options.attach_info.ProcessInfoSpecified ())
Jim Ingham4805a1c2010-09-15 01:34:14 +0000557 {
558 if (old_exec_module_sp)
Greg Clayton1d1f39e2011-11-29 04:03:30 +0000559 m_options.attach_info.GetExecutableFile().GetFilename() = old_exec_module_sp->GetPlatformFileSpec().GetFilename();
Jim Ingham4805a1c2010-09-15 01:34:14 +0000560
Greg Clayton527154d2011-11-15 03:53:30 +0000561 if (!m_options.attach_info.ProcessInfoSpecified ())
562 {
563 error.SetErrorString ("no process specified, create a target with a file, or specify the --pid or --name command option");
564 }
565 }
566
567 if (error.Success())
568 {
569 error = process->Attach (m_options.attach_info);
570
Jim Ingham4805a1c2010-09-15 01:34:14 +0000571 if (error.Success())
572 {
573 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
574 }
Jim Ingham7508e732010-08-09 23:31:02 +0000575 else
576 {
Greg Clayton527154d2011-11-15 03:53:30 +0000577 result.AppendErrorWithFormat ("attach failed: %s\n", error.AsCString());
Jim Ingham4805a1c2010-09-15 01:34:14 +0000578 result.SetStatus (eReturnStatusFailed);
579 return false;
Jim Ingham7508e732010-08-09 23:31:02 +0000580 }
Jim Inghamc2dc7c82011-01-29 01:49:25 +0000581 // If we're synchronous, wait for the stopped event and report that.
582 // Otherwise just return.
583 // FIXME: in the async case it will now be possible to get to the command
584 // interpreter with a state eStateAttaching. Make sure we handle that correctly.
Jim Inghamee940e22011-09-15 01:08:57 +0000585 StateType state = process->WaitForProcessToStop (NULL);
Greg Clayton527154d2011-11-15 03:53:30 +0000586
Jim Inghamee940e22011-09-15 01:08:57 +0000587 result.SetDidChangeProcessState (true);
Johnny Chen9986a3b2012-05-18 00:51:36 +0000588
589 if (state == eStateStopped)
590 {
591 result.AppendMessageWithFormat ("Process %llu %s\n", process->GetID(), StateAsCString (state));
592 result.SetStatus (eReturnStatusSuccessFinishNoResult);
593 }
594 else
595 {
596 result.AppendError ("attach failed: process did not stop (no such process or permission problem?)");
Jim Ingham5d90ade2012-07-27 23:57:19 +0000597 process->Destroy();
Johnny Chen9986a3b2012-05-18 00:51:36 +0000598 result.SetStatus (eReturnStatusFailed);
599 return false;
600 }
Jim Ingham7508e732010-08-09 23:31:02 +0000601 }
Jim Ingham7508e732010-08-09 23:31:02 +0000602 }
603 }
604
605 if (result.Succeeded())
606 {
607 // Okay, we're done. Last step is to warn if the executable module has changed:
Greg Clayton7e2f91c2011-01-29 07:10:55 +0000608 char new_path[PATH_MAX];
Greg Clayton5beb99d2011-08-11 02:48:45 +0000609 ModuleSP new_exec_module_sp (target->GetExecutableModule());
Jim Ingham7508e732010-08-09 23:31:02 +0000610 if (!old_exec_module_sp)
611 {
Greg Clayton7e2f91c2011-01-29 07:10:55 +0000612 // We might not have a module if we attached to a raw pid...
Greg Clayton5beb99d2011-08-11 02:48:45 +0000613 if (new_exec_module_sp)
Greg Clayton7e2f91c2011-01-29 07:10:55 +0000614 {
Greg Clayton5beb99d2011-08-11 02:48:45 +0000615 new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX);
Greg Clayton7e2f91c2011-01-29 07:10:55 +0000616 result.AppendMessageWithFormat("Executable module set to \"%s\".\n", new_path);
617 }
Jim Ingham7508e732010-08-09 23:31:02 +0000618 }
Greg Clayton5beb99d2011-08-11 02:48:45 +0000619 else if (old_exec_module_sp->GetFileSpec() != new_exec_module_sp->GetFileSpec())
Jim Ingham7508e732010-08-09 23:31:02 +0000620 {
Greg Clayton7e2f91c2011-01-29 07:10:55 +0000621 char old_path[PATH_MAX];
Jim Ingham7508e732010-08-09 23:31:02 +0000622
Greg Clayton5beb99d2011-08-11 02:48:45 +0000623 old_exec_module_sp->GetFileSpec().GetPath (old_path, PATH_MAX);
624 new_exec_module_sp->GetFileSpec().GetPath (new_path, PATH_MAX);
Jim Ingham7508e732010-08-09 23:31:02 +0000625
626 result.AppendWarningWithFormat("Executable module changed from \"%s\" to \"%s\".\n",
627 old_path, new_path);
628 }
629
630 if (!old_arch_spec.IsValid())
631 {
Greg Clayton940b1032011-02-23 00:35:02 +0000632 result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().GetArchitectureName());
Jim Ingham7508e732010-08-09 23:31:02 +0000633 }
634 else if (old_arch_spec != target->GetArchitecture())
635 {
636 result.AppendWarningWithFormat("Architecture changed from %s to %s.\n",
Greg Clayton940b1032011-02-23 00:35:02 +0000637 old_arch_spec.GetArchitectureName(), target->GetArchitecture().GetArchitectureName());
Jim Ingham7508e732010-08-09 23:31:02 +0000638 }
Johnny Chen7c099972012-05-24 00:43:00 +0000639
640 // This supports the use-case scenario of immediately continuing the process once attached.
641 if (m_options.attach_info.GetContinueOnceAttached())
Sean Callanan4336d932012-05-31 01:30:08 +0000642 m_interpreter.HandleCommand("process continue", eLazyBoolNo, result);
Jim Ingham7508e732010-08-09 23:31:02 +0000643 }
644 return result.Succeeded();
645 }
646
Chris Lattner24943d22010-06-08 16:52:24 +0000647 CommandOptions m_options;
648};
649
650
Greg Claytonb3448432011-03-24 21:19:54 +0000651OptionDefinition
Chris Lattner24943d22010-06-08 16:52:24 +0000652CommandObjectProcessAttach::CommandOptions::g_option_table[] =
653{
Jim Ingham3a458eb2012-07-20 21:37:13 +0000654{ LLDB_OPT_SET_ALL, false, "continue",'c', no_argument, NULL, 0, eArgTypeNone, "Immediately continue the process once attached."},
655{ LLDB_OPT_SET_ALL, false, "plugin", 'P', required_argument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."},
656{ LLDB_OPT_SET_1, false, "pid", 'p', required_argument, NULL, 0, eArgTypePid, "The process ID of an existing process to attach to."},
657{ LLDB_OPT_SET_2, false, "name", 'n', required_argument, NULL, 0, eArgTypeProcessName, "The name of the process to attach to."},
658{ LLDB_OPT_SET_2, false, "include-existing", 'i', no_argument, NULL, 0, eArgTypeNone, "Include existing processes when doing attach -w."},
659{ 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 +0000660{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +0000661};
662
663//-------------------------------------------------------------------------
664// CommandObjectProcessContinue
665//-------------------------------------------------------------------------
Jim Ingham22dc9722010-12-09 18:58:16 +0000666#pragma mark CommandObjectProcessContinue
Chris Lattner24943d22010-06-08 16:52:24 +0000667
Jim Inghamda26bd22012-06-08 21:56:10 +0000668class CommandObjectProcessContinue : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +0000669{
670public:
671
Greg Clayton238c0a12010-09-18 01:14:36 +0000672 CommandObjectProcessContinue (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000673 CommandObjectParsed (interpreter,
674 "process continue",
675 "Continue execution of all threads in the current process.",
676 "process continue",
Jim Ingham124e6902012-08-11 01:27:55 +0000677 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
678 m_options(interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000679 {
680 }
681
682
683 ~CommandObjectProcessContinue ()
684 {
685 }
686
Jim Inghamda26bd22012-06-08 21:56:10 +0000687protected:
Jim Ingham124e6902012-08-11 01:27:55 +0000688
689 class CommandOptions : public Options
690 {
691 public:
692
693 CommandOptions (CommandInterpreter &interpreter) :
694 Options(interpreter)
695 {
696 // Keep default values of all options in one place: OptionParsingStarting ()
697 OptionParsingStarting ();
698 }
699
700 ~CommandOptions ()
701 {
702 }
703
704 Error
705 SetOptionValue (uint32_t option_idx, const char *option_arg)
706 {
707 Error error;
708 char short_option = (char) m_getopt_table[option_idx].val;
709 bool success = false;
710 switch (short_option)
711 {
712 case 'i':
713 m_ignore = Args::StringToUInt32 (option_arg, 0, 0, &success);
714 if (!success)
715 error.SetErrorStringWithFormat ("invalid value for ignore option: \"%s\", should be a number.", option_arg);
716 break;
717
718 default:
719 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
720 break;
721 }
722 return error;
723 }
724
725 void
726 OptionParsingStarting ()
727 {
728 m_ignore = 0;
729 }
730
731 const OptionDefinition*
732 GetDefinitions ()
733 {
734 return g_option_table;
735 }
736
737 // Options table: Required for subclasses of Options.
738
739 static OptionDefinition g_option_table[];
740
741 uint32_t m_ignore;
742 };
743
Chris Lattner24943d22010-06-08 16:52:24 +0000744 bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000745 DoExecute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000746 CommandReturnObject &result)
747 {
Greg Clayton567e7f32011-09-22 04:58:26 +0000748 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Greg Clayton238c0a12010-09-18 01:14:36 +0000749 bool synchronous_execution = m_interpreter.GetSynchronous ();
Chris Lattner24943d22010-06-08 16:52:24 +0000750
751 if (process == NULL)
752 {
753 result.AppendError ("no process to continue");
754 result.SetStatus (eReturnStatusFailed);
755 return false;
756 }
757
758 StateType state = process->GetState();
759 if (state == eStateStopped)
760 {
761 if (command.GetArgumentCount() != 0)
762 {
763 result.AppendErrorWithFormat ("The '%s' command does not take any arguments.\n", m_cmd_name.c_str());
764 result.SetStatus (eReturnStatusFailed);
765 return false;
766 }
767
Jim Ingham124e6902012-08-11 01:27:55 +0000768 if (m_options.m_ignore > 0)
769 {
770 ThreadSP sel_thread_sp(process->GetThreadList().GetSelectedThread());
771 if (sel_thread_sp)
772 {
773 StopInfoSP stop_info_sp = sel_thread_sp->GetStopInfo();
774 if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonBreakpoint)
775 {
776 uint64_t bp_site_id = stop_info_sp->GetValue();
777 BreakpointSiteSP bp_site_sp(process->GetBreakpointSiteList().FindByID(bp_site_id));
778 if (bp_site_sp)
779 {
780 uint32_t num_owners = bp_site_sp->GetNumberOfOwners();
781 for (uint32_t i = 0; i < num_owners; i++)
782 {
783 Breakpoint &bp_ref = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
784 if (!bp_ref.IsInternal())
785 {
786 bp_ref.SetIgnoreCount(m_options.m_ignore);
787 }
788 }
789 }
790 }
791 }
792 }
793
Chris Lattner24943d22010-06-08 16:52:24 +0000794 const uint32_t num_threads = process->GetThreadList().GetSize();
795
796 // Set the actions that the threads should each take when resuming
797 for (uint32_t idx=0; idx<num_threads; ++idx)
798 {
799 process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState (eStateRunning);
800 }
801
802 Error error(process->Resume());
803 if (error.Success())
804 {
Greg Clayton444e35b2011-10-19 18:09:39 +0000805 result.AppendMessageWithFormat ("Process %llu resuming\n", process->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000806 if (synchronous_execution)
807 {
Greg Claytonbef15832010-07-14 00:18:15 +0000808 state = process->WaitForProcessToStop (NULL);
Chris Lattner24943d22010-06-08 16:52:24 +0000809
810 result.SetDidChangeProcessState (true);
Greg Clayton444e35b2011-10-19 18:09:39 +0000811 result.AppendMessageWithFormat ("Process %llu %s\n", process->GetID(), StateAsCString (state));
Chris Lattner24943d22010-06-08 16:52:24 +0000812 result.SetStatus (eReturnStatusSuccessFinishNoResult);
813 }
814 else
815 {
816 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
817 }
818 }
819 else
820 {
821 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
822 result.SetStatus (eReturnStatusFailed);
823 }
824 }
825 else
826 {
827 result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
828 StateAsCString(state));
829 result.SetStatus (eReturnStatusFailed);
830 }
831 return result.Succeeded();
832 }
Jim Ingham124e6902012-08-11 01:27:55 +0000833
834 Options *
835 GetOptions ()
836 {
837 return &m_options;
838 }
839
840 CommandOptions m_options;
841
842};
843
844OptionDefinition
845CommandObjectProcessContinue::CommandOptions::g_option_table[] =
846{
847{ LLDB_OPT_SET_ALL, false, "ignore-count",'i', required_argument, NULL, 0, eArgTypeUnsignedInteger,
848 "Ignore <N> crossings of the breakpoint (if it exists) for the currently selected thread."},
849{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +0000850};
851
852//-------------------------------------------------------------------------
853// CommandObjectProcessDetach
854//-------------------------------------------------------------------------
Jim Ingham22dc9722010-12-09 18:58:16 +0000855#pragma mark CommandObjectProcessDetach
Chris Lattner24943d22010-06-08 16:52:24 +0000856
Jim Inghamda26bd22012-06-08 21:56:10 +0000857class CommandObjectProcessDetach : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +0000858{
859public:
860
Greg Clayton238c0a12010-09-18 01:14:36 +0000861 CommandObjectProcessDetach (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000862 CommandObjectParsed (interpreter,
863 "process detach",
864 "Detach from the current process being debugged.",
865 "process detach",
866 eFlagProcessMustBeLaunched)
Chris Lattner24943d22010-06-08 16:52:24 +0000867 {
868 }
869
870 ~CommandObjectProcessDetach ()
871 {
872 }
873
Jim Inghamda26bd22012-06-08 21:56:10 +0000874protected:
Chris Lattner24943d22010-06-08 16:52:24 +0000875 bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000876 DoExecute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000877 CommandReturnObject &result)
878 {
Greg Clayton567e7f32011-09-22 04:58:26 +0000879 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Chris Lattner24943d22010-06-08 16:52:24 +0000880 if (process == NULL)
881 {
882 result.AppendError ("must have a valid process in order to detach");
883 result.SetStatus (eReturnStatusFailed);
884 return false;
885 }
886
Greg Clayton444e35b2011-10-19 18:09:39 +0000887 result.AppendMessageWithFormat ("Detaching from process %llu\n", process->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000888 Error error (process->Detach());
889 if (error.Success())
890 {
891 result.SetStatus (eReturnStatusSuccessFinishResult);
892 }
893 else
894 {
895 result.AppendErrorWithFormat ("Detach failed: %s\n", error.AsCString());
896 result.SetStatus (eReturnStatusFailed);
897 return false;
898 }
899 return result.Succeeded();
900 }
901};
902
903//-------------------------------------------------------------------------
Greg Claytone71e2582011-02-04 01:58:07 +0000904// CommandObjectProcessConnect
905//-------------------------------------------------------------------------
906#pragma mark CommandObjectProcessConnect
907
Jim Inghamda26bd22012-06-08 21:56:10 +0000908class CommandObjectProcessConnect : public CommandObjectParsed
Greg Claytone71e2582011-02-04 01:58:07 +0000909{
910public:
911
912 class CommandOptions : public Options
913 {
914 public:
915
Greg Claytonf15996e2011-04-07 22:46:35 +0000916 CommandOptions (CommandInterpreter &interpreter) :
917 Options(interpreter)
Greg Claytone71e2582011-02-04 01:58:07 +0000918 {
Greg Clayton143fcc32011-04-13 00:18:08 +0000919 // Keep default values of all options in one place: OptionParsingStarting ()
920 OptionParsingStarting ();
Greg Claytone71e2582011-02-04 01:58:07 +0000921 }
922
923 ~CommandOptions ()
924 {
925 }
926
927 Error
Greg Clayton143fcc32011-04-13 00:18:08 +0000928 SetOptionValue (uint32_t option_idx, const char *option_arg)
Greg Claytone71e2582011-02-04 01:58:07 +0000929 {
930 Error error;
931 char short_option = (char) m_getopt_table[option_idx].val;
932
933 switch (short_option)
934 {
935 case 'p':
936 plugin_name.assign (option_arg);
937 break;
938
939 default:
Greg Clayton9c236732011-10-26 00:56:27 +0000940 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Greg Claytone71e2582011-02-04 01:58:07 +0000941 break;
942 }
943 return error;
944 }
945
946 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000947 OptionParsingStarting ()
Greg Claytone71e2582011-02-04 01:58:07 +0000948 {
Greg Claytone71e2582011-02-04 01:58:07 +0000949 plugin_name.clear();
950 }
951
Greg Claytonb3448432011-03-24 21:19:54 +0000952 const OptionDefinition*
Greg Claytone71e2582011-02-04 01:58:07 +0000953 GetDefinitions ()
954 {
955 return g_option_table;
956 }
957
958 // Options table: Required for subclasses of Options.
959
Greg Claytonb3448432011-03-24 21:19:54 +0000960 static OptionDefinition g_option_table[];
Greg Claytone71e2582011-02-04 01:58:07 +0000961
962 // Instance variables to hold the values for command options.
963
964 std::string plugin_name;
965 };
966
967 CommandObjectProcessConnect (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000968 CommandObjectParsed (interpreter,
969 "process connect",
970 "Connect to a remote debug service.",
971 "process connect <remote-url>",
972 0),
Greg Claytonf15996e2011-04-07 22:46:35 +0000973 m_options (interpreter)
Greg Claytone71e2582011-02-04 01:58:07 +0000974 {
975 }
976
977 ~CommandObjectProcessConnect ()
978 {
979 }
980
981
Jim Inghamda26bd22012-06-08 21:56:10 +0000982 Options *
983 GetOptions ()
984 {
985 return &m_options;
986 }
987
988protected:
Greg Claytone71e2582011-02-04 01:58:07 +0000989 bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000990 DoExecute (Args& command,
Greg Claytone71e2582011-02-04 01:58:07 +0000991 CommandReturnObject &result)
992 {
993
994 TargetSP target_sp (m_interpreter.GetDebugger().GetSelectedTarget());
995 Error error;
Greg Clayton567e7f32011-09-22 04:58:26 +0000996 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Greg Claytone71e2582011-02-04 01:58:07 +0000997 if (process)
998 {
999 if (process->IsAlive())
1000 {
Greg Clayton444e35b2011-10-19 18:09:39 +00001001 result.AppendErrorWithFormat ("Process %llu is currently being debugged, kill the process before connecting.\n",
Greg Claytone71e2582011-02-04 01:58:07 +00001002 process->GetID());
1003 result.SetStatus (eReturnStatusFailed);
1004 return false;
1005 }
1006 }
1007
1008 if (!target_sp)
1009 {
1010 // If there isn't a current target create one.
1011 FileSpec emptyFileSpec;
Greg Claytone71e2582011-02-04 01:58:07 +00001012
1013 error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(),
1014 emptyFileSpec,
Greg Clayton3e8c25f2011-09-24 00:52:29 +00001015 NULL,
Greg Claytone71e2582011-02-04 01:58:07 +00001016 false,
Greg Clayton3e8c25f2011-09-24 00:52:29 +00001017 NULL, // No platform options
Greg Claytone71e2582011-02-04 01:58:07 +00001018 target_sp);
1019 if (!target_sp || error.Fail())
1020 {
1021 result.AppendError(error.AsCString("Error creating target"));
1022 result.SetStatus (eReturnStatusFailed);
1023 return false;
1024 }
1025 m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target_sp.get());
1026 }
1027
1028 if (command.GetArgumentCount() == 1)
1029 {
1030 const char *plugin_name = NULL;
1031 if (!m_options.plugin_name.empty())
1032 plugin_name = m_options.plugin_name.c_str();
1033
1034 const char *remote_url = command.GetArgumentAtIndex(0);
Greg Clayton46c9a352012-02-09 06:16:32 +00001035 process = target_sp->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name, NULL).get();
Greg Claytone71e2582011-02-04 01:58:07 +00001036
1037 if (process)
1038 {
1039 error = process->ConnectRemote (remote_url);
1040
1041 if (error.Fail())
1042 {
1043 result.AppendError(error.AsCString("Remote connect failed"));
1044 result.SetStatus (eReturnStatusFailed);
Greg Clayton0cbb93b2012-03-31 00:10:30 +00001045 target_sp->DeleteCurrentProcess();
Greg Claytone71e2582011-02-04 01:58:07 +00001046 return false;
1047 }
1048 }
1049 else
1050 {
Jason Molenda7e5fa7f2011-09-20 21:44:10 +00001051 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",
1052 m_cmd_name.c_str());
Greg Claytone71e2582011-02-04 01:58:07 +00001053 result.SetStatus (eReturnStatusFailed);
1054 }
1055 }
1056 else
1057 {
Jason Molenda7e5fa7f2011-09-20 21:44:10 +00001058 result.AppendErrorWithFormat ("'%s' takes exactly one argument:\nUsage: %s\n",
Greg Claytone71e2582011-02-04 01:58:07 +00001059 m_cmd_name.c_str(),
1060 m_cmd_syntax.c_str());
1061 result.SetStatus (eReturnStatusFailed);
1062 }
1063 return result.Succeeded();
1064 }
Greg Claytone71e2582011-02-04 01:58:07 +00001065
1066 CommandOptions m_options;
1067};
1068
1069
Greg Claytonb3448432011-03-24 21:19:54 +00001070OptionDefinition
Greg Claytone71e2582011-02-04 01:58:07 +00001071CommandObjectProcessConnect::CommandOptions::g_option_table[] =
1072{
1073 { LLDB_OPT_SET_ALL, false, "plugin", 'p', required_argument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."},
1074 { 0, false, NULL, 0 , 0, NULL, 0, eArgTypeNone, NULL }
1075};
1076
1077//-------------------------------------------------------------------------
Greg Clayton0baa3942010-11-04 01:54:29 +00001078// CommandObjectProcessLoad
1079//-------------------------------------------------------------------------
Jim Ingham22dc9722010-12-09 18:58:16 +00001080#pragma mark CommandObjectProcessLoad
Greg Clayton0baa3942010-11-04 01:54:29 +00001081
Jim Inghamda26bd22012-06-08 21:56:10 +00001082class CommandObjectProcessLoad : public CommandObjectParsed
Greg Clayton0baa3942010-11-04 01:54:29 +00001083{
1084public:
1085
1086 CommandObjectProcessLoad (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001087 CommandObjectParsed (interpreter,
1088 "process load",
1089 "Load a shared library into the current process.",
1090 "process load <filename> [<filename> ...]",
1091 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
Greg Clayton0baa3942010-11-04 01:54:29 +00001092 {
1093 }
1094
1095 ~CommandObjectProcessLoad ()
1096 {
1097 }
1098
Jim Inghamda26bd22012-06-08 21:56:10 +00001099protected:
Greg Clayton0baa3942010-11-04 01:54:29 +00001100 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001101 DoExecute (Args& command,
Greg Clayton0baa3942010-11-04 01:54:29 +00001102 CommandReturnObject &result)
1103 {
Greg Clayton567e7f32011-09-22 04:58:26 +00001104 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Greg Clayton0baa3942010-11-04 01:54:29 +00001105 if (process == NULL)
1106 {
1107 result.AppendError ("must have a valid process in order to load a shared library");
1108 result.SetStatus (eReturnStatusFailed);
1109 return false;
1110 }
1111
1112 const uint32_t argc = command.GetArgumentCount();
1113
1114 for (uint32_t i=0; i<argc; ++i)
1115 {
1116 Error error;
1117 const char *image_path = command.GetArgumentAtIndex(i);
1118 FileSpec image_spec (image_path, false);
Greg Claytonf2bf8702011-08-11 16:25:18 +00001119 process->GetTarget().GetPlatform()->ResolveRemotePath(image_spec, image_spec);
Greg Clayton0baa3942010-11-04 01:54:29 +00001120 uint32_t image_token = process->LoadImage(image_spec, error);
1121 if (image_token != LLDB_INVALID_IMAGE_TOKEN)
1122 {
1123 result.AppendMessageWithFormat ("Loading \"%s\"...ok\nImage %u loaded.\n", image_path, image_token);
1124 result.SetStatus (eReturnStatusSuccessFinishResult);
1125 }
1126 else
1127 {
1128 result.AppendErrorWithFormat ("failed to load '%s': %s", image_path, error.AsCString());
1129 result.SetStatus (eReturnStatusFailed);
1130 }
1131 }
1132 return result.Succeeded();
1133 }
1134};
1135
1136
1137//-------------------------------------------------------------------------
1138// CommandObjectProcessUnload
1139//-------------------------------------------------------------------------
Jim Ingham22dc9722010-12-09 18:58:16 +00001140#pragma mark CommandObjectProcessUnload
Greg Clayton0baa3942010-11-04 01:54:29 +00001141
Jim Inghamda26bd22012-06-08 21:56:10 +00001142class CommandObjectProcessUnload : public CommandObjectParsed
Greg Clayton0baa3942010-11-04 01:54:29 +00001143{
1144public:
1145
1146 CommandObjectProcessUnload (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001147 CommandObjectParsed (interpreter,
1148 "process unload",
1149 "Unload a shared library from the current process using the index returned by a previous call to \"process load\".",
1150 "process unload <index>",
1151 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
Greg Clayton0baa3942010-11-04 01:54:29 +00001152 {
1153 }
1154
1155 ~CommandObjectProcessUnload ()
1156 {
1157 }
1158
Jim Inghamda26bd22012-06-08 21:56:10 +00001159protected:
Greg Clayton0baa3942010-11-04 01:54:29 +00001160 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001161 DoExecute (Args& command,
Greg Clayton0baa3942010-11-04 01:54:29 +00001162 CommandReturnObject &result)
1163 {
Greg Clayton567e7f32011-09-22 04:58:26 +00001164 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Greg Clayton0baa3942010-11-04 01:54:29 +00001165 if (process == NULL)
1166 {
1167 result.AppendError ("must have a valid process in order to load a shared library");
1168 result.SetStatus (eReturnStatusFailed);
1169 return false;
1170 }
1171
1172 const uint32_t argc = command.GetArgumentCount();
1173
1174 for (uint32_t i=0; i<argc; ++i)
1175 {
1176 const char *image_token_cstr = command.GetArgumentAtIndex(i);
1177 uint32_t image_token = Args::StringToUInt32(image_token_cstr, LLDB_INVALID_IMAGE_TOKEN, 0);
1178 if (image_token == LLDB_INVALID_IMAGE_TOKEN)
1179 {
1180 result.AppendErrorWithFormat ("invalid image index argument '%s'", image_token_cstr);
1181 result.SetStatus (eReturnStatusFailed);
1182 break;
1183 }
1184 else
1185 {
1186 Error error (process->UnloadImage(image_token));
1187 if (error.Success())
1188 {
1189 result.AppendMessageWithFormat ("Unloading shared library with index %u...ok\n", image_token);
1190 result.SetStatus (eReturnStatusSuccessFinishResult);
1191 }
1192 else
1193 {
1194 result.AppendErrorWithFormat ("failed to unload image: %s", error.AsCString());
1195 result.SetStatus (eReturnStatusFailed);
1196 break;
1197 }
1198 }
1199 }
1200 return result.Succeeded();
1201 }
1202};
1203
1204//-------------------------------------------------------------------------
Chris Lattner24943d22010-06-08 16:52:24 +00001205// CommandObjectProcessSignal
1206//-------------------------------------------------------------------------
Jim Ingham22dc9722010-12-09 18:58:16 +00001207#pragma mark CommandObjectProcessSignal
Chris Lattner24943d22010-06-08 16:52:24 +00001208
Jim Inghamda26bd22012-06-08 21:56:10 +00001209class CommandObjectProcessSignal : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +00001210{
1211public:
1212
Greg Clayton238c0a12010-09-18 01:14:36 +00001213 CommandObjectProcessSignal (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001214 CommandObjectParsed (interpreter,
1215 "process signal",
1216 "Send a UNIX signal to the current process being debugged.",
1217 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +00001218 {
Caroline Tice43b014a2010-10-04 22:28:36 +00001219 CommandArgumentEntry arg;
1220 CommandArgumentData signal_arg;
1221
1222 // Define the first (and only) variant of this arg.
Caroline Tice3a62e6d2010-10-18 22:56:57 +00001223 signal_arg.arg_type = eArgTypeUnixSignal;
Caroline Tice43b014a2010-10-04 22:28:36 +00001224 signal_arg.arg_repetition = eArgRepeatPlain;
1225
1226 // There is only one variant this argument could be; put it into the argument entry.
1227 arg.push_back (signal_arg);
1228
1229 // Push the data for the first argument into the m_arguments vector.
1230 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +00001231 }
1232
1233 ~CommandObjectProcessSignal ()
1234 {
1235 }
1236
Jim Inghamda26bd22012-06-08 21:56:10 +00001237protected:
Chris Lattner24943d22010-06-08 16:52:24 +00001238 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001239 DoExecute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +00001240 CommandReturnObject &result)
1241 {
Greg Clayton567e7f32011-09-22 04:58:26 +00001242 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001243 if (process == NULL)
1244 {
1245 result.AppendError ("no process to signal");
1246 result.SetStatus (eReturnStatusFailed);
1247 return false;
1248 }
1249
1250 if (command.GetArgumentCount() == 1)
1251 {
Greg Clayton8f6be2a2010-10-09 01:40:57 +00001252 int signo = LLDB_INVALID_SIGNAL_NUMBER;
1253
1254 const char *signal_name = command.GetArgumentAtIndex(0);
1255 if (::isxdigit (signal_name[0]))
1256 signo = Args::StringToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0);
1257 else
1258 signo = process->GetUnixSignals().GetSignalNumberFromName (signal_name);
1259
1260 if (signo == LLDB_INVALID_SIGNAL_NUMBER)
Chris Lattner24943d22010-06-08 16:52:24 +00001261 {
1262 result.AppendErrorWithFormat ("Invalid signal argument '%s'.\n", command.GetArgumentAtIndex(0));
1263 result.SetStatus (eReturnStatusFailed);
1264 }
1265 else
1266 {
1267 Error error (process->Signal (signo));
1268 if (error.Success())
1269 {
1270 result.SetStatus (eReturnStatusSuccessFinishResult);
1271 }
1272 else
1273 {
1274 result.AppendErrorWithFormat ("Failed to send signal %i: %s\n", signo, error.AsCString());
1275 result.SetStatus (eReturnStatusFailed);
1276 }
1277 }
1278 }
1279 else
1280 {
Jason Molenda7e5fa7f2011-09-20 21:44:10 +00001281 result.AppendErrorWithFormat("'%s' takes exactly one signal number argument:\nUsage: %s\n", m_cmd_name.c_str(),
Chris Lattner24943d22010-06-08 16:52:24 +00001282 m_cmd_syntax.c_str());
1283 result.SetStatus (eReturnStatusFailed);
1284 }
1285 return result.Succeeded();
1286 }
1287};
1288
1289
1290//-------------------------------------------------------------------------
1291// CommandObjectProcessInterrupt
1292//-------------------------------------------------------------------------
Jim Ingham22dc9722010-12-09 18:58:16 +00001293#pragma mark CommandObjectProcessInterrupt
Chris Lattner24943d22010-06-08 16:52:24 +00001294
Jim Inghamda26bd22012-06-08 21:56:10 +00001295class CommandObjectProcessInterrupt : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +00001296{
1297public:
1298
1299
Greg Clayton238c0a12010-09-18 01:14:36 +00001300 CommandObjectProcessInterrupt (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001301 CommandObjectParsed (interpreter,
1302 "process interrupt",
1303 "Interrupt the current process being debugged.",
1304 "process interrupt",
1305 eFlagProcessMustBeLaunched)
Chris Lattner24943d22010-06-08 16:52:24 +00001306 {
1307 }
1308
1309 ~CommandObjectProcessInterrupt ()
1310 {
1311 }
1312
Jim Inghamda26bd22012-06-08 21:56:10 +00001313protected:
Chris Lattner24943d22010-06-08 16:52:24 +00001314 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001315 DoExecute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +00001316 CommandReturnObject &result)
1317 {
Greg Clayton567e7f32011-09-22 04:58:26 +00001318 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001319 if (process == NULL)
1320 {
1321 result.AppendError ("no process to halt");
1322 result.SetStatus (eReturnStatusFailed);
1323 return false;
1324 }
1325
1326 if (command.GetArgumentCount() == 0)
1327 {
1328 Error error(process->Halt ());
1329 if (error.Success())
1330 {
1331 result.SetStatus (eReturnStatusSuccessFinishResult);
1332
1333 // Maybe we should add a "SuspendThreadPlans so we
1334 // can halt, and keep in place all the current thread plans.
1335 process->GetThreadList().DiscardThreadPlans();
1336 }
1337 else
1338 {
1339 result.AppendErrorWithFormat ("Failed to halt process: %s\n", error.AsCString());
1340 result.SetStatus (eReturnStatusFailed);
1341 }
1342 }
1343 else
1344 {
Jason Molenda7e5fa7f2011-09-20 21:44:10 +00001345 result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n",
Chris Lattner24943d22010-06-08 16:52:24 +00001346 m_cmd_name.c_str(),
1347 m_cmd_syntax.c_str());
1348 result.SetStatus (eReturnStatusFailed);
1349 }
1350 return result.Succeeded();
1351 }
1352};
1353
1354//-------------------------------------------------------------------------
1355// CommandObjectProcessKill
1356//-------------------------------------------------------------------------
Jim Ingham22dc9722010-12-09 18:58:16 +00001357#pragma mark CommandObjectProcessKill
Chris Lattner24943d22010-06-08 16:52:24 +00001358
Jim Inghamda26bd22012-06-08 21:56:10 +00001359class CommandObjectProcessKill : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +00001360{
1361public:
1362
Greg Clayton238c0a12010-09-18 01:14:36 +00001363 CommandObjectProcessKill (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001364 CommandObjectParsed (interpreter,
1365 "process kill",
1366 "Terminate the current process being debugged.",
1367 "process kill",
1368 eFlagProcessMustBeLaunched)
Chris Lattner24943d22010-06-08 16:52:24 +00001369 {
1370 }
1371
1372 ~CommandObjectProcessKill ()
1373 {
1374 }
1375
Jim Inghamda26bd22012-06-08 21:56:10 +00001376protected:
Chris Lattner24943d22010-06-08 16:52:24 +00001377 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001378 DoExecute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +00001379 CommandReturnObject &result)
1380 {
Greg Clayton567e7f32011-09-22 04:58:26 +00001381 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001382 if (process == NULL)
1383 {
1384 result.AppendError ("no process to kill");
1385 result.SetStatus (eReturnStatusFailed);
1386 return false;
1387 }
1388
1389 if (command.GetArgumentCount() == 0)
1390 {
1391 Error error (process->Destroy());
1392 if (error.Success())
1393 {
1394 result.SetStatus (eReturnStatusSuccessFinishResult);
1395 }
1396 else
1397 {
1398 result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString());
1399 result.SetStatus (eReturnStatusFailed);
1400 }
1401 }
1402 else
1403 {
Jason Molenda7e5fa7f2011-09-20 21:44:10 +00001404 result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n",
Chris Lattner24943d22010-06-08 16:52:24 +00001405 m_cmd_name.c_str(),
1406 m_cmd_syntax.c_str());
1407 result.SetStatus (eReturnStatusFailed);
1408 }
1409 return result.Succeeded();
1410 }
1411};
1412
1413//-------------------------------------------------------------------------
Jim Ingham41313fc2010-06-18 01:23:09 +00001414// CommandObjectProcessStatus
1415//-------------------------------------------------------------------------
Jim Ingham22dc9722010-12-09 18:58:16 +00001416#pragma mark CommandObjectProcessStatus
1417
Jim Inghamda26bd22012-06-08 21:56:10 +00001418class CommandObjectProcessStatus : public CommandObjectParsed
Jim Ingham41313fc2010-06-18 01:23:09 +00001419{
1420public:
Greg Clayton238c0a12010-09-18 01:14:36 +00001421 CommandObjectProcessStatus (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001422 CommandObjectParsed (interpreter,
1423 "process status",
1424 "Show the current status and location of executing process.",
1425 "process status",
1426 0)
Jim Ingham41313fc2010-06-18 01:23:09 +00001427 {
1428 }
1429
1430 ~CommandObjectProcessStatus()
1431 {
1432 }
1433
1434
1435 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001436 DoExecute (Args& command, CommandReturnObject &result)
Jim Ingham41313fc2010-06-18 01:23:09 +00001437 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001438 Stream &strm = result.GetOutputStream();
Jim Ingham41313fc2010-06-18 01:23:09 +00001439 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Greg Claytonb72d0f02011-04-12 05:54:46 +00001440 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
Greg Clayton567e7f32011-09-22 04:58:26 +00001441 Process *process = exe_ctx.GetProcessPtr();
1442 if (process)
Jim Ingham41313fc2010-06-18 01:23:09 +00001443 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001444 const bool only_threads_with_stop_reason = true;
1445 const uint32_t start_frame = 0;
1446 const uint32_t num_frames = 1;
1447 const uint32_t num_frames_with_source = 1;
Greg Clayton567e7f32011-09-22 04:58:26 +00001448 process->GetStatus(strm);
1449 process->GetThreadStatus (strm,
1450 only_threads_with_stop_reason,
1451 start_frame,
1452 num_frames,
1453 num_frames_with_source);
Greg Claytonabe0fed2011-04-18 08:33:37 +00001454
Jim Ingham41313fc2010-06-18 01:23:09 +00001455 }
1456 else
1457 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001458 result.AppendError ("No process.");
Jim Ingham41313fc2010-06-18 01:23:09 +00001459 result.SetStatus (eReturnStatusFailed);
1460 }
1461 return result.Succeeded();
1462 }
1463};
1464
1465//-------------------------------------------------------------------------
Caroline Tice23d6f272010-10-13 20:44:39 +00001466// CommandObjectProcessHandle
1467//-------------------------------------------------------------------------
Jim Ingham22dc9722010-12-09 18:58:16 +00001468#pragma mark CommandObjectProcessHandle
Caroline Tice23d6f272010-10-13 20:44:39 +00001469
Jim Inghamda26bd22012-06-08 21:56:10 +00001470class CommandObjectProcessHandle : public CommandObjectParsed
Caroline Tice23d6f272010-10-13 20:44:39 +00001471{
1472public:
1473
1474 class CommandOptions : public Options
1475 {
1476 public:
1477
Greg Claytonf15996e2011-04-07 22:46:35 +00001478 CommandOptions (CommandInterpreter &interpreter) :
1479 Options (interpreter)
Caroline Tice23d6f272010-10-13 20:44:39 +00001480 {
Greg Clayton143fcc32011-04-13 00:18:08 +00001481 OptionParsingStarting ();
Caroline Tice23d6f272010-10-13 20:44:39 +00001482 }
1483
1484 ~CommandOptions ()
1485 {
1486 }
1487
1488 Error
Greg Clayton143fcc32011-04-13 00:18:08 +00001489 SetOptionValue (uint32_t option_idx, const char *option_arg)
Caroline Tice23d6f272010-10-13 20:44:39 +00001490 {
1491 Error error;
1492 char short_option = (char) m_getopt_table[option_idx].val;
1493
1494 switch (short_option)
1495 {
1496 case 's':
1497 stop = option_arg;
1498 break;
1499 case 'n':
1500 notify = option_arg;
1501 break;
1502 case 'p':
1503 pass = option_arg;
1504 break;
1505 default:
Greg Clayton9c236732011-10-26 00:56:27 +00001506 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Caroline Tice23d6f272010-10-13 20:44:39 +00001507 break;
1508 }
1509 return error;
1510 }
1511
1512 void
Greg Clayton143fcc32011-04-13 00:18:08 +00001513 OptionParsingStarting ()
Caroline Tice23d6f272010-10-13 20:44:39 +00001514 {
Caroline Tice23d6f272010-10-13 20:44:39 +00001515 stop.clear();
1516 notify.clear();
1517 pass.clear();
1518 }
1519
Greg Claytonb3448432011-03-24 21:19:54 +00001520 const OptionDefinition*
Caroline Tice23d6f272010-10-13 20:44:39 +00001521 GetDefinitions ()
1522 {
1523 return g_option_table;
1524 }
1525
1526 // Options table: Required for subclasses of Options.
1527
Greg Claytonb3448432011-03-24 21:19:54 +00001528 static OptionDefinition g_option_table[];
Caroline Tice23d6f272010-10-13 20:44:39 +00001529
1530 // Instance variables to hold the values for command options.
1531
1532 std::string stop;
1533 std::string notify;
1534 std::string pass;
1535 };
1536
1537
1538 CommandObjectProcessHandle (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001539 CommandObjectParsed (interpreter,
1540 "process handle",
1541 "Show or update what the process and debugger should do with various signals received from the OS.",
1542 NULL),
Greg Claytonf15996e2011-04-07 22:46:35 +00001543 m_options (interpreter)
Caroline Tice23d6f272010-10-13 20:44:39 +00001544 {
Caroline Ticee7471982010-10-14 21:31:13 +00001545 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 +00001546 CommandArgumentEntry arg;
Caroline Tice3a62e6d2010-10-18 22:56:57 +00001547 CommandArgumentData signal_arg;
Caroline Tice23d6f272010-10-13 20:44:39 +00001548
Caroline Tice3a62e6d2010-10-18 22:56:57 +00001549 signal_arg.arg_type = eArgTypeUnixSignal;
1550 signal_arg.arg_repetition = eArgRepeatStar;
Caroline Tice23d6f272010-10-13 20:44:39 +00001551
Caroline Tice3a62e6d2010-10-18 22:56:57 +00001552 arg.push_back (signal_arg);
Caroline Tice23d6f272010-10-13 20:44:39 +00001553
1554 m_arguments.push_back (arg);
1555 }
1556
1557 ~CommandObjectProcessHandle ()
1558 {
1559 }
1560
1561 Options *
1562 GetOptions ()
1563 {
1564 return &m_options;
1565 }
1566
1567 bool
Caroline Ticee7471982010-10-14 21:31:13 +00001568 VerifyCommandOptionValue (const std::string &option, int &real_value)
Caroline Tice23d6f272010-10-13 20:44:39 +00001569 {
1570 bool okay = true;
1571
Caroline Ticee7471982010-10-14 21:31:13 +00001572 bool success = false;
1573 bool tmp_value = Args::StringToBoolean (option.c_str(), false, &success);
1574
1575 if (success && tmp_value)
1576 real_value = 1;
1577 else if (success && !tmp_value)
1578 real_value = 0;
Caroline Tice23d6f272010-10-13 20:44:39 +00001579 else
1580 {
1581 // If the value isn't 'true' or 'false', it had better be 0 or 1.
Caroline Ticee7471982010-10-14 21:31:13 +00001582 real_value = Args::StringToUInt32 (option.c_str(), 3);
1583 if (real_value != 0 && real_value != 1)
Caroline Tice23d6f272010-10-13 20:44:39 +00001584 okay = false;
1585 }
1586
1587 return okay;
1588 }
1589
Caroline Ticee7471982010-10-14 21:31:13 +00001590 void
1591 PrintSignalHeader (Stream &str)
1592 {
1593 str.Printf ("NAME PASS STOP NOTIFY\n");
1594 str.Printf ("========== ===== ===== ======\n");
1595 }
1596
1597 void
1598 PrintSignal (Stream &str, int32_t signo, const char *sig_name, UnixSignals &signals)
1599 {
1600 bool stop;
1601 bool suppress;
1602 bool notify;
1603
1604 str.Printf ("%-10s ", sig_name);
1605 if (signals.GetSignalInfo (signo, suppress, stop, notify))
1606 {
1607 bool pass = !suppress;
1608 str.Printf ("%s %s %s",
1609 (pass ? "true " : "false"),
1610 (stop ? "true " : "false"),
1611 (notify ? "true " : "false"));
1612 }
1613 str.Printf ("\n");
1614 }
1615
1616 void
1617 PrintSignalInformation (Stream &str, Args &signal_args, int num_valid_signals, UnixSignals &signals)
1618 {
1619 PrintSignalHeader (str);
1620
1621 if (num_valid_signals > 0)
1622 {
1623 size_t num_args = signal_args.GetArgumentCount();
1624 for (size_t i = 0; i < num_args; ++i)
1625 {
1626 int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i));
1627 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
1628 PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals);
1629 }
1630 }
1631 else // Print info for ALL signals
1632 {
1633 int32_t signo = signals.GetFirstSignalNumber();
1634 while (signo != LLDB_INVALID_SIGNAL_NUMBER)
1635 {
1636 PrintSignal (str, signo, signals.GetSignalAsCString (signo), signals);
1637 signo = signals.GetNextSignalNumber (signo);
1638 }
1639 }
1640 }
1641
Jim Inghamda26bd22012-06-08 21:56:10 +00001642protected:
Caroline Tice23d6f272010-10-13 20:44:39 +00001643 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001644 DoExecute (Args &signal_args, CommandReturnObject &result)
Caroline Tice23d6f272010-10-13 20:44:39 +00001645 {
1646 TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
1647
1648 if (!target_sp)
1649 {
1650 result.AppendError ("No current target;"
1651 " cannot handle signals until you have a valid target and process.\n");
1652 result.SetStatus (eReturnStatusFailed);
1653 return false;
1654 }
1655
1656 ProcessSP process_sp = target_sp->GetProcessSP();
1657
1658 if (!process_sp)
1659 {
1660 result.AppendError ("No current process; cannot handle signals until you have a valid process.\n");
1661 result.SetStatus (eReturnStatusFailed);
1662 return false;
1663 }
1664
Caroline Tice23d6f272010-10-13 20:44:39 +00001665 int stop_action = -1; // -1 means leave the current setting alone
Caroline Ticee7471982010-10-14 21:31:13 +00001666 int pass_action = -1; // -1 means leave the current setting alone
Caroline Tice23d6f272010-10-13 20:44:39 +00001667 int notify_action = -1; // -1 means leave the current setting alone
1668
1669 if (! m_options.stop.empty()
Caroline Ticee7471982010-10-14 21:31:13 +00001670 && ! VerifyCommandOptionValue (m_options.stop, stop_action))
Caroline Tice23d6f272010-10-13 20:44:39 +00001671 {
1672 result.AppendError ("Invalid argument for command option --stop; must be true or false.\n");
1673 result.SetStatus (eReturnStatusFailed);
1674 return false;
1675 }
1676
1677 if (! m_options.notify.empty()
Caroline Ticee7471982010-10-14 21:31:13 +00001678 && ! VerifyCommandOptionValue (m_options.notify, notify_action))
Caroline Tice23d6f272010-10-13 20:44:39 +00001679 {
1680 result.AppendError ("Invalid argument for command option --notify; must be true or false.\n");
1681 result.SetStatus (eReturnStatusFailed);
1682 return false;
1683 }
1684
1685 if (! m_options.pass.empty()
Caroline Ticee7471982010-10-14 21:31:13 +00001686 && ! VerifyCommandOptionValue (m_options.pass, pass_action))
Caroline Tice23d6f272010-10-13 20:44:39 +00001687 {
1688 result.AppendError ("Invalid argument for command option --pass; must be true or false.\n");
1689 result.SetStatus (eReturnStatusFailed);
1690 return false;
1691 }
1692
1693 size_t num_args = signal_args.GetArgumentCount();
1694 UnixSignals &signals = process_sp->GetUnixSignals();
1695 int num_signals_set = 0;
1696
Caroline Ticee7471982010-10-14 21:31:13 +00001697 if (num_args > 0)
Caroline Tice23d6f272010-10-13 20:44:39 +00001698 {
Caroline Ticee7471982010-10-14 21:31:13 +00001699 for (size_t i = 0; i < num_args; ++i)
Caroline Tice23d6f272010-10-13 20:44:39 +00001700 {
Caroline Ticee7471982010-10-14 21:31:13 +00001701 int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i));
1702 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
Caroline Tice23d6f272010-10-13 20:44:39 +00001703 {
Caroline Ticee7471982010-10-14 21:31:13 +00001704 // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees
1705 // the value is either 0 or 1.
1706 if (stop_action != -1)
1707 signals.SetShouldStop (signo, (bool) stop_action);
1708 if (pass_action != -1)
1709 {
1710 bool suppress = ! ((bool) pass_action);
1711 signals.SetShouldSuppress (signo, suppress);
1712 }
1713 if (notify_action != -1)
1714 signals.SetShouldNotify (signo, (bool) notify_action);
1715 ++num_signals_set;
Caroline Tice23d6f272010-10-13 20:44:39 +00001716 }
Caroline Ticee7471982010-10-14 21:31:13 +00001717 else
1718 {
1719 result.AppendErrorWithFormat ("Invalid signal name '%s'\n", signal_args.GetArgumentAtIndex (i));
1720 }
Caroline Tice23d6f272010-10-13 20:44:39 +00001721 }
1722 }
Caroline Ticee7471982010-10-14 21:31:13 +00001723 else
1724 {
1725 // No signal specified, if any command options were specified, update ALL signals.
1726 if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1))
1727 {
1728 if (m_interpreter.Confirm ("Do you really want to update all the signals?", false))
1729 {
1730 int32_t signo = signals.GetFirstSignalNumber();
1731 while (signo != LLDB_INVALID_SIGNAL_NUMBER)
1732 {
1733 if (notify_action != -1)
1734 signals.SetShouldNotify (signo, (bool) notify_action);
1735 if (stop_action != -1)
1736 signals.SetShouldStop (signo, (bool) stop_action);
1737 if (pass_action != -1)
1738 {
1739 bool suppress = ! ((bool) pass_action);
1740 signals.SetShouldSuppress (signo, suppress);
1741 }
1742 signo = signals.GetNextSignalNumber (signo);
1743 }
1744 }
1745 }
1746 }
1747
1748 PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals);
Caroline Tice23d6f272010-10-13 20:44:39 +00001749
1750 if (num_signals_set > 0)
1751 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1752 else
1753 result.SetStatus (eReturnStatusFailed);
1754
1755 return result.Succeeded();
1756 }
1757
Caroline Tice23d6f272010-10-13 20:44:39 +00001758 CommandOptions m_options;
1759};
1760
Greg Claytonb3448432011-03-24 21:19:54 +00001761OptionDefinition
Caroline Tice23d6f272010-10-13 20:44:39 +00001762CommandObjectProcessHandle::CommandOptions::g_option_table[] =
1763{
1764{ 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." },
1765{ 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." },
1766{ LLDB_OPT_SET_1, false, "pass", 'p', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." },
1767{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1768};
1769
1770//-------------------------------------------------------------------------
Chris Lattner24943d22010-06-08 16:52:24 +00001771// CommandObjectMultiwordProcess
1772//-------------------------------------------------------------------------
1773
Greg Clayton63094e02010-06-23 01:19:29 +00001774CommandObjectMultiwordProcess::CommandObjectMultiwordProcess (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001775 CommandObjectMultiword (interpreter,
1776 "process",
1777 "A set of commands for operating on a process.",
1778 "process <subcommand> [<subcommand-options>]")
Chris Lattner24943d22010-06-08 16:52:24 +00001779{
Greg Claytona9eb8272011-07-02 21:07:54 +00001780 LoadSubCommand ("attach", CommandObjectSP (new CommandObjectProcessAttach (interpreter)));
1781 LoadSubCommand ("launch", CommandObjectSP (new CommandObjectProcessLaunch (interpreter)));
1782 LoadSubCommand ("continue", CommandObjectSP (new CommandObjectProcessContinue (interpreter)));
1783 LoadSubCommand ("connect", CommandObjectSP (new CommandObjectProcessConnect (interpreter)));
1784 LoadSubCommand ("detach", CommandObjectSP (new CommandObjectProcessDetach (interpreter)));
1785 LoadSubCommand ("load", CommandObjectSP (new CommandObjectProcessLoad (interpreter)));
1786 LoadSubCommand ("unload", CommandObjectSP (new CommandObjectProcessUnload (interpreter)));
1787 LoadSubCommand ("signal", CommandObjectSP (new CommandObjectProcessSignal (interpreter)));
1788 LoadSubCommand ("handle", CommandObjectSP (new CommandObjectProcessHandle (interpreter)));
1789 LoadSubCommand ("status", CommandObjectSP (new CommandObjectProcessStatus (interpreter)));
Greg Clayton238c0a12010-09-18 01:14:36 +00001790 LoadSubCommand ("interrupt", CommandObjectSP (new CommandObjectProcessInterrupt (interpreter)));
Greg Claytona9eb8272011-07-02 21:07:54 +00001791 LoadSubCommand ("kill", CommandObjectSP (new CommandObjectProcessKill (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +00001792}
1793
1794CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess ()
1795{
1796}
1797