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