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