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