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 "CommandObjectProcess.h"
11 
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "lldb/Interpreter/Args.h"
17 #include "lldb/Interpreter/Options.h"
18 #include "lldb/Core/State.h"
19 #include "lldb/Interpreter/CommandInterpreter.h"
20 #include "lldb/Interpreter/CommandReturnObject.h"
21 #include "./CommandObjectThread.h"
22 #include "lldb/Target/Process.h"
23 #include "lldb/Target/Target.h"
24 #include "lldb/Target/Thread.h"
25 
26 using namespace lldb;
27 using namespace lldb_private;
28 
29 //-------------------------------------------------------------------------
30 // CommandObjectProcessLaunch
31 //-------------------------------------------------------------------------
32 #pragma mark CommandObjectProjectLaunch
33 class CommandObjectProcessLaunch : public CommandObject
34 {
35 public:
36 
37     class CommandOptions : public Options
38     {
39     public:
40 
41         CommandOptions () :
42             Options()
43         {
44             // Keep default values of all options in one place: ResetOptionValues ()
45             ResetOptionValues ();
46         }
47 
48         ~CommandOptions ()
49         {
50         }
51 
52         Error
53         SetOptionValue (int option_idx, const char *option_arg)
54         {
55             Error error;
56             char short_option = (char) m_getopt_table[option_idx].val;
57 
58             switch (short_option)
59             {
60                 case 's':   stop_at_entry = true;               break;
61                 case 'e':   stderr_path.assign (option_arg);    break;
62                 case 'i':   stdin_path.assign (option_arg);     break;
63                 case 'o':   stdout_path.assign (option_arg);    break;
64                 case 'p':   plugin_name.assign (option_arg);    break;
65                 case 'n':   no_stdio = true;                    break;
66                 case 'w':   working_dir.assign (option_arg);    break;
67                 case 't':
68                     if (option_arg && option_arg[0])
69                         tty_name.assign (option_arg);
70                     in_new_tty = true;
71                     break;
72                 default:
73                     error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
74                     break;
75 
76             }
77             return error;
78         }
79 
80         void
81         ResetOptionValues ()
82         {
83             Options::ResetOptionValues();
84             stop_at_entry = false;
85             in_new_tty = false;
86             tty_name.clear();
87             stdin_path.clear();
88             stdout_path.clear();
89             stderr_path.clear();
90             plugin_name.clear();
91             working_dir.clear();
92             no_stdio = false;
93         }
94 
95         const lldb::OptionDefinition*
96         GetDefinitions ()
97         {
98             return g_option_table;
99         }
100 
101         // Options table: Required for subclasses of Options.
102 
103         static lldb::OptionDefinition g_option_table[];
104 
105         // Instance variables to hold the values for command options.
106 
107         bool stop_at_entry;
108         bool in_new_tty;
109         bool no_stdio;
110         std::string tty_name;
111         std::string stderr_path;
112         std::string stdin_path;
113         std::string stdout_path;
114         std::string plugin_name;
115         std::string working_dir;
116 
117     };
118 
119     CommandObjectProcessLaunch (CommandInterpreter &interpreter) :
120         CommandObject (interpreter,
121                        "process launch",
122                        "Launch the executable in the debugger.",
123                        NULL)
124     {
125         CommandArgumentEntry arg;
126         CommandArgumentData run_args_arg;
127 
128         // Define the first (and only) variant of this arg.
129         run_args_arg.arg_type = eArgTypeRunArgs;
130         run_args_arg.arg_repetition = eArgRepeatOptional;
131 
132         // There is only one variant this argument could be; put it into the argument entry.
133         arg.push_back (run_args_arg);
134 
135         // Push the data for the first argument into the m_arguments vector.
136         m_arguments.push_back (arg);
137     }
138 
139 
140     ~CommandObjectProcessLaunch ()
141     {
142     }
143 
144     Options *
145     GetOptions ()
146     {
147         return &m_options;
148     }
149 
150     bool
151     Execute (Args& launch_args, CommandReturnObject &result)
152     {
153         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
154 
155         if (target == NULL)
156         {
157             result.AppendError ("invalid target, set executable file using 'file' command");
158             result.SetStatus (eReturnStatusFailed);
159             return false;
160         }
161 
162         // If our listener is NULL, users aren't allows to launch
163         char filename[PATH_MAX];
164         const Module *exe_module = target->GetExecutableModule().get();
165         exe_module->GetFileSpec().GetPath(filename, sizeof(filename));
166 
167         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
168         if (process && process->IsAlive())
169         {
170             if (!m_interpreter.Confirm ("There is a running process, kill it and restart?", true))
171             {
172                 result.AppendErrorWithFormat ("Process %u is currently being debugged, restart cancelled.\n",
173                                               process->GetID());
174                 result.SetStatus (eReturnStatusFailed);
175                 return false;
176             }
177             else
178             {
179                 Error error (process->Destroy());
180                 if (error.Success())
181                 {
182                     result.SetStatus (eReturnStatusSuccessFinishResult);
183                 }
184                 else
185                 {
186                     result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString());
187                     result.SetStatus (eReturnStatusFailed);
188                 }
189             }
190         }
191 
192         const char *plugin_name;
193         if (!m_options.plugin_name.empty())
194             plugin_name = m_options.plugin_name.c_str();
195         else
196             plugin_name = NULL;
197 
198         process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name).get();
199 
200         if (process == NULL)
201         {
202             result.AppendErrorWithFormat ("Failed to find a process plugin for executable.\n");
203             result.SetStatus (eReturnStatusFailed);
204             return false;
205         }
206 
207         // If no launch args were given on the command line, then use any that
208         // might have been set using the "run-args" set variable.
209         if (launch_args.GetArgumentCount() == 0)
210         {
211             if (process->GetRunArguments().GetArgumentCount() > 0)
212                 launch_args = process->GetRunArguments();
213         }
214 
215         if (m_options.in_new_tty)
216         {
217             char exec_file_path[PATH_MAX];
218             if (exe_module->GetFileSpec().GetPath(exec_file_path, sizeof(exec_file_path)))
219             {
220                 launch_args.InsertArgumentAtIndex(0, exec_file_path);
221             }
222             else
223             {
224                 result.AppendError("invalid executable");
225                 result.SetStatus (eReturnStatusFailed);
226                 return false;
227             }
228         }
229 
230         Args environment;
231 
232         process->GetEnvironmentAsArgs (environment);
233 
234         uint32_t launch_flags = eLaunchFlagNone;
235 
236         if (process->GetDisableASLR())
237             launch_flags |= eLaunchFlagDisableASLR;
238 
239         if (m_options.no_stdio)
240             launch_flags |= eLaunchFlagDisableSTDIO;
241         else if (!m_options.in_new_tty
242                  && m_options.stdin_path.empty()
243                  && m_options.stdout_path.empty()
244                  && m_options.stderr_path.empty())
245         {
246             // Only use the settings value if the user hasn't specified any options that would override it.
247             if (process->GetDisableSTDIO())
248                 launch_flags |= eLaunchFlagDisableSTDIO;
249         }
250 
251         const char **inferior_argv = launch_args.GetArgumentCount() ? launch_args.GetConstArgumentVector() : NULL;
252         const char **inferior_envp = environment.GetArgumentCount() ? environment.GetConstArgumentVector() : NULL;
253 
254         Error error;
255         const char *working_dir = NULL;
256         if (!m_options.working_dir.empty())
257             working_dir = m_options.working_dir.c_str();
258 
259         if (m_options.in_new_tty)
260         {
261 
262             lldb::pid_t pid = Host::LaunchInNewTerminal (m_options.tty_name.c_str(),
263                                                          inferior_argv,
264                                                          inferior_envp,
265                                                          working_dir,
266                                                          &exe_module->GetArchitecture(),
267                                                          true,
268                                                          process->GetDisableASLR());
269 
270             if (pid != LLDB_INVALID_PROCESS_ID)
271                 error = process->Attach (pid);
272         }
273         else
274         {
275             const char * stdin_path = NULL;
276             const char * stdout_path = NULL;
277             const char * stderr_path = NULL;
278 
279             // Were any standard input/output/error paths given on the command line?
280             if (m_options.stdin_path.empty() &&
281                 m_options.stdout_path.empty() &&
282                 m_options.stderr_path.empty())
283             {
284                 // No standard file handles were given on the command line, check
285                 // with the process object in case they were give using "set settings"
286                 stdin_path = process->GetStandardInputPath();
287                 stdout_path = process->GetStandardOutputPath();
288                 stderr_path = process->GetStandardErrorPath();
289             }
290             else
291             {
292                 stdin_path = m_options.stdin_path.empty()  ? NULL : m_options.stdin_path.c_str();
293                 stdout_path = m_options.stdout_path.empty() ? NULL : m_options.stdout_path.c_str();
294                 stderr_path = m_options.stderr_path.empty() ? NULL : m_options.stderr_path.c_str();
295             }
296 
297             error = process->Launch (inferior_argv,
298                                      inferior_envp,
299                                      launch_flags,
300                                      stdin_path,
301                                      stdout_path,
302                                      stderr_path,
303                                      working_dir);
304         }
305 
306         if (error.Success())
307         {
308             const char *archname = exe_module->GetArchitecture().AsCString();
309 
310             result.AppendMessageWithFormat ("Process %i launched: '%s' (%s)\n", process->GetID(), filename, archname);
311             result.SetDidChangeProcessState (true);
312             if (m_options.stop_at_entry == false)
313             {
314                 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
315                 StateType state = process->WaitForProcessToStop (NULL);
316 
317                 if (state == eStateStopped)
318                 {
319                     error = process->Resume();
320                     if (error.Success())
321                     {
322                         bool synchronous_execution = m_interpreter.GetSynchronous ();
323                         if (synchronous_execution)
324                         {
325                             state = process->WaitForProcessToStop (NULL);
326                             result.SetDidChangeProcessState (true);
327                             result.SetStatus (eReturnStatusSuccessFinishResult);
328                         }
329                         else
330                         {
331                             result.SetStatus (eReturnStatusSuccessContinuingNoResult);
332                         }
333                     }
334                 }
335             }
336         }
337 
338         return result.Succeeded();
339     }
340 
341     virtual const char *GetRepeatCommand (Args &current_command_args, uint32_t index)
342     {
343         // No repeat for "process launch"...
344         return "";
345     }
346 
347 protected:
348 
349     CommandOptions m_options;
350 };
351 
352 
353 #define SET1 LLDB_OPT_SET_1
354 #define SET2 LLDB_OPT_SET_2
355 #define SET3 LLDB_OPT_SET_3
356 
357 lldb::OptionDefinition
358 CommandObjectProcessLaunch::CommandOptions::g_option_table[] =
359 {
360 { SET1 | SET2 | SET3, false, "stop-at-entry", 's', no_argument,       NULL, 0, eArgTypeNone,    "Stop at the entry point of the program when launching a process."},
361 { SET1              , false, "stdin",         'i', required_argument, NULL, 0, eArgTypePath,    "Redirect stdin for the process to <path>."},
362 { SET1              , false, "stdout",        'o', required_argument, NULL, 0, eArgTypePath,    "Redirect stdout for the process to <path>."},
363 { SET1              , false, "stderr",        'e', required_argument, NULL, 0, eArgTypePath,    "Redirect stderr for the process to <path>."},
364 { SET1 | SET2 | SET3, false, "plugin",        'p', required_argument, NULL, 0, eArgTypePlugin,  "Name of the process plugin you want to use."},
365 {        SET2       , false, "tty",           't', optional_argument, NULL, 0, eArgTypePath,    "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."},
366 {               SET3, false, "no-stdio",      'n', no_argument,       NULL, 0, eArgTypeNone,    "Do not set up for terminal I/O to go to running process."},
367 { SET1 | SET2 | SET3, false, "working-dir",   'w', required_argument, NULL, 0, eArgTypePath,    "Set the current working directory to <path> when running the inferior."},
368 { 0,                  false, NULL,             0,  0,                 NULL, 0, eArgTypeNone,    NULL }
369 };
370 
371 #undef SET1
372 #undef SET2
373 #undef SET3
374 
375 //-------------------------------------------------------------------------
376 // CommandObjectProcessAttach
377 //-------------------------------------------------------------------------
378 #pragma mark CommandObjectProcessAttach
379 class CommandObjectProcessAttach : public CommandObject
380 {
381 public:
382 
383     class CommandOptions : public Options
384     {
385     public:
386 
387         CommandOptions () :
388             Options()
389         {
390             // Keep default values of all options in one place: ResetOptionValues ()
391             ResetOptionValues ();
392         }
393 
394         ~CommandOptions ()
395         {
396         }
397 
398         Error
399         SetOptionValue (int option_idx, const char *option_arg)
400         {
401             Error error;
402             char short_option = (char) m_getopt_table[option_idx].val;
403             bool success = false;
404             switch (short_option)
405             {
406                 case 'p':
407                     pid = Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success);
408                     if (!success || pid == LLDB_INVALID_PROCESS_ID)
409                     {
410                         error.SetErrorStringWithFormat("Invalid process ID '%s'.\n", option_arg);
411                     }
412                     break;
413 
414                 case 'P':
415                     plugin_name = option_arg;
416                     break;
417 
418                 case 'n':
419                     name.assign(option_arg);
420                     break;
421 
422                 case 'w':
423                     waitfor = true;
424                     break;
425 
426                 default:
427                     error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
428                     break;
429             }
430             return error;
431         }
432 
433         void
434         ResetOptionValues ()
435         {
436             Options::ResetOptionValues();
437             pid = LLDB_INVALID_PROCESS_ID;
438             name.clear();
439             waitfor = false;
440         }
441 
442         const lldb::OptionDefinition*
443         GetDefinitions ()
444         {
445             return g_option_table;
446         }
447 
448         virtual bool
449         HandleOptionArgumentCompletion (CommandInterpreter &interpeter,
450                                         Args &input,
451                                         int cursor_index,
452                                         int char_pos,
453                                         OptionElementVector &opt_element_vector,
454                                         int opt_element_index,
455                                         int match_start_point,
456                                         int max_return_elements,
457                                         bool &word_complete,
458                                         StringList &matches)
459         {
460             int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
461             int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
462 
463             // We are only completing the name option for now...
464 
465             const lldb::OptionDefinition *opt_defs = GetDefinitions();
466             if (opt_defs[opt_defs_index].short_option == 'n')
467             {
468                 // Are we in the name?
469 
470                 // Look to see if there is a -P argument provided, and if so use that plugin, otherwise
471                 // use the default plugin.
472                 Process *process = interpeter.GetDebugger().GetExecutionContext().process;
473                 bool need_to_delete_process = false;
474 
475                 const char *partial_name = NULL;
476                 partial_name = input.GetArgumentAtIndex(opt_arg_pos);
477 
478                 if (process && process->IsAlive())
479                     return true;
480 
481                 Target *target = interpeter.GetDebugger().GetSelectedTarget().get();
482                 if (target == NULL)
483                 {
484                     // No target has been set yet, for now do host completion.  Otherwise I don't know how we would
485                     // figure out what the right target to use is...
486                     std::vector<lldb::pid_t> pids;
487                     Host::ListProcessesMatchingName (partial_name, matches, pids);
488                     return true;
489                 }
490                 if (!process)
491                 {
492                     process = target->CreateProcess (interpeter.GetDebugger().GetListener(), partial_name).get();
493                     need_to_delete_process = true;
494                 }
495 
496                 if (process)
497                 {
498                     matches.Clear();
499                     std::vector<lldb::pid_t> pids;
500                     process->ListProcessesMatchingName (NULL, matches, pids);
501                     if (need_to_delete_process)
502                         target->DeleteCurrentProcess();
503                     return true;
504                 }
505             }
506 
507             return false;
508         }
509 
510         // Options table: Required for subclasses of Options.
511 
512         static lldb::OptionDefinition g_option_table[];
513 
514         // Instance variables to hold the values for command options.
515 
516         lldb::pid_t pid;
517         std::string plugin_name;
518         std::string name;
519         bool waitfor;
520     };
521 
522     CommandObjectProcessAttach (CommandInterpreter &interpreter) :
523         CommandObject (interpreter,
524                        "process attach",
525                        "Attach to a process.",
526                        "process attach <cmd-options>")
527     {
528     }
529 
530     ~CommandObjectProcessAttach ()
531     {
532     }
533 
534     bool
535     Execute (Args& command,
536              CommandReturnObject &result)
537     {
538         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
539 
540         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
541         if (process)
542         {
543             if (process->IsAlive())
544             {
545                 result.AppendErrorWithFormat ("Process %u is currently being debugged, kill the process before attaching.\n",
546                                               process->GetID());
547                 result.SetStatus (eReturnStatusFailed);
548                 return false;
549             }
550         }
551 
552         if (target == NULL)
553         {
554             // If there isn't a current target create one.
555             TargetSP new_target_sp;
556             FileSpec emptyFileSpec;
557             ArchSpec emptyArchSpec;
558             Error error;
559 
560             error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(),
561                                                                               emptyFileSpec,
562                                                                               emptyArchSpec,
563                                                                               NULL,
564                                                                               false,
565                                                                               new_target_sp);
566             target = new_target_sp.get();
567             if (target == NULL || error.Fail())
568             {
569                 result.AppendError(error.AsCString("Error creating empty target"));
570                 return false;
571             }
572             m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target);
573         }
574 
575         // Record the old executable module, we want to issue a warning if the process of attaching changed the
576         // current executable (like somebody said "file foo" then attached to a PID whose executable was bar.)
577 
578         ModuleSP old_exec_module_sp = target->GetExecutableModule();
579         ArchSpec old_arch_spec = target->GetArchitecture();
580 
581         if (command.GetArgumentCount())
582         {
583             result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: \n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
584             result.SetStatus (eReturnStatusFailed);
585         }
586         else
587         {
588             const char *plugin_name = NULL;
589 
590             if (!m_options.plugin_name.empty())
591                 plugin_name = m_options.plugin_name.c_str();
592 
593             process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name).get();
594 
595             if (process)
596             {
597                 Error error;
598                 int attach_pid = m_options.pid;
599 
600                 const char *wait_name = NULL;
601 
602                 if (m_options.name.empty())
603                 {
604                     if (old_exec_module_sp)
605                     {
606                         wait_name = old_exec_module_sp->GetFileSpec().GetFilename().AsCString();
607                     }
608                 }
609                 else
610                 {
611                     wait_name = m_options.name.c_str();
612                 }
613 
614                 // If we are waiting for a process with this name to show up, do that first.
615                 if (m_options.waitfor)
616                 {
617 
618                     if (wait_name == NULL)
619                     {
620                         result.AppendError("Invalid arguments: must have a file loaded or supply a process name with the waitfor option.\n");
621                         result.SetStatus (eReturnStatusFailed);
622                         return false;
623                     }
624 
625                     m_interpreter.GetDebugger().GetOutputStream().Printf("Waiting to attach to a process named \"%s\".\n", wait_name);
626                     error = process->Attach (wait_name, m_options.waitfor);
627                     if (error.Success())
628                     {
629                         result.SetStatus (eReturnStatusSuccessContinuingNoResult);
630                     }
631                     else
632                     {
633                         result.AppendErrorWithFormat ("Waiting for a process to launch named '%s': %s\n",
634                                                          wait_name,
635                                                          error.AsCString());
636                         result.SetStatus (eReturnStatusFailed);
637                         return false;
638                     }
639                 }
640                 else
641                 {
642                     // If the process was specified by name look it up, so we can warn if there are multiple
643                     // processes with this pid.
644 
645                     if (attach_pid == LLDB_INVALID_PROCESS_ID && wait_name != NULL)
646                     {
647                         std::vector<lldb::pid_t> pids;
648                         StringList matches;
649 
650                         process->ListProcessesMatchingName(wait_name, matches, pids);
651                         if (matches.GetSize() > 1)
652                         {
653                             result.AppendErrorWithFormat("More than one process named %s\n", wait_name);
654                             result.SetStatus (eReturnStatusFailed);
655                             return false;
656                         }
657                         else if (matches.GetSize() == 0)
658                         {
659                             result.AppendErrorWithFormat("Could not find a process named %s\n", wait_name);
660                             result.SetStatus (eReturnStatusFailed);
661                             return false;
662                         }
663                         else
664                         {
665                             attach_pid = pids[0];
666                         }
667 
668                     }
669 
670                     if (attach_pid != LLDB_INVALID_PROCESS_ID)
671                     {
672                         error = process->Attach (attach_pid);
673                         if (error.Success())
674                         {
675                             result.SetStatus (eReturnStatusSuccessContinuingNoResult);
676                         }
677                         else
678                         {
679                             result.AppendErrorWithFormat ("Attaching to process %i failed: %s.\n",
680                                                          attach_pid,
681                                                          error.AsCString());
682                             result.SetStatus (eReturnStatusFailed);
683                         }
684                     }
685                     else
686                     {
687                         result.AppendErrorWithFormat ("No PID specified for attach\n",
688                                                          attach_pid,
689                                                          error.AsCString());
690                         result.SetStatus (eReturnStatusFailed);
691 
692                     }
693                 }
694             }
695         }
696 
697         if (result.Succeeded())
698         {
699             // Okay, we're done.  Last step is to warn if the executable module has changed:
700             if (!old_exec_module_sp)
701             {
702                 char new_path[PATH_MAX + 1];
703                 target->GetExecutableModule()->GetFileSpec().GetPath(new_path, PATH_MAX);
704 
705                 result.AppendMessageWithFormat("Executable module set to \"%s\".\n",
706                     new_path);
707             }
708             else if (old_exec_module_sp->GetFileSpec() != target->GetExecutableModule()->GetFileSpec())
709             {
710                 char old_path[PATH_MAX + 1];
711                 char new_path[PATH_MAX + 1];
712 
713                 old_exec_module_sp->GetFileSpec().GetPath(old_path, PATH_MAX);
714                 target->GetExecutableModule()->GetFileSpec().GetPath (new_path, PATH_MAX);
715 
716                 result.AppendWarningWithFormat("Executable module changed from \"%s\" to \"%s\".\n",
717                                                     old_path, new_path);
718             }
719 
720             if (!old_arch_spec.IsValid())
721             {
722                 result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().AsCString());
723             }
724             else if (old_arch_spec != target->GetArchitecture())
725             {
726                 result.AppendWarningWithFormat("Architecture changed from %s to %s.\n",
727                                                 old_arch_spec.AsCString(), target->GetArchitecture().AsCString());
728             }
729         }
730         return result.Succeeded();
731     }
732 
733     Options *
734     GetOptions ()
735     {
736         return &m_options;
737     }
738 
739 protected:
740 
741     CommandOptions m_options;
742 };
743 
744 
745 lldb::OptionDefinition
746 CommandObjectProcessAttach::CommandOptions::g_option_table[] =
747 {
748 { LLDB_OPT_SET_ALL, false, "plugin", 'P', required_argument, NULL, 0, eArgTypePlugin,        "Name of the process plugin you want to use."},
749 { LLDB_OPT_SET_1,   false, "pid",    'p', required_argument, NULL, 0, eArgTypePid,           "The process ID of an existing process to attach to."},
750 { LLDB_OPT_SET_2,   false, "name",   'n', required_argument, NULL, 0, eArgTypeProcessName,  "The name of the process to attach to."},
751 { LLDB_OPT_SET_2,   false, "waitfor",'w', no_argument,       NULL, 0, eArgTypeNone,              "Wait for the the process with <process-name> to launch."},
752 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
753 };
754 
755 //-------------------------------------------------------------------------
756 // CommandObjectProcessContinue
757 //-------------------------------------------------------------------------
758 #pragma mark CommandObjectProcessContinue
759 
760 class CommandObjectProcessContinue : public CommandObject
761 {
762 public:
763 
764     CommandObjectProcessContinue (CommandInterpreter &interpreter) :
765         CommandObject (interpreter,
766                        "process continue",
767                        "Continue execution of all threads in the current process.",
768                        "process continue",
769                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
770     {
771     }
772 
773 
774     ~CommandObjectProcessContinue ()
775     {
776     }
777 
778     bool
779     Execute (Args& command,
780              CommandReturnObject &result)
781     {
782         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
783         bool synchronous_execution = m_interpreter.GetSynchronous ();
784 
785         if (process == NULL)
786         {
787             result.AppendError ("no process to continue");
788             result.SetStatus (eReturnStatusFailed);
789             return false;
790          }
791 
792         StateType state = process->GetState();
793         if (state == eStateStopped)
794         {
795             if (command.GetArgumentCount() != 0)
796             {
797                 result.AppendErrorWithFormat ("The '%s' command does not take any arguments.\n", m_cmd_name.c_str());
798                 result.SetStatus (eReturnStatusFailed);
799                 return false;
800             }
801 
802             const uint32_t num_threads = process->GetThreadList().GetSize();
803 
804             // Set the actions that the threads should each take when resuming
805             for (uint32_t idx=0; idx<num_threads; ++idx)
806             {
807                 process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState (eStateRunning);
808             }
809 
810             Error error(process->Resume());
811             if (error.Success())
812             {
813                 result.AppendMessageWithFormat ("Process %i resuming\n", process->GetID());
814                 if (synchronous_execution)
815                 {
816                     state = process->WaitForProcessToStop (NULL);
817 
818                     result.SetDidChangeProcessState (true);
819                     result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state));
820                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
821                 }
822                 else
823                 {
824                     result.SetStatus (eReturnStatusSuccessContinuingNoResult);
825                 }
826             }
827             else
828             {
829                 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
830                 result.SetStatus (eReturnStatusFailed);
831             }
832         }
833         else
834         {
835             result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
836                                          StateAsCString(state));
837             result.SetStatus (eReturnStatusFailed);
838         }
839         return result.Succeeded();
840     }
841 };
842 
843 //-------------------------------------------------------------------------
844 // CommandObjectProcessDetach
845 //-------------------------------------------------------------------------
846 #pragma mark CommandObjectProcessDetach
847 
848 class CommandObjectProcessDetach : public CommandObject
849 {
850 public:
851 
852     CommandObjectProcessDetach (CommandInterpreter &interpreter) :
853         CommandObject (interpreter,
854                        "process detach",
855                        "Detach from the current process being debugged.",
856                        "process detach",
857                        eFlagProcessMustBeLaunched)
858     {
859     }
860 
861     ~CommandObjectProcessDetach ()
862     {
863     }
864 
865     bool
866     Execute (Args& command,
867              CommandReturnObject &result)
868     {
869         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
870         if (process == NULL)
871         {
872             result.AppendError ("must have a valid process in order to detach");
873             result.SetStatus (eReturnStatusFailed);
874             return false;
875         }
876 
877         result.AppendMessageWithFormat ("Detaching from process %i\n", process->GetID());
878         Error error (process->Detach());
879         if (error.Success())
880         {
881             result.SetStatus (eReturnStatusSuccessFinishResult);
882         }
883         else
884         {
885             result.AppendErrorWithFormat ("Detach failed: %s\n", error.AsCString());
886             result.SetStatus (eReturnStatusFailed);
887             return false;
888         }
889         return result.Succeeded();
890     }
891 };
892 
893 //-------------------------------------------------------------------------
894 // CommandObjectProcessLoad
895 //-------------------------------------------------------------------------
896 #pragma mark CommandObjectProcessLoad
897 
898 class CommandObjectProcessLoad : public CommandObject
899 {
900 public:
901 
902     CommandObjectProcessLoad (CommandInterpreter &interpreter) :
903         CommandObject (interpreter,
904                        "process load",
905                        "Load a shared library into the current process.",
906                        "process load <filename> [<filename> ...]",
907                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
908     {
909     }
910 
911     ~CommandObjectProcessLoad ()
912     {
913     }
914 
915     bool
916     Execute (Args& command,
917              CommandReturnObject &result)
918     {
919         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
920         if (process == NULL)
921         {
922             result.AppendError ("must have a valid process in order to load a shared library");
923             result.SetStatus (eReturnStatusFailed);
924             return false;
925         }
926 
927         const uint32_t argc = command.GetArgumentCount();
928 
929         for (uint32_t i=0; i<argc; ++i)
930         {
931             Error error;
932             const char *image_path = command.GetArgumentAtIndex(i);
933             FileSpec image_spec (image_path, false);
934             uint32_t image_token = process->LoadImage(image_spec, error);
935             if (image_token != LLDB_INVALID_IMAGE_TOKEN)
936             {
937                 result.AppendMessageWithFormat ("Loading \"%s\"...ok\nImage %u loaded.\n", image_path, image_token);
938                 result.SetStatus (eReturnStatusSuccessFinishResult);
939             }
940             else
941             {
942                 result.AppendErrorWithFormat ("failed to load '%s': %s", image_path, error.AsCString());
943                 result.SetStatus (eReturnStatusFailed);
944             }
945         }
946         return result.Succeeded();
947     }
948 };
949 
950 
951 //-------------------------------------------------------------------------
952 // CommandObjectProcessUnload
953 //-------------------------------------------------------------------------
954 #pragma mark CommandObjectProcessUnload
955 
956 class CommandObjectProcessUnload : public CommandObject
957 {
958 public:
959 
960     CommandObjectProcessUnload (CommandInterpreter &interpreter) :
961         CommandObject (interpreter,
962                        "process unload",
963                        "Unload a shared library from the current process using the index returned by a previous call to \"process load\".",
964                        "process unload <index>",
965                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
966     {
967     }
968 
969     ~CommandObjectProcessUnload ()
970     {
971     }
972 
973     bool
974     Execute (Args& command,
975              CommandReturnObject &result)
976     {
977         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
978         if (process == NULL)
979         {
980             result.AppendError ("must have a valid process in order to load a shared library");
981             result.SetStatus (eReturnStatusFailed);
982             return false;
983         }
984 
985         const uint32_t argc = command.GetArgumentCount();
986 
987         for (uint32_t i=0; i<argc; ++i)
988         {
989             const char *image_token_cstr = command.GetArgumentAtIndex(i);
990             uint32_t image_token = Args::StringToUInt32(image_token_cstr, LLDB_INVALID_IMAGE_TOKEN, 0);
991             if (image_token == LLDB_INVALID_IMAGE_TOKEN)
992             {
993                 result.AppendErrorWithFormat ("invalid image index argument '%s'", image_token_cstr);
994                 result.SetStatus (eReturnStatusFailed);
995                 break;
996             }
997             else
998             {
999                 Error error (process->UnloadImage(image_token));
1000                 if (error.Success())
1001                 {
1002                     result.AppendMessageWithFormat ("Unloading shared library with index %u...ok\n", image_token);
1003                     result.SetStatus (eReturnStatusSuccessFinishResult);
1004                 }
1005                 else
1006                 {
1007                     result.AppendErrorWithFormat ("failed to unload image: %s", error.AsCString());
1008                     result.SetStatus (eReturnStatusFailed);
1009                     break;
1010                 }
1011             }
1012         }
1013         return result.Succeeded();
1014     }
1015 };
1016 
1017 //-------------------------------------------------------------------------
1018 // CommandObjectProcessSignal
1019 //-------------------------------------------------------------------------
1020 #pragma mark CommandObjectProcessSignal
1021 
1022 class CommandObjectProcessSignal : public CommandObject
1023 {
1024 public:
1025 
1026     CommandObjectProcessSignal (CommandInterpreter &interpreter) :
1027         CommandObject (interpreter,
1028                        "process signal",
1029                        "Send a UNIX signal to the current process being debugged.",
1030                        NULL)
1031     {
1032         CommandArgumentEntry arg;
1033         CommandArgumentData signal_arg;
1034 
1035         // Define the first (and only) variant of this arg.
1036         signal_arg.arg_type = eArgTypeUnixSignal;
1037         signal_arg.arg_repetition = eArgRepeatPlain;
1038 
1039         // There is only one variant this argument could be; put it into the argument entry.
1040         arg.push_back (signal_arg);
1041 
1042         // Push the data for the first argument into the m_arguments vector.
1043         m_arguments.push_back (arg);
1044     }
1045 
1046     ~CommandObjectProcessSignal ()
1047     {
1048     }
1049 
1050     bool
1051     Execute (Args& command,
1052              CommandReturnObject &result)
1053     {
1054         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
1055         if (process == NULL)
1056         {
1057             result.AppendError ("no process to signal");
1058             result.SetStatus (eReturnStatusFailed);
1059             return false;
1060         }
1061 
1062         if (command.GetArgumentCount() == 1)
1063         {
1064             int signo = LLDB_INVALID_SIGNAL_NUMBER;
1065 
1066             const char *signal_name = command.GetArgumentAtIndex(0);
1067             if (::isxdigit (signal_name[0]))
1068                 signo = Args::StringToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0);
1069             else
1070                 signo = process->GetUnixSignals().GetSignalNumberFromName (signal_name);
1071 
1072             if (signo == LLDB_INVALID_SIGNAL_NUMBER)
1073             {
1074                 result.AppendErrorWithFormat ("Invalid signal argument '%s'.\n", command.GetArgumentAtIndex(0));
1075                 result.SetStatus (eReturnStatusFailed);
1076             }
1077             else
1078             {
1079                 Error error (process->Signal (signo));
1080                 if (error.Success())
1081                 {
1082                     result.SetStatus (eReturnStatusSuccessFinishResult);
1083                 }
1084                 else
1085                 {
1086                     result.AppendErrorWithFormat ("Failed to send signal %i: %s\n", signo, error.AsCString());
1087                     result.SetStatus (eReturnStatusFailed);
1088                 }
1089             }
1090         }
1091         else
1092         {
1093             result.AppendErrorWithFormat("'%s' takes exactly one signal number argument:\nUsage: \n", m_cmd_name.c_str(),
1094                                         m_cmd_syntax.c_str());
1095             result.SetStatus (eReturnStatusFailed);
1096         }
1097         return result.Succeeded();
1098     }
1099 };
1100 
1101 
1102 //-------------------------------------------------------------------------
1103 // CommandObjectProcessInterrupt
1104 //-------------------------------------------------------------------------
1105 #pragma mark CommandObjectProcessInterrupt
1106 
1107 class CommandObjectProcessInterrupt : public CommandObject
1108 {
1109 public:
1110 
1111 
1112     CommandObjectProcessInterrupt (CommandInterpreter &interpreter) :
1113     CommandObject (interpreter,
1114                    "process interrupt",
1115                    "Interrupt the current process being debugged.",
1116                    "process interrupt",
1117                    eFlagProcessMustBeLaunched)
1118     {
1119     }
1120 
1121     ~CommandObjectProcessInterrupt ()
1122     {
1123     }
1124 
1125     bool
1126     Execute (Args& command,
1127              CommandReturnObject &result)
1128     {
1129         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
1130         if (process == NULL)
1131         {
1132             result.AppendError ("no process to halt");
1133             result.SetStatus (eReturnStatusFailed);
1134             return false;
1135         }
1136 
1137         if (command.GetArgumentCount() == 0)
1138         {
1139             Error error(process->Halt ());
1140             if (error.Success())
1141             {
1142                 result.SetStatus (eReturnStatusSuccessFinishResult);
1143 
1144                 // Maybe we should add a "SuspendThreadPlans so we
1145                 // can halt, and keep in place all the current thread plans.
1146                 process->GetThreadList().DiscardThreadPlans();
1147             }
1148             else
1149             {
1150                 result.AppendErrorWithFormat ("Failed to halt process: %s\n", error.AsCString());
1151                 result.SetStatus (eReturnStatusFailed);
1152             }
1153         }
1154         else
1155         {
1156             result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: \n",
1157                                         m_cmd_name.c_str(),
1158                                         m_cmd_syntax.c_str());
1159             result.SetStatus (eReturnStatusFailed);
1160         }
1161         return result.Succeeded();
1162     }
1163 };
1164 
1165 //-------------------------------------------------------------------------
1166 // CommandObjectProcessKill
1167 //-------------------------------------------------------------------------
1168 #pragma mark CommandObjectProcessKill
1169 
1170 class CommandObjectProcessKill : public CommandObject
1171 {
1172 public:
1173 
1174     CommandObjectProcessKill (CommandInterpreter &interpreter) :
1175     CommandObject (interpreter,
1176                    "process kill",
1177                    "Terminate the current process being debugged.",
1178                    "process kill",
1179                    eFlagProcessMustBeLaunched)
1180     {
1181     }
1182 
1183     ~CommandObjectProcessKill ()
1184     {
1185     }
1186 
1187     bool
1188     Execute (Args& command,
1189              CommandReturnObject &result)
1190     {
1191         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
1192         if (process == NULL)
1193         {
1194             result.AppendError ("no process to kill");
1195             result.SetStatus (eReturnStatusFailed);
1196             return false;
1197         }
1198 
1199         if (command.GetArgumentCount() == 0)
1200         {
1201             Error error (process->Destroy());
1202             if (error.Success())
1203             {
1204                 result.SetStatus (eReturnStatusSuccessFinishResult);
1205             }
1206             else
1207             {
1208                 result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString());
1209                 result.SetStatus (eReturnStatusFailed);
1210             }
1211         }
1212         else
1213         {
1214             result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: \n",
1215                                         m_cmd_name.c_str(),
1216                                         m_cmd_syntax.c_str());
1217             result.SetStatus (eReturnStatusFailed);
1218         }
1219         return result.Succeeded();
1220     }
1221 };
1222 
1223 //-------------------------------------------------------------------------
1224 // CommandObjectProcessStatus
1225 //-------------------------------------------------------------------------
1226 #pragma mark CommandObjectProcessStatus
1227 
1228 class CommandObjectProcessStatus : public CommandObject
1229 {
1230 public:
1231     CommandObjectProcessStatus (CommandInterpreter &interpreter) :
1232     CommandObject (interpreter,
1233                    "process status",
1234                    "Show the current status and location of executing process.",
1235                    "process status",
1236                    0)
1237     {
1238     }
1239 
1240     ~CommandObjectProcessStatus()
1241     {
1242     }
1243 
1244 
1245     bool
1246     Execute
1247     (
1248         Args& command,
1249         CommandReturnObject &result
1250     )
1251     {
1252         StreamString &output_stream = result.GetOutputStream();
1253         result.SetStatus (eReturnStatusSuccessFinishNoResult);
1254         ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext());
1255         if (exe_ctx.process)
1256         {
1257             const StateType state = exe_ctx.process->GetState();
1258             if (StateIsStoppedState(state))
1259             {
1260                 if (state == eStateExited)
1261                 {
1262                     int exit_status = exe_ctx.process->GetExitStatus();
1263                     const char *exit_description = exe_ctx.process->GetExitDescription();
1264                     output_stream.Printf ("Process %d exited with status = %i (0x%8.8x) %s\n",
1265                                           exe_ctx.process->GetID(),
1266                                           exit_status,
1267                                           exit_status,
1268                                           exit_description ? exit_description : "");
1269                 }
1270                 else
1271                 {
1272                     output_stream.Printf ("Process %d %s\n", exe_ctx.process->GetID(), StateAsCString (state));
1273                     if (exe_ctx.thread == NULL)
1274                         exe_ctx.thread = exe_ctx.process->GetThreadList().GetThreadAtIndex(0).get();
1275                     if (exe_ctx.thread != NULL)
1276                     {
1277                         DisplayThreadsInfo (m_interpreter, &exe_ctx, result, true, true);
1278                     }
1279                     else
1280                     {
1281                         result.AppendError ("No valid thread found in current process.");
1282                         result.SetStatus (eReturnStatusFailed);
1283                     }
1284                 }
1285             }
1286             else
1287             {
1288                 output_stream.Printf ("Process %d is running.\n",
1289                                           exe_ctx.process->GetID());
1290             }
1291         }
1292         else
1293         {
1294             result.AppendError ("No current location or status available.");
1295             result.SetStatus (eReturnStatusFailed);
1296         }
1297         return result.Succeeded();
1298     }
1299 };
1300 
1301 //-------------------------------------------------------------------------
1302 // CommandObjectProcessHandle
1303 //-------------------------------------------------------------------------
1304 #pragma mark CommandObjectProcessHandle
1305 
1306 class CommandObjectProcessHandle : public CommandObject
1307 {
1308 public:
1309 
1310     class CommandOptions : public Options
1311     {
1312     public:
1313 
1314         CommandOptions () :
1315             Options ()
1316         {
1317             ResetOptionValues ();
1318         }
1319 
1320         ~CommandOptions ()
1321         {
1322         }
1323 
1324         Error
1325         SetOptionValue (int option_idx, const char *option_arg)
1326         {
1327             Error error;
1328             char short_option = (char) m_getopt_table[option_idx].val;
1329 
1330             switch (short_option)
1331             {
1332                 case 's':
1333                     stop = option_arg;
1334                     break;
1335                 case 'n':
1336                     notify = option_arg;
1337                     break;
1338                 case 'p':
1339                     pass = option_arg;
1340                     break;
1341                 default:
1342                     error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
1343                     break;
1344             }
1345             return error;
1346         }
1347 
1348         void
1349         ResetOptionValues ()
1350         {
1351             Options::ResetOptionValues();
1352             stop.clear();
1353             notify.clear();
1354             pass.clear();
1355         }
1356 
1357         const lldb::OptionDefinition*
1358         GetDefinitions ()
1359         {
1360             return g_option_table;
1361         }
1362 
1363         // Options table: Required for subclasses of Options.
1364 
1365         static lldb::OptionDefinition g_option_table[];
1366 
1367         // Instance variables to hold the values for command options.
1368 
1369         std::string stop;
1370         std::string notify;
1371         std::string pass;
1372     };
1373 
1374 
1375     CommandObjectProcessHandle (CommandInterpreter &interpreter) :
1376         CommandObject (interpreter,
1377                        "process handle",
1378                        "Show or update what the process and debugger should do with various signals received from the OS.",
1379                        NULL)
1380     {
1381         SetHelpLong ("If no signals are specified, update them all.  If no update option is specified, list the current values.\n");
1382         CommandArgumentEntry arg;
1383         CommandArgumentData signal_arg;
1384 
1385         signal_arg.arg_type = eArgTypeUnixSignal;
1386         signal_arg.arg_repetition = eArgRepeatStar;
1387 
1388         arg.push_back (signal_arg);
1389 
1390         m_arguments.push_back (arg);
1391     }
1392 
1393     ~CommandObjectProcessHandle ()
1394     {
1395     }
1396 
1397     Options *
1398     GetOptions ()
1399     {
1400         return &m_options;
1401     }
1402 
1403     bool
1404     VerifyCommandOptionValue (const std::string &option, int &real_value)
1405     {
1406         bool okay = true;
1407 
1408         bool success = false;
1409         bool tmp_value = Args::StringToBoolean (option.c_str(), false, &success);
1410 
1411         if (success && tmp_value)
1412             real_value = 1;
1413         else if (success && !tmp_value)
1414             real_value = 0;
1415         else
1416         {
1417             // If the value isn't 'true' or 'false', it had better be 0 or 1.
1418             real_value = Args::StringToUInt32 (option.c_str(), 3);
1419             if (real_value != 0 && real_value != 1)
1420                 okay = false;
1421         }
1422 
1423         return okay;
1424     }
1425 
1426     void
1427     PrintSignalHeader (Stream &str)
1428     {
1429         str.Printf ("NAME        PASS   STOP   NOTIFY\n");
1430         str.Printf ("==========  =====  =====  ======\n");
1431     }
1432 
1433     void
1434     PrintSignal (Stream &str, int32_t signo, const char *sig_name, UnixSignals &signals)
1435     {
1436         bool stop;
1437         bool suppress;
1438         bool notify;
1439 
1440         str.Printf ("%-10s  ", sig_name);
1441         if (signals.GetSignalInfo (signo, suppress, stop, notify))
1442         {
1443             bool pass = !suppress;
1444             str.Printf ("%s  %s  %s",
1445                         (pass ? "true " : "false"),
1446                         (stop ? "true " : "false"),
1447                         (notify ? "true " : "false"));
1448         }
1449         str.Printf ("\n");
1450     }
1451 
1452     void
1453     PrintSignalInformation (Stream &str, Args &signal_args, int num_valid_signals, UnixSignals &signals)
1454     {
1455         PrintSignalHeader (str);
1456 
1457         if (num_valid_signals > 0)
1458         {
1459             size_t num_args = signal_args.GetArgumentCount();
1460             for (size_t i = 0; i < num_args; ++i)
1461             {
1462                 int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i));
1463                 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
1464                     PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals);
1465             }
1466         }
1467         else // Print info for ALL signals
1468         {
1469             int32_t signo = signals.GetFirstSignalNumber();
1470             while (signo != LLDB_INVALID_SIGNAL_NUMBER)
1471             {
1472                 PrintSignal (str, signo, signals.GetSignalAsCString (signo), signals);
1473                 signo = signals.GetNextSignalNumber (signo);
1474             }
1475         }
1476     }
1477 
1478     bool
1479     Execute (Args &signal_args, CommandReturnObject &result)
1480     {
1481         TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
1482 
1483         if (!target_sp)
1484         {
1485             result.AppendError ("No current target;"
1486                                 " cannot handle signals until you have a valid target and process.\n");
1487             result.SetStatus (eReturnStatusFailed);
1488             return false;
1489         }
1490 
1491         ProcessSP process_sp = target_sp->GetProcessSP();
1492 
1493         if (!process_sp)
1494         {
1495             result.AppendError ("No current process; cannot handle signals until you have a valid process.\n");
1496             result.SetStatus (eReturnStatusFailed);
1497             return false;
1498         }
1499 
1500         int stop_action = -1;   // -1 means leave the current setting alone
1501         int pass_action = -1;   // -1 means leave the current setting alone
1502         int notify_action = -1; // -1 means leave the current setting alone
1503 
1504         if (! m_options.stop.empty()
1505             && ! VerifyCommandOptionValue (m_options.stop, stop_action))
1506         {
1507             result.AppendError ("Invalid argument for command option --stop; must be true or false.\n");
1508             result.SetStatus (eReturnStatusFailed);
1509             return false;
1510         }
1511 
1512         if (! m_options.notify.empty()
1513             && ! VerifyCommandOptionValue (m_options.notify, notify_action))
1514         {
1515             result.AppendError ("Invalid argument for command option --notify; must be true or false.\n");
1516             result.SetStatus (eReturnStatusFailed);
1517             return false;
1518         }
1519 
1520         if (! m_options.pass.empty()
1521             && ! VerifyCommandOptionValue (m_options.pass, pass_action))
1522         {
1523             result.AppendError ("Invalid argument for command option --pass; must be true or false.\n");
1524             result.SetStatus (eReturnStatusFailed);
1525             return false;
1526         }
1527 
1528         size_t num_args = signal_args.GetArgumentCount();
1529         UnixSignals &signals = process_sp->GetUnixSignals();
1530         int num_signals_set = 0;
1531 
1532         if (num_args > 0)
1533         {
1534             for (size_t i = 0; i < num_args; ++i)
1535             {
1536                 int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i));
1537                 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
1538                 {
1539                     // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees
1540                     // the value is either 0 or 1.
1541                     if (stop_action != -1)
1542                         signals.SetShouldStop (signo, (bool) stop_action);
1543                     if (pass_action != -1)
1544                     {
1545                         bool suppress = ! ((bool) pass_action);
1546                         signals.SetShouldSuppress (signo, suppress);
1547                     }
1548                     if (notify_action != -1)
1549                         signals.SetShouldNotify (signo, (bool) notify_action);
1550                     ++num_signals_set;
1551                 }
1552                 else
1553                 {
1554                     result.AppendErrorWithFormat ("Invalid signal name '%s'\n", signal_args.GetArgumentAtIndex (i));
1555                 }
1556             }
1557         }
1558         else
1559         {
1560             // No signal specified, if any command options were specified, update ALL signals.
1561             if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1))
1562             {
1563                 if (m_interpreter.Confirm ("Do you really want to update all the signals?", false))
1564                 {
1565                     int32_t signo = signals.GetFirstSignalNumber();
1566                     while (signo != LLDB_INVALID_SIGNAL_NUMBER)
1567                     {
1568                         if (notify_action != -1)
1569                             signals.SetShouldNotify (signo, (bool) notify_action);
1570                         if (stop_action != -1)
1571                             signals.SetShouldStop (signo, (bool) stop_action);
1572                         if (pass_action != -1)
1573                         {
1574                             bool suppress = ! ((bool) pass_action);
1575                             signals.SetShouldSuppress (signo, suppress);
1576                         }
1577                         signo = signals.GetNextSignalNumber (signo);
1578                     }
1579                 }
1580             }
1581         }
1582 
1583         PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals);
1584 
1585         if (num_signals_set > 0)
1586             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1587         else
1588             result.SetStatus (eReturnStatusFailed);
1589 
1590         return result.Succeeded();
1591     }
1592 
1593 protected:
1594 
1595     CommandOptions m_options;
1596 };
1597 
1598 lldb::OptionDefinition
1599 CommandObjectProcessHandle::CommandOptions::g_option_table[] =
1600 {
1601 { LLDB_OPT_SET_1, false, "stop",   's', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the process should be stopped if the signal is received." },
1602 { LLDB_OPT_SET_1, false, "notify", 'n', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the debugger should notify the user if the signal is received." },
1603 { LLDB_OPT_SET_1, false, "pass",  'p', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." },
1604 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1605 };
1606 
1607 //-------------------------------------------------------------------------
1608 // CommandObjectMultiwordProcess
1609 //-------------------------------------------------------------------------
1610 
1611 CommandObjectMultiwordProcess::CommandObjectMultiwordProcess (CommandInterpreter &interpreter) :
1612     CommandObjectMultiword (interpreter,
1613                             "process",
1614                             "A set of commands for operating on a process.",
1615                             "process <subcommand> [<subcommand-options>]")
1616 {
1617     LoadSubCommand ("attach",      CommandObjectSP (new CommandObjectProcessAttach (interpreter)));
1618     LoadSubCommand ("launch",      CommandObjectSP (new CommandObjectProcessLaunch (interpreter)));
1619     LoadSubCommand ("continue",    CommandObjectSP (new CommandObjectProcessContinue (interpreter)));
1620     LoadSubCommand ("detach",      CommandObjectSP (new CommandObjectProcessDetach (interpreter)));
1621     LoadSubCommand ("load",        CommandObjectSP (new CommandObjectProcessLoad (interpreter)));
1622     LoadSubCommand ("unload",      CommandObjectSP (new CommandObjectProcessUnload (interpreter)));
1623     LoadSubCommand ("signal",      CommandObjectSP (new CommandObjectProcessSignal (interpreter)));
1624     LoadSubCommand ("handle",      CommandObjectSP (new CommandObjectProcessHandle (interpreter)));
1625     LoadSubCommand ("status",      CommandObjectSP (new CommandObjectProcessStatus (interpreter)));
1626     LoadSubCommand ("interrupt",   CommandObjectSP (new CommandObjectProcessInterrupt (interpreter)));
1627     LoadSubCommand ("kill",        CommandObjectSP (new CommandObjectProcessKill (interpreter)));
1628 }
1629 
1630 CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess ()
1631 {
1632 }
1633 
1634