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