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         if (command.GetArgumentCount())
533         {
534             result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
535             result.SetStatus (eReturnStatusFailed);
536             return false;
537         }
538 
539         m_interpreter.UpdateExecutionContext(nullptr);
540         StreamString stream;
541         const auto error = target->Attach(m_options.attach_info, &stream);
542         if (error.Success())
543         {
544             ProcessSP process_sp (target->GetProcessSP());
545             if (process_sp)
546             {
547                 if (stream.GetData())
548                     result.AppendMessage(stream.GetData());
549                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
550                 result.SetDidChangeProcessState (true);
551             }
552             else
553             {
554                 result.AppendError("no error returned from Target::Attach, and target has no process");
555                 result.SetStatus (eReturnStatusFailed);
556             }
557         }
558         else
559         {
560             result.AppendErrorWithFormat ("attach failed: %s\n", error.AsCString());
561             result.SetStatus (eReturnStatusFailed);
562         }
563 
564         if (!result.Succeeded())
565             return false;
566 
567         // Okay, we're done.  Last step is to warn if the executable module has changed:
568         char new_path[PATH_MAX];
569         ModuleSP new_exec_module_sp (target->GetExecutableModule());
570         if (!old_exec_module_sp)
571         {
572             // We might not have a module if we attached to a raw pid...
573             if (new_exec_module_sp)
574             {
575                 new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX);
576                 result.AppendMessageWithFormat("Executable module set to \"%s\".\n", new_path);
577             }
578         }
579         else if (old_exec_module_sp->GetFileSpec() != new_exec_module_sp->GetFileSpec())
580         {
581             char old_path[PATH_MAX];
582 
583             old_exec_module_sp->GetFileSpec().GetPath (old_path, PATH_MAX);
584             new_exec_module_sp->GetFileSpec().GetPath (new_path, PATH_MAX);
585 
586             result.AppendWarningWithFormat("Executable module changed from \"%s\" to \"%s\".\n",
587                                                 old_path, new_path);
588         }
589 
590         if (!old_arch_spec.IsValid())
591         {
592             result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().GetTriple().getTriple().c_str());
593         }
594         else if (!old_arch_spec.IsExactMatch(target->GetArchitecture()))
595         {
596             result.AppendWarningWithFormat("Architecture changed from %s to %s.\n",
597                                            old_arch_spec.GetTriple().getTriple().c_str(),
598                                            target->GetArchitecture().GetTriple().getTriple().c_str());
599         }
600 
601         // This supports the use-case scenario of immediately continuing the process once attached.
602         if (m_options.attach_info.GetContinueOnceAttached())
603             m_interpreter.HandleCommand("process continue", eLazyBoolNo, result);
604 
605         return result.Succeeded();
606     }
607 
608     CommandOptions m_options;
609 };
610 
611 
612 OptionDefinition
613 CommandObjectProcessAttach::CommandOptions::g_option_table[] =
614 {
615 { LLDB_OPT_SET_ALL, false, "continue",'c', OptionParser::eNoArgument,         NULL, NULL, 0, eArgTypeNone,         "Immediately continue the process once attached."},
616 { LLDB_OPT_SET_ALL, false, "plugin",  'P', OptionParser::eRequiredArgument,   NULL, NULL, 0, eArgTypePlugin,       "Name of the process plugin you want to use."},
617 { LLDB_OPT_SET_1,   false, "pid",     'p', OptionParser::eRequiredArgument,   NULL, NULL, 0, eArgTypePid,          "The process ID of an existing process to attach to."},
618 { LLDB_OPT_SET_2,   false, "name",    'n', OptionParser::eRequiredArgument,   NULL, NULL, 0, eArgTypeProcessName,  "The name of the process to attach to."},
619 { LLDB_OPT_SET_2,   false, "include-existing", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,         "Include existing processes when doing attach -w."},
620 { LLDB_OPT_SET_2,   false, "waitfor", 'w', OptionParser::eNoArgument,         NULL, NULL, 0, eArgTypeNone,         "Wait for the process with <process-name> to launch."},
621 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
622 };
623 
624 //-------------------------------------------------------------------------
625 // CommandObjectProcessContinue
626 //-------------------------------------------------------------------------
627 #pragma mark CommandObjectProcessContinue
628 
629 class CommandObjectProcessContinue : public CommandObjectParsed
630 {
631 public:
632 
633     CommandObjectProcessContinue (CommandInterpreter &interpreter) :
634         CommandObjectParsed (interpreter,
635                              "process continue",
636                              "Continue execution of all threads in the current process.",
637                              "process continue",
638                              eFlagRequiresProcess       |
639                              eFlagTryTargetAPILock      |
640                              eFlagProcessMustBeLaunched |
641                              eFlagProcessMustBePaused   ),
642         m_options(interpreter)
643     {
644     }
645 
646 
647     ~CommandObjectProcessContinue ()
648     {
649     }
650 
651 protected:
652 
653     class CommandOptions : public Options
654     {
655     public:
656 
657         CommandOptions (CommandInterpreter &interpreter) :
658             Options(interpreter)
659         {
660             // Keep default values of all options in one place: OptionParsingStarting ()
661             OptionParsingStarting ();
662         }
663 
664         ~CommandOptions ()
665         {
666         }
667 
668         Error
669         SetOptionValue (uint32_t option_idx, const char *option_arg)
670         {
671             Error error;
672             const int short_option = m_getopt_table[option_idx].val;
673             bool success = false;
674             switch (short_option)
675             {
676                 case 'i':
677                     m_ignore = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
678                     if (!success)
679                         error.SetErrorStringWithFormat ("invalid value for ignore option: \"%s\", should be a number.", option_arg);
680                     break;
681 
682                 default:
683                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
684                     break;
685             }
686             return error;
687         }
688 
689         void
690         OptionParsingStarting ()
691         {
692             m_ignore = 0;
693         }
694 
695         const OptionDefinition*
696         GetDefinitions ()
697         {
698             return g_option_table;
699         }
700 
701         // Options table: Required for subclasses of Options.
702 
703         static OptionDefinition g_option_table[];
704 
705         uint32_t m_ignore;
706     };
707 
708     bool
709     DoExecute (Args& command, CommandReturnObject &result)
710     {
711         Process *process = m_exe_ctx.GetProcessPtr();
712         bool synchronous_execution = m_interpreter.GetSynchronous ();
713         StateType state = process->GetState();
714         if (state == eStateStopped)
715         {
716             if (command.GetArgumentCount() != 0)
717             {
718                 result.AppendErrorWithFormat ("The '%s' command does not take any arguments.\n", m_cmd_name.c_str());
719                 result.SetStatus (eReturnStatusFailed);
720                 return false;
721             }
722 
723             if (m_options.m_ignore > 0)
724             {
725                 ThreadSP sel_thread_sp(process->GetThreadList().GetSelectedThread());
726                 if (sel_thread_sp)
727                 {
728                     StopInfoSP stop_info_sp = sel_thread_sp->GetStopInfo();
729                     if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonBreakpoint)
730                     {
731                         lldb::break_id_t bp_site_id = (lldb::break_id_t)stop_info_sp->GetValue();
732                         BreakpointSiteSP bp_site_sp(process->GetBreakpointSiteList().FindByID(bp_site_id));
733                         if (bp_site_sp)
734                         {
735                             const size_t num_owners = bp_site_sp->GetNumberOfOwners();
736                             for (size_t i = 0; i < num_owners; i++)
737                             {
738                                 Breakpoint &bp_ref = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
739                                 if (!bp_ref.IsInternal())
740                                 {
741                                     bp_ref.SetIgnoreCount(m_options.m_ignore);
742                                 }
743                             }
744                         }
745                     }
746                 }
747             }
748 
749             {  // Scope for thread list mutex:
750                 Mutex::Locker locker (process->GetThreadList().GetMutex());
751                 const uint32_t num_threads = process->GetThreadList().GetSize();
752 
753                 // Set the actions that the threads should each take when resuming
754                 for (uint32_t idx=0; idx<num_threads; ++idx)
755                 {
756                     const bool override_suspend = false;
757                     process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState (eStateRunning, override_suspend);
758                 }
759             }
760 
761             StreamString stream;
762             Error error;
763             if (synchronous_execution)
764                 error = process->ResumeSynchronous (&stream);
765             else
766                 error = process->Resume ();
767 
768             if (error.Success())
769             {
770                 // There is a race condition where this thread will return up the call stack to the main command
771                 // handler and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has
772                 // a chance to call PushProcessIOHandler().
773                 process->SyncIOHandler(2000);
774 
775                 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
776                 if (synchronous_execution)
777                 {
778                     // If any state changed events had anything to say, add that to the result
779                     if (stream.GetData())
780                         result.AppendMessage(stream.GetData());
781 
782                     result.SetDidChangeProcessState (true);
783                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
784                 }
785                 else
786                 {
787                     result.SetStatus (eReturnStatusSuccessContinuingNoResult);
788                 }
789             }
790             else
791             {
792                 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
793                 result.SetStatus (eReturnStatusFailed);
794             }
795         }
796         else
797         {
798             result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
799                                          StateAsCString(state));
800             result.SetStatus (eReturnStatusFailed);
801         }
802         return result.Succeeded();
803     }
804 
805     Options *
806     GetOptions ()
807     {
808         return &m_options;
809     }
810 
811     CommandOptions m_options;
812 
813 };
814 
815 OptionDefinition
816 CommandObjectProcessContinue::CommandOptions::g_option_table[] =
817 {
818 { LLDB_OPT_SET_ALL, false, "ignore-count",'i', OptionParser::eRequiredArgument,         NULL, NULL, 0, eArgTypeUnsignedInteger,
819                            "Ignore <N> crossings of the breakpoint (if it exists) for the currently selected thread."},
820 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
821 };
822 
823 //-------------------------------------------------------------------------
824 // CommandObjectProcessDetach
825 //-------------------------------------------------------------------------
826 #pragma mark CommandObjectProcessDetach
827 
828 class CommandObjectProcessDetach : public CommandObjectParsed
829 {
830 public:
831     class CommandOptions : public Options
832     {
833     public:
834 
835         CommandOptions (CommandInterpreter &interpreter) :
836             Options (interpreter)
837         {
838             OptionParsingStarting ();
839         }
840 
841         ~CommandOptions ()
842         {
843         }
844 
845         Error
846         SetOptionValue (uint32_t option_idx, const char *option_arg)
847         {
848             Error error;
849             const int short_option = m_getopt_table[option_idx].val;
850 
851             switch (short_option)
852             {
853                 case 's':
854                     bool tmp_result;
855                     bool success;
856                     tmp_result = Args::StringToBoolean(option_arg, false, &success);
857                     if (!success)
858                         error.SetErrorStringWithFormat("invalid boolean option: \"%s\"", option_arg);
859                     else
860                     {
861                         if (tmp_result)
862                             m_keep_stopped = eLazyBoolYes;
863                         else
864                             m_keep_stopped = eLazyBoolNo;
865                     }
866                     break;
867                 default:
868                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
869                     break;
870             }
871             return error;
872         }
873 
874         void
875         OptionParsingStarting ()
876         {
877             m_keep_stopped = eLazyBoolCalculate;
878         }
879 
880         const OptionDefinition*
881         GetDefinitions ()
882         {
883             return g_option_table;
884         }
885 
886         // Options table: Required for subclasses of Options.
887 
888         static OptionDefinition g_option_table[];
889 
890         // Instance variables to hold the values for command options.
891         LazyBool m_keep_stopped;
892     };
893 
894     CommandObjectProcessDetach (CommandInterpreter &interpreter) :
895         CommandObjectParsed (interpreter,
896                              "process detach",
897                              "Detach from the current process being debugged.",
898                              "process detach",
899                              eFlagRequiresProcess      |
900                              eFlagTryTargetAPILock     |
901                              eFlagProcessMustBeLaunched),
902         m_options(interpreter)
903     {
904     }
905 
906     ~CommandObjectProcessDetach ()
907     {
908     }
909 
910     Options *
911     GetOptions ()
912     {
913         return &m_options;
914     }
915 
916 
917 protected:
918     bool
919     DoExecute (Args& command, CommandReturnObject &result)
920     {
921         Process *process = m_exe_ctx.GetProcessPtr();
922         // FIXME: This will be a Command Option:
923         bool keep_stopped;
924         if (m_options.m_keep_stopped == eLazyBoolCalculate)
925         {
926             // Check the process default:
927             if (process->GetDetachKeepsStopped())
928                 keep_stopped = true;
929             else
930                 keep_stopped = false;
931         }
932         else if (m_options.m_keep_stopped == eLazyBoolYes)
933             keep_stopped = true;
934         else
935             keep_stopped = false;
936 
937         Error error (process->Detach(keep_stopped));
938         if (error.Success())
939         {
940             result.SetStatus (eReturnStatusSuccessFinishResult);
941         }
942         else
943         {
944             result.AppendErrorWithFormat ("Detach failed: %s\n", error.AsCString());
945             result.SetStatus (eReturnStatusFailed);
946             return false;
947         }
948         return result.Succeeded();
949     }
950 
951     CommandOptions m_options;
952 };
953 
954 OptionDefinition
955 CommandObjectProcessDetach::CommandOptions::g_option_table[] =
956 {
957 { 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)." },
958 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
959 };
960 
961 //-------------------------------------------------------------------------
962 // CommandObjectProcessConnect
963 //-------------------------------------------------------------------------
964 #pragma mark CommandObjectProcessConnect
965 
966 class CommandObjectProcessConnect : public CommandObjectParsed
967 {
968 public:
969 
970     class CommandOptions : public Options
971     {
972     public:
973 
974         CommandOptions (CommandInterpreter &interpreter) :
975             Options(interpreter)
976         {
977             // Keep default values of all options in one place: OptionParsingStarting ()
978             OptionParsingStarting ();
979         }
980 
981         ~CommandOptions ()
982         {
983         }
984 
985         Error
986         SetOptionValue (uint32_t option_idx, const char *option_arg)
987         {
988             Error error;
989             const int short_option = m_getopt_table[option_idx].val;
990 
991             switch (short_option)
992             {
993             case 'p':
994                 plugin_name.assign (option_arg);
995                 break;
996 
997             default:
998                 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
999                 break;
1000             }
1001             return error;
1002         }
1003 
1004         void
1005         OptionParsingStarting ()
1006         {
1007             plugin_name.clear();
1008         }
1009 
1010         const OptionDefinition*
1011         GetDefinitions ()
1012         {
1013             return g_option_table;
1014         }
1015 
1016         // Options table: Required for subclasses of Options.
1017 
1018         static OptionDefinition g_option_table[];
1019 
1020         // Instance variables to hold the values for command options.
1021 
1022         std::string plugin_name;
1023     };
1024 
1025     CommandObjectProcessConnect (CommandInterpreter &interpreter) :
1026         CommandObjectParsed (interpreter,
1027                              "process connect",
1028                              "Connect to a remote debug service.",
1029                              "process connect <remote-url>",
1030                              0),
1031         m_options (interpreter)
1032     {
1033     }
1034 
1035     ~CommandObjectProcessConnect ()
1036     {
1037     }
1038 
1039 
1040     Options *
1041     GetOptions ()
1042     {
1043         return &m_options;
1044     }
1045 
1046 protected:
1047     bool
1048     DoExecute (Args& command,
1049              CommandReturnObject &result)
1050     {
1051 
1052         TargetSP target_sp (m_interpreter.GetDebugger().GetSelectedTarget());
1053         Error error;
1054         Process *process = m_exe_ctx.GetProcessPtr();
1055         if (process)
1056         {
1057             if (process->IsAlive())
1058             {
1059                 result.AppendErrorWithFormat ("Process %" PRIu64 " is currently being debugged, kill the process before connecting.\n",
1060                                               process->GetID());
1061                 result.SetStatus (eReturnStatusFailed);
1062                 return false;
1063             }
1064         }
1065 
1066         if (!target_sp)
1067         {
1068             // If there isn't a current target create one.
1069 
1070             error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(),
1071                                                                               NULL,
1072                                                                               NULL,
1073                                                                               false,
1074                                                                               NULL, // No platform options
1075                                                                               target_sp);
1076             if (!target_sp || error.Fail())
1077             {
1078                 result.AppendError(error.AsCString("Error creating target"));
1079                 result.SetStatus (eReturnStatusFailed);
1080                 return false;
1081             }
1082             m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target_sp.get());
1083         }
1084 
1085         if (command.GetArgumentCount() == 1)
1086         {
1087             const char *plugin_name = NULL;
1088             if (!m_options.plugin_name.empty())
1089                 plugin_name = m_options.plugin_name.c_str();
1090 
1091             const char *remote_url = command.GetArgumentAtIndex(0);
1092             process = target_sp->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name, NULL).get();
1093 
1094             if (process)
1095             {
1096                 error = process->ConnectRemote (process->GetTarget().GetDebugger().GetOutputFile().get(), remote_url);
1097 
1098                 if (error.Fail())
1099                 {
1100                     result.AppendError(error.AsCString("Remote connect failed"));
1101                     result.SetStatus (eReturnStatusFailed);
1102                     target_sp->DeleteCurrentProcess();
1103                     return false;
1104                 }
1105             }
1106             else
1107             {
1108                 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",
1109                                               remote_url);
1110                 result.SetStatus (eReturnStatusFailed);
1111             }
1112         }
1113         else
1114         {
1115             result.AppendErrorWithFormat ("'%s' takes exactly one argument:\nUsage: %s\n",
1116                                           m_cmd_name.c_str(),
1117                                           m_cmd_syntax.c_str());
1118             result.SetStatus (eReturnStatusFailed);
1119         }
1120         return result.Succeeded();
1121     }
1122 
1123     CommandOptions m_options;
1124 };
1125 
1126 OptionDefinition
1127 CommandObjectProcessConnect::CommandOptions::g_option_table[] =
1128 {
1129     { LLDB_OPT_SET_ALL, false, "plugin", 'p', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."},
1130     { 0,                false, NULL,      0 , 0,                 NULL, NULL, 0, eArgTypeNone,   NULL }
1131 };
1132 
1133 //-------------------------------------------------------------------------
1134 // CommandObjectProcessPlugin
1135 //-------------------------------------------------------------------------
1136 #pragma mark CommandObjectProcessPlugin
1137 
1138 class CommandObjectProcessPlugin : public CommandObjectProxy
1139 {
1140 public:
1141 
1142     CommandObjectProcessPlugin (CommandInterpreter &interpreter) :
1143         CommandObjectProxy (interpreter,
1144                             "process plugin",
1145                             "Send a custom command to the current process plug-in.",
1146                             "process plugin <args>",
1147                             0)
1148     {
1149     }
1150 
1151     ~CommandObjectProcessPlugin ()
1152     {
1153     }
1154 
1155     virtual CommandObject *
1156     GetProxyCommandObject()
1157     {
1158         Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
1159         if (process)
1160             return process->GetPluginCommandObject();
1161         return NULL;
1162     }
1163 };
1164 
1165 
1166 //-------------------------------------------------------------------------
1167 // CommandObjectProcessLoad
1168 //-------------------------------------------------------------------------
1169 #pragma mark CommandObjectProcessLoad
1170 
1171 class CommandObjectProcessLoad : public CommandObjectParsed
1172 {
1173 public:
1174 
1175     CommandObjectProcessLoad (CommandInterpreter &interpreter) :
1176         CommandObjectParsed (interpreter,
1177                              "process load",
1178                              "Load a shared library into the current process.",
1179                              "process load <filename> [<filename> ...]",
1180                              eFlagRequiresProcess       |
1181                              eFlagTryTargetAPILock      |
1182                              eFlagProcessMustBeLaunched |
1183                              eFlagProcessMustBePaused   )
1184     {
1185     }
1186 
1187     ~CommandObjectProcessLoad ()
1188     {
1189     }
1190 
1191 protected:
1192     bool
1193     DoExecute (Args& command,
1194              CommandReturnObject &result)
1195     {
1196         Process *process = m_exe_ctx.GetProcessPtr();
1197 
1198         const size_t argc = command.GetArgumentCount();
1199 
1200         for (uint32_t i=0; i<argc; ++i)
1201         {
1202             Error error;
1203             const char *image_path = command.GetArgumentAtIndex(i);
1204             FileSpec image_spec (image_path, false);
1205             process->GetTarget().GetPlatform()->ResolveRemotePath(image_spec, image_spec);
1206             uint32_t image_token = process->LoadImage(image_spec, error);
1207             if (image_token != LLDB_INVALID_IMAGE_TOKEN)
1208             {
1209                 result.AppendMessageWithFormat ("Loading \"%s\"...ok\nImage %u loaded.\n", image_path, image_token);
1210                 result.SetStatus (eReturnStatusSuccessFinishResult);
1211             }
1212             else
1213             {
1214                 result.AppendErrorWithFormat ("failed to load '%s': %s", image_path, error.AsCString());
1215                 result.SetStatus (eReturnStatusFailed);
1216             }
1217         }
1218         return result.Succeeded();
1219     }
1220 };
1221 
1222 
1223 //-------------------------------------------------------------------------
1224 // CommandObjectProcessUnload
1225 //-------------------------------------------------------------------------
1226 #pragma mark CommandObjectProcessUnload
1227 
1228 class CommandObjectProcessUnload : public CommandObjectParsed
1229 {
1230 public:
1231 
1232     CommandObjectProcessUnload (CommandInterpreter &interpreter) :
1233         CommandObjectParsed (interpreter,
1234                              "process unload",
1235                              "Unload a shared library from the current process using the index returned by a previous call to \"process load\".",
1236                              "process unload <index>",
1237                              eFlagRequiresProcess       |
1238                              eFlagTryTargetAPILock      |
1239                              eFlagProcessMustBeLaunched |
1240                              eFlagProcessMustBePaused   )
1241     {
1242     }
1243 
1244     ~CommandObjectProcessUnload ()
1245     {
1246     }
1247 
1248 protected:
1249     bool
1250     DoExecute (Args& command,
1251              CommandReturnObject &result)
1252     {
1253         Process *process = m_exe_ctx.GetProcessPtr();
1254 
1255         const size_t argc = command.GetArgumentCount();
1256 
1257         for (uint32_t i=0; i<argc; ++i)
1258         {
1259             const char *image_token_cstr = command.GetArgumentAtIndex(i);
1260             uint32_t image_token = StringConvert::ToUInt32(image_token_cstr, LLDB_INVALID_IMAGE_TOKEN, 0);
1261             if (image_token == LLDB_INVALID_IMAGE_TOKEN)
1262             {
1263                 result.AppendErrorWithFormat ("invalid image index argument '%s'", image_token_cstr);
1264                 result.SetStatus (eReturnStatusFailed);
1265                 break;
1266             }
1267             else
1268             {
1269                 Error error (process->UnloadImage(image_token));
1270                 if (error.Success())
1271                 {
1272                     result.AppendMessageWithFormat ("Unloading shared library with index %u...ok\n", image_token);
1273                     result.SetStatus (eReturnStatusSuccessFinishResult);
1274                 }
1275                 else
1276                 {
1277                     result.AppendErrorWithFormat ("failed to unload image: %s", error.AsCString());
1278                     result.SetStatus (eReturnStatusFailed);
1279                     break;
1280                 }
1281             }
1282         }
1283         return result.Succeeded();
1284     }
1285 };
1286 
1287 //-------------------------------------------------------------------------
1288 // CommandObjectProcessSignal
1289 //-------------------------------------------------------------------------
1290 #pragma mark CommandObjectProcessSignal
1291 
1292 class CommandObjectProcessSignal : public CommandObjectParsed
1293 {
1294 public:
1295 
1296     CommandObjectProcessSignal (CommandInterpreter &interpreter) :
1297         CommandObjectParsed (interpreter,
1298                              "process signal",
1299                              "Send a UNIX signal to the current process being debugged.",
1300                              NULL,
1301                              eFlagRequiresProcess | eFlagTryTargetAPILock)
1302     {
1303         CommandArgumentEntry arg;
1304         CommandArgumentData signal_arg;
1305 
1306         // Define the first (and only) variant of this arg.
1307         signal_arg.arg_type = eArgTypeUnixSignal;
1308         signal_arg.arg_repetition = eArgRepeatPlain;
1309 
1310         // There is only one variant this argument could be; put it into the argument entry.
1311         arg.push_back (signal_arg);
1312 
1313         // Push the data for the first argument into the m_arguments vector.
1314         m_arguments.push_back (arg);
1315     }
1316 
1317     ~CommandObjectProcessSignal ()
1318     {
1319     }
1320 
1321 protected:
1322     bool
1323     DoExecute (Args& command,
1324              CommandReturnObject &result)
1325     {
1326         Process *process = m_exe_ctx.GetProcessPtr();
1327 
1328         if (command.GetArgumentCount() == 1)
1329         {
1330             int signo = LLDB_INVALID_SIGNAL_NUMBER;
1331 
1332             const char *signal_name = command.GetArgumentAtIndex(0);
1333             if (::isxdigit (signal_name[0]))
1334                 signo = StringConvert::ToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0);
1335             else
1336                 signo = process->GetUnixSignals().GetSignalNumberFromName (signal_name);
1337 
1338             if (signo == LLDB_INVALID_SIGNAL_NUMBER)
1339             {
1340                 result.AppendErrorWithFormat ("Invalid signal argument '%s'.\n", command.GetArgumentAtIndex(0));
1341                 result.SetStatus (eReturnStatusFailed);
1342             }
1343             else
1344             {
1345                 Error error (process->Signal (signo));
1346                 if (error.Success())
1347                 {
1348                     result.SetStatus (eReturnStatusSuccessFinishResult);
1349                 }
1350                 else
1351                 {
1352                     result.AppendErrorWithFormat ("Failed to send signal %i: %s\n", signo, error.AsCString());
1353                     result.SetStatus (eReturnStatusFailed);
1354                 }
1355             }
1356         }
1357         else
1358         {
1359             result.AppendErrorWithFormat("'%s' takes exactly one signal number argument:\nUsage: %s\n", m_cmd_name.c_str(),
1360                                         m_cmd_syntax.c_str());
1361             result.SetStatus (eReturnStatusFailed);
1362         }
1363         return result.Succeeded();
1364     }
1365 };
1366 
1367 
1368 //-------------------------------------------------------------------------
1369 // CommandObjectProcessInterrupt
1370 //-------------------------------------------------------------------------
1371 #pragma mark CommandObjectProcessInterrupt
1372 
1373 class CommandObjectProcessInterrupt : public CommandObjectParsed
1374 {
1375 public:
1376 
1377 
1378     CommandObjectProcessInterrupt (CommandInterpreter &interpreter) :
1379         CommandObjectParsed (interpreter,
1380                              "process interrupt",
1381                              "Interrupt the current process being debugged.",
1382                              "process interrupt",
1383                              eFlagRequiresProcess      |
1384                              eFlagTryTargetAPILock     |
1385                              eFlagProcessMustBeLaunched)
1386     {
1387     }
1388 
1389     ~CommandObjectProcessInterrupt ()
1390     {
1391     }
1392 
1393 protected:
1394     bool
1395     DoExecute (Args& command,
1396                CommandReturnObject &result)
1397     {
1398         Process *process = m_exe_ctx.GetProcessPtr();
1399         if (process == NULL)
1400         {
1401             result.AppendError ("no process to halt");
1402             result.SetStatus (eReturnStatusFailed);
1403             return false;
1404         }
1405 
1406         if (command.GetArgumentCount() == 0)
1407         {
1408             bool clear_thread_plans = true;
1409             Error error(process->Halt (clear_thread_plans));
1410             if (error.Success())
1411             {
1412                 result.SetStatus (eReturnStatusSuccessFinishResult);
1413             }
1414             else
1415             {
1416                 result.AppendErrorWithFormat ("Failed to halt process: %s\n", error.AsCString());
1417                 result.SetStatus (eReturnStatusFailed);
1418             }
1419         }
1420         else
1421         {
1422             result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n",
1423                                         m_cmd_name.c_str(),
1424                                         m_cmd_syntax.c_str());
1425             result.SetStatus (eReturnStatusFailed);
1426         }
1427         return result.Succeeded();
1428     }
1429 };
1430 
1431 //-------------------------------------------------------------------------
1432 // CommandObjectProcessKill
1433 //-------------------------------------------------------------------------
1434 #pragma mark CommandObjectProcessKill
1435 
1436 class CommandObjectProcessKill : public CommandObjectParsed
1437 {
1438 public:
1439 
1440     CommandObjectProcessKill (CommandInterpreter &interpreter) :
1441         CommandObjectParsed (interpreter,
1442                              "process kill",
1443                              "Terminate the current process being debugged.",
1444                              "process kill",
1445                              eFlagRequiresProcess      |
1446                              eFlagTryTargetAPILock     |
1447                              eFlagProcessMustBeLaunched)
1448     {
1449     }
1450 
1451     ~CommandObjectProcessKill ()
1452     {
1453     }
1454 
1455 protected:
1456     bool
1457     DoExecute (Args& command,
1458              CommandReturnObject &result)
1459     {
1460         Process *process = m_exe_ctx.GetProcessPtr();
1461         if (process == NULL)
1462         {
1463             result.AppendError ("no process to kill");
1464             result.SetStatus (eReturnStatusFailed);
1465             return false;
1466         }
1467 
1468         if (command.GetArgumentCount() == 0)
1469         {
1470             Error error (process->Destroy());
1471             if (error.Success())
1472             {
1473                 result.SetStatus (eReturnStatusSuccessFinishResult);
1474             }
1475             else
1476             {
1477                 result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString());
1478                 result.SetStatus (eReturnStatusFailed);
1479             }
1480         }
1481         else
1482         {
1483             result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n",
1484                                         m_cmd_name.c_str(),
1485                                         m_cmd_syntax.c_str());
1486             result.SetStatus (eReturnStatusFailed);
1487         }
1488         return result.Succeeded();
1489     }
1490 };
1491 
1492 //-------------------------------------------------------------------------
1493 // CommandObjectProcessSaveCore
1494 //-------------------------------------------------------------------------
1495 #pragma mark CommandObjectProcessSaveCore
1496 
1497 class CommandObjectProcessSaveCore : public CommandObjectParsed
1498 {
1499 public:
1500 
1501     CommandObjectProcessSaveCore (CommandInterpreter &interpreter) :
1502     CommandObjectParsed (interpreter,
1503                          "process save-core",
1504                          "Save the current process as a core file using an appropriate file type.",
1505                          "process save-core FILE",
1506                          eFlagRequiresProcess      |
1507                          eFlagTryTargetAPILock     |
1508                          eFlagProcessMustBeLaunched)
1509     {
1510     }
1511 
1512     ~CommandObjectProcessSaveCore ()
1513     {
1514     }
1515 
1516 protected:
1517     bool
1518     DoExecute (Args& command,
1519                CommandReturnObject &result)
1520     {
1521         ProcessSP process_sp = m_exe_ctx.GetProcessSP();
1522         if (process_sp)
1523         {
1524             if (command.GetArgumentCount() == 1)
1525             {
1526                 FileSpec output_file(command.GetArgumentAtIndex(0), false);
1527                 Error error = PluginManager::SaveCore(process_sp, output_file);
1528                 if (error.Success())
1529                 {
1530                     result.SetStatus (eReturnStatusSuccessFinishResult);
1531                 }
1532                 else
1533                 {
1534                     result.AppendErrorWithFormat ("Failed to save core file for process: %s\n", error.AsCString());
1535                     result.SetStatus (eReturnStatusFailed);
1536                 }
1537             }
1538             else
1539             {
1540                 result.AppendErrorWithFormat ("'%s' takes one arguments:\nUsage: %s\n",
1541                                               m_cmd_name.c_str(),
1542                                               m_cmd_syntax.c_str());
1543                 result.SetStatus (eReturnStatusFailed);
1544             }
1545         }
1546         else
1547         {
1548             result.AppendError ("invalid process");
1549             result.SetStatus (eReturnStatusFailed);
1550             return false;
1551         }
1552 
1553         return result.Succeeded();
1554     }
1555 };
1556 
1557 //-------------------------------------------------------------------------
1558 // CommandObjectProcessStatus
1559 //-------------------------------------------------------------------------
1560 #pragma mark CommandObjectProcessStatus
1561 
1562 class CommandObjectProcessStatus : public CommandObjectParsed
1563 {
1564 public:
1565     CommandObjectProcessStatus (CommandInterpreter &interpreter) :
1566         CommandObjectParsed (interpreter,
1567                              "process status",
1568                              "Show the current status and location of executing process.",
1569                              "process status",
1570                              eFlagRequiresProcess | eFlagTryTargetAPILock)
1571     {
1572     }
1573 
1574     ~CommandObjectProcessStatus()
1575     {
1576     }
1577 
1578 
1579     bool
1580     DoExecute (Args& command, CommandReturnObject &result)
1581     {
1582         Stream &strm = result.GetOutputStream();
1583         result.SetStatus (eReturnStatusSuccessFinishNoResult);
1584         // No need to check "process" for validity as eFlagRequiresProcess ensures it is valid
1585         Process *process = m_exe_ctx.GetProcessPtr();
1586         const bool only_threads_with_stop_reason = true;
1587         const uint32_t start_frame = 0;
1588         const uint32_t num_frames = 1;
1589         const uint32_t num_frames_with_source = 1;
1590         process->GetStatus(strm);
1591         process->GetThreadStatus (strm,
1592                                   only_threads_with_stop_reason,
1593                                   start_frame,
1594                                   num_frames,
1595                                   num_frames_with_source);
1596         return result.Succeeded();
1597     }
1598 };
1599 
1600 //-------------------------------------------------------------------------
1601 // CommandObjectProcessHandle
1602 //-------------------------------------------------------------------------
1603 #pragma mark CommandObjectProcessHandle
1604 
1605 class CommandObjectProcessHandle : public CommandObjectParsed
1606 {
1607 public:
1608 
1609     class CommandOptions : public Options
1610     {
1611     public:
1612 
1613         CommandOptions (CommandInterpreter &interpreter) :
1614             Options (interpreter)
1615         {
1616             OptionParsingStarting ();
1617         }
1618 
1619         ~CommandOptions ()
1620         {
1621         }
1622 
1623         Error
1624         SetOptionValue (uint32_t option_idx, const char *option_arg)
1625         {
1626             Error error;
1627             const int short_option = m_getopt_table[option_idx].val;
1628 
1629             switch (short_option)
1630             {
1631                 case 's':
1632                     stop = option_arg;
1633                     break;
1634                 case 'n':
1635                     notify = option_arg;
1636                     break;
1637                 case 'p':
1638                     pass = option_arg;
1639                     break;
1640                 default:
1641                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
1642                     break;
1643             }
1644             return error;
1645         }
1646 
1647         void
1648         OptionParsingStarting ()
1649         {
1650             stop.clear();
1651             notify.clear();
1652             pass.clear();
1653         }
1654 
1655         const OptionDefinition*
1656         GetDefinitions ()
1657         {
1658             return g_option_table;
1659         }
1660 
1661         // Options table: Required for subclasses of Options.
1662 
1663         static OptionDefinition g_option_table[];
1664 
1665         // Instance variables to hold the values for command options.
1666 
1667         std::string stop;
1668         std::string notify;
1669         std::string pass;
1670     };
1671 
1672 
1673     CommandObjectProcessHandle (CommandInterpreter &interpreter) :
1674         CommandObjectParsed (interpreter,
1675                              "process handle",
1676                              "Show or update what the process and debugger should do with various signals received from the OS.",
1677                              NULL),
1678         m_options (interpreter)
1679     {
1680         SetHelpLong ("If no signals are specified, update them all.  If no update option is specified, list the current values.\n");
1681         CommandArgumentEntry arg;
1682         CommandArgumentData signal_arg;
1683 
1684         signal_arg.arg_type = eArgTypeUnixSignal;
1685         signal_arg.arg_repetition = eArgRepeatStar;
1686 
1687         arg.push_back (signal_arg);
1688 
1689         m_arguments.push_back (arg);
1690     }
1691 
1692     ~CommandObjectProcessHandle ()
1693     {
1694     }
1695 
1696     Options *
1697     GetOptions ()
1698     {
1699         return &m_options;
1700     }
1701 
1702     bool
1703     VerifyCommandOptionValue (const std::string &option, int &real_value)
1704     {
1705         bool okay = true;
1706 
1707         bool success = false;
1708         bool tmp_value = Args::StringToBoolean (option.c_str(), false, &success);
1709 
1710         if (success && tmp_value)
1711             real_value = 1;
1712         else if (success && !tmp_value)
1713             real_value = 0;
1714         else
1715         {
1716             // If the value isn't 'true' or 'false', it had better be 0 or 1.
1717             real_value = StringConvert::ToUInt32 (option.c_str(), 3);
1718             if (real_value != 0 && real_value != 1)
1719                 okay = false;
1720         }
1721 
1722         return okay;
1723     }
1724 
1725     void
1726     PrintSignalHeader (Stream &str)
1727     {
1728         str.Printf ("NAME        PASS   STOP   NOTIFY\n");
1729         str.Printf ("==========  =====  =====  ======\n");
1730     }
1731 
1732     void
1733     PrintSignal (Stream &str, int32_t signo, const char *sig_name, UnixSignals &signals)
1734     {
1735         bool stop;
1736         bool suppress;
1737         bool notify;
1738 
1739         str.Printf ("%-10s  ", sig_name);
1740         if (signals.GetSignalInfo (signo, suppress, stop, notify))
1741         {
1742             bool pass = !suppress;
1743             str.Printf ("%s  %s  %s",
1744                         (pass ? "true " : "false"),
1745                         (stop ? "true " : "false"),
1746                         (notify ? "true " : "false"));
1747         }
1748         str.Printf ("\n");
1749     }
1750 
1751     void
1752     PrintSignalInformation (Stream &str, Args &signal_args, int num_valid_signals, UnixSignals &signals)
1753     {
1754         PrintSignalHeader (str);
1755 
1756         if (num_valid_signals > 0)
1757         {
1758             size_t num_args = signal_args.GetArgumentCount();
1759             for (size_t i = 0; i < num_args; ++i)
1760             {
1761                 int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i));
1762                 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
1763                     PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals);
1764             }
1765         }
1766         else // Print info for ALL signals
1767         {
1768             int32_t signo = signals.GetFirstSignalNumber();
1769             while (signo != LLDB_INVALID_SIGNAL_NUMBER)
1770             {
1771                 PrintSignal (str, signo, signals.GetSignalAsCString (signo), signals);
1772                 signo = signals.GetNextSignalNumber (signo);
1773             }
1774         }
1775     }
1776 
1777 protected:
1778     bool
1779     DoExecute (Args &signal_args, CommandReturnObject &result)
1780     {
1781         TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
1782 
1783         if (!target_sp)
1784         {
1785             result.AppendError ("No current target;"
1786                                 " cannot handle signals until you have a valid target and process.\n");
1787             result.SetStatus (eReturnStatusFailed);
1788             return false;
1789         }
1790 
1791         ProcessSP process_sp = target_sp->GetProcessSP();
1792 
1793         if (!process_sp)
1794         {
1795             result.AppendError ("No current process; cannot handle signals until you have a valid process.\n");
1796             result.SetStatus (eReturnStatusFailed);
1797             return false;
1798         }
1799 
1800         int stop_action = -1;   // -1 means leave the current setting alone
1801         int pass_action = -1;   // -1 means leave the current setting alone
1802         int notify_action = -1; // -1 means leave the current setting alone
1803 
1804         if (! m_options.stop.empty()
1805             && ! VerifyCommandOptionValue (m_options.stop, stop_action))
1806         {
1807             result.AppendError ("Invalid argument for command option --stop; must be true or false.\n");
1808             result.SetStatus (eReturnStatusFailed);
1809             return false;
1810         }
1811 
1812         if (! m_options.notify.empty()
1813             && ! VerifyCommandOptionValue (m_options.notify, notify_action))
1814         {
1815             result.AppendError ("Invalid argument for command option --notify; must be true or false.\n");
1816             result.SetStatus (eReturnStatusFailed);
1817             return false;
1818         }
1819 
1820         if (! m_options.pass.empty()
1821             && ! VerifyCommandOptionValue (m_options.pass, pass_action))
1822         {
1823             result.AppendError ("Invalid argument for command option --pass; must be true or false.\n");
1824             result.SetStatus (eReturnStatusFailed);
1825             return false;
1826         }
1827 
1828         size_t num_args = signal_args.GetArgumentCount();
1829         UnixSignals &signals = process_sp->GetUnixSignals();
1830         int num_signals_set = 0;
1831 
1832         if (num_args > 0)
1833         {
1834             for (size_t i = 0; i < num_args; ++i)
1835             {
1836                 int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i));
1837                 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
1838                 {
1839                     // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees
1840                     // the value is either 0 or 1.
1841                     if (stop_action != -1)
1842                         signals.SetShouldStop (signo, (bool) stop_action);
1843                     if (pass_action != -1)
1844                     {
1845                         bool suppress = ! ((bool) pass_action);
1846                         signals.SetShouldSuppress (signo, suppress);
1847                     }
1848                     if (notify_action != -1)
1849                         signals.SetShouldNotify (signo, (bool) notify_action);
1850                     ++num_signals_set;
1851                 }
1852                 else
1853                 {
1854                     result.AppendErrorWithFormat ("Invalid signal name '%s'\n", signal_args.GetArgumentAtIndex (i));
1855                 }
1856             }
1857         }
1858         else
1859         {
1860             // No signal specified, if any command options were specified, update ALL signals.
1861             if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1))
1862             {
1863                 if (m_interpreter.Confirm ("Do you really want to update all the signals?", false))
1864                 {
1865                     int32_t signo = signals.GetFirstSignalNumber();
1866                     while (signo != LLDB_INVALID_SIGNAL_NUMBER)
1867                     {
1868                         if (notify_action != -1)
1869                             signals.SetShouldNotify (signo, (bool) notify_action);
1870                         if (stop_action != -1)
1871                             signals.SetShouldStop (signo, (bool) stop_action);
1872                         if (pass_action != -1)
1873                         {
1874                             bool suppress = ! ((bool) pass_action);
1875                             signals.SetShouldSuppress (signo, suppress);
1876                         }
1877                         signo = signals.GetNextSignalNumber (signo);
1878                     }
1879                 }
1880             }
1881         }
1882 
1883         PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals);
1884 
1885         if (num_signals_set > 0)
1886             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1887         else
1888             result.SetStatus (eReturnStatusFailed);
1889 
1890         return result.Succeeded();
1891     }
1892 
1893     CommandOptions m_options;
1894 };
1895 
1896 OptionDefinition
1897 CommandObjectProcessHandle::CommandOptions::g_option_table[] =
1898 {
1899 { 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." },
1900 { 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." },
1901 { LLDB_OPT_SET_1, false, "pass",  'p', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." },
1902 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
1903 };
1904 
1905 //-------------------------------------------------------------------------
1906 // CommandObjectMultiwordProcess
1907 //-------------------------------------------------------------------------
1908 
1909 CommandObjectMultiwordProcess::CommandObjectMultiwordProcess (CommandInterpreter &interpreter) :
1910     CommandObjectMultiword (interpreter,
1911                             "process",
1912                             "A set of commands for operating on a process.",
1913                             "process <subcommand> [<subcommand-options>]")
1914 {
1915     LoadSubCommand ("attach",      CommandObjectSP (new CommandObjectProcessAttach    (interpreter)));
1916     LoadSubCommand ("launch",      CommandObjectSP (new CommandObjectProcessLaunch    (interpreter)));
1917     LoadSubCommand ("continue",    CommandObjectSP (new CommandObjectProcessContinue  (interpreter)));
1918     LoadSubCommand ("connect",     CommandObjectSP (new CommandObjectProcessConnect   (interpreter)));
1919     LoadSubCommand ("detach",      CommandObjectSP (new CommandObjectProcessDetach    (interpreter)));
1920     LoadSubCommand ("load",        CommandObjectSP (new CommandObjectProcessLoad      (interpreter)));
1921     LoadSubCommand ("unload",      CommandObjectSP (new CommandObjectProcessUnload    (interpreter)));
1922     LoadSubCommand ("signal",      CommandObjectSP (new CommandObjectProcessSignal    (interpreter)));
1923     LoadSubCommand ("handle",      CommandObjectSP (new CommandObjectProcessHandle    (interpreter)));
1924     LoadSubCommand ("status",      CommandObjectSP (new CommandObjectProcessStatus    (interpreter)));
1925     LoadSubCommand ("interrupt",   CommandObjectSP (new CommandObjectProcessInterrupt (interpreter)));
1926     LoadSubCommand ("kill",        CommandObjectSP (new CommandObjectProcessKill      (interpreter)));
1927     LoadSubCommand ("plugin",      CommandObjectSP (new CommandObjectProcessPlugin    (interpreter)));
1928     LoadSubCommand ("save-core",   CommandObjectSP (new CommandObjectProcessSaveCore  (interpreter)));
1929 }
1930 
1931 CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess ()
1932 {
1933 }
1934 
1935