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