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