xref: /llvm-project/lldb/source/Commands/CommandObjectProcess.cpp (revision bb3a283b3e8bc2cc4157ef1b73b7d5e6cda40775)
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         bool synchronous_execution = m_interpreter.GetSynchronous ();
540 
541         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
542         if (process)
543         {
544             if (process->IsAlive())
545             {
546                 result.AppendErrorWithFormat ("Process %u is currently being debugged, kill the process before attaching.\n",
547                                               process->GetID());
548                 result.SetStatus (eReturnStatusFailed);
549                 return false;
550             }
551         }
552 
553         if (target == NULL)
554         {
555             // If there isn't a current target create one.
556             TargetSP new_target_sp;
557             FileSpec emptyFileSpec;
558             ArchSpec emptyArchSpec;
559             Error error;
560 
561             error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(),
562                                                                               emptyFileSpec,
563                                                                               emptyArchSpec,
564                                                                               NULL,
565                                                                               false,
566                                                                               new_target_sp);
567             target = new_target_sp.get();
568             if (target == NULL || error.Fail())
569             {
570                 result.AppendError(error.AsCString("Error creating empty target"));
571                 return false;
572             }
573             m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target);
574         }
575 
576         // Record the old executable module, we want to issue a warning if the process of attaching changed the
577         // current executable (like somebody said "file foo" then attached to a PID whose executable was bar.)
578 
579         ModuleSP old_exec_module_sp = target->GetExecutableModule();
580         ArchSpec old_arch_spec = target->GetArchitecture();
581 
582         if (command.GetArgumentCount())
583         {
584             result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: \n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
585             result.SetStatus (eReturnStatusFailed);
586         }
587         else
588         {
589             const char *plugin_name = NULL;
590 
591             if (!m_options.plugin_name.empty())
592                 plugin_name = m_options.plugin_name.c_str();
593 
594             process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name).get();
595 
596             if (process)
597             {
598                 Error error;
599                 int attach_pid = m_options.pid;
600 
601                 const char *wait_name = NULL;
602 
603                 if (m_options.name.empty())
604                 {
605                     if (old_exec_module_sp)
606                     {
607                         wait_name = old_exec_module_sp->GetFileSpec().GetFilename().AsCString();
608                     }
609                 }
610                 else
611                 {
612                     wait_name = m_options.name.c_str();
613                 }
614 
615                 // If we are waiting for a process with this name to show up, do that first.
616                 if (m_options.waitfor)
617                 {
618 
619                     if (wait_name == NULL)
620                     {
621                         result.AppendError("Invalid arguments: must have a file loaded or supply a process name with the waitfor option.\n");
622                         result.SetStatus (eReturnStatusFailed);
623                         return false;
624                     }
625 
626                     m_interpreter.GetDebugger().GetOutputStream().Printf("Waiting to attach to a process named \"%s\".\n", wait_name);
627                     error = process->Attach (wait_name, m_options.waitfor);
628                     if (error.Success())
629                     {
630                         result.SetStatus (eReturnStatusSuccessContinuingNoResult);
631                     }
632                     else
633                     {
634                         result.AppendErrorWithFormat ("Waiting for a process to launch named '%s': %s\n",
635                                                          wait_name,
636                                                          error.AsCString());
637                         result.SetStatus (eReturnStatusFailed);
638                         return false;
639                     }
640                     // If we're synchronous, wait for the stopped event and report that.
641                     // Otherwise just return.
642                     // FIXME: in the async case it will now be possible to get to the command
643                     // interpreter with a state eStateAttaching.  Make sure we handle that correctly.
644                     if (synchronous_execution)
645                     {
646                         StateType state = process->WaitForProcessToStop (NULL);
647 
648                         result.SetDidChangeProcessState (true);
649                         result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state));
650                         result.SetStatus (eReturnStatusSuccessFinishNoResult);
651                     }
652                     else
653                     {
654                         result.SetDidChangeProcessState (true);
655                         result.AppendMessageWithFormat ("Starting to attach to process.");
656                         result.SetStatus (eReturnStatusSuccessFinishNoResult);
657                     }
658                 }
659                 else
660                 {
661                     // If the process was specified by name look it up, so we can warn if there are multiple
662                     // processes with this pid.
663 
664                     if (attach_pid == LLDB_INVALID_PROCESS_ID && wait_name != NULL)
665                     {
666                         std::vector<lldb::pid_t> pids;
667                         StringList matches;
668 
669                         process->ListProcessesMatchingName(wait_name, matches, pids);
670                         if (matches.GetSize() > 1)
671                         {
672                             result.AppendErrorWithFormat("More than one process named %s\n", wait_name);
673                             result.SetStatus (eReturnStatusFailed);
674                             return false;
675                         }
676                         else if (matches.GetSize() == 0)
677                         {
678                             result.AppendErrorWithFormat("Could not find a process named %s\n", wait_name);
679                             result.SetStatus (eReturnStatusFailed);
680                             return false;
681                         }
682                         else
683                         {
684                             attach_pid = pids[0];
685                         }
686 
687                     }
688 
689                     if (attach_pid != LLDB_INVALID_PROCESS_ID)
690                     {
691                         error = process->Attach (attach_pid);
692                         if (error.Success())
693                         {
694                             result.SetStatus (eReturnStatusSuccessContinuingNoResult);
695                         }
696                         else
697                         {
698                             result.AppendErrorWithFormat ("Attaching to process %i failed: %s.\n",
699                                                          attach_pid,
700                                                          error.AsCString());
701                             result.SetStatus (eReturnStatusFailed);
702                         }
703                         // See comment for synchronous_execution above.
704                         if (synchronous_execution)
705                         {
706                             StateType state = process->WaitForProcessToStop (NULL);
707 
708                             result.SetDidChangeProcessState (true);
709                             result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state));
710                             result.SetStatus (eReturnStatusSuccessFinishNoResult);
711                         }
712                         else
713                         {
714                             result.SetDidChangeProcessState (true);
715                             result.AppendMessageWithFormat ("Starting to attach to process.");
716                             result.SetStatus (eReturnStatusSuccessFinishNoResult);
717                         }
718                     }
719                     else
720                     {
721                         result.AppendErrorWithFormat ("No PID specified for attach\n",
722                                                          attach_pid,
723                                                          error.AsCString());
724                         result.SetStatus (eReturnStatusFailed);
725 
726                     }
727                 }
728             }
729         }
730 
731         if (result.Succeeded())
732         {
733             // Okay, we're done.  Last step is to warn if the executable module has changed:
734             if (!old_exec_module_sp)
735             {
736                 char new_path[PATH_MAX + 1];
737                 target->GetExecutableModule()->GetFileSpec().GetPath(new_path, PATH_MAX);
738 
739                 result.AppendMessageWithFormat("Executable module set to \"%s\".\n",
740                     new_path);
741             }
742             else if (old_exec_module_sp->GetFileSpec() != target->GetExecutableModule()->GetFileSpec())
743             {
744                 char old_path[PATH_MAX + 1];
745                 char new_path[PATH_MAX + 1];
746 
747                 old_exec_module_sp->GetFileSpec().GetPath(old_path, PATH_MAX);
748                 target->GetExecutableModule()->GetFileSpec().GetPath (new_path, PATH_MAX);
749 
750                 result.AppendWarningWithFormat("Executable module changed from \"%s\" to \"%s\".\n",
751                                                     old_path, new_path);
752             }
753 
754             if (!old_arch_spec.IsValid())
755             {
756                 result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().AsCString());
757             }
758             else if (old_arch_spec != target->GetArchitecture())
759             {
760                 result.AppendWarningWithFormat("Architecture changed from %s to %s.\n",
761                                                 old_arch_spec.AsCString(), target->GetArchitecture().AsCString());
762             }
763         }
764         return result.Succeeded();
765     }
766 
767     Options *
768     GetOptions ()
769     {
770         return &m_options;
771     }
772 
773 protected:
774 
775     CommandOptions m_options;
776 };
777 
778 
779 lldb::OptionDefinition
780 CommandObjectProcessAttach::CommandOptions::g_option_table[] =
781 {
782 { LLDB_OPT_SET_ALL, false, "plugin", 'P', required_argument, NULL, 0, eArgTypePlugin,        "Name of the process plugin you want to use."},
783 { LLDB_OPT_SET_1,   false, "pid",    'p', required_argument, NULL, 0, eArgTypePid,           "The process ID of an existing process to attach to."},
784 { LLDB_OPT_SET_2,   false, "name",   'n', required_argument, NULL, 0, eArgTypeProcessName,  "The name of the process to attach to."},
785 { LLDB_OPT_SET_2,   false, "waitfor",'w', no_argument,       NULL, 0, eArgTypeNone,              "Wait for the the process with <process-name> to launch."},
786 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
787 };
788 
789 //-------------------------------------------------------------------------
790 // CommandObjectProcessContinue
791 //-------------------------------------------------------------------------
792 #pragma mark CommandObjectProcessContinue
793 
794 class CommandObjectProcessContinue : public CommandObject
795 {
796 public:
797 
798     CommandObjectProcessContinue (CommandInterpreter &interpreter) :
799         CommandObject (interpreter,
800                        "process continue",
801                        "Continue execution of all threads in the current process.",
802                        "process continue",
803                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
804     {
805     }
806 
807 
808     ~CommandObjectProcessContinue ()
809     {
810     }
811 
812     bool
813     Execute (Args& command,
814              CommandReturnObject &result)
815     {
816         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
817         bool synchronous_execution = m_interpreter.GetSynchronous ();
818 
819         if (process == NULL)
820         {
821             result.AppendError ("no process to continue");
822             result.SetStatus (eReturnStatusFailed);
823             return false;
824          }
825 
826         StateType state = process->GetState();
827         if (state == eStateStopped)
828         {
829             if (command.GetArgumentCount() != 0)
830             {
831                 result.AppendErrorWithFormat ("The '%s' command does not take any arguments.\n", m_cmd_name.c_str());
832                 result.SetStatus (eReturnStatusFailed);
833                 return false;
834             }
835 
836             const uint32_t num_threads = process->GetThreadList().GetSize();
837 
838             // Set the actions that the threads should each take when resuming
839             for (uint32_t idx=0; idx<num_threads; ++idx)
840             {
841                 process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState (eStateRunning);
842             }
843 
844             Error error(process->Resume());
845             if (error.Success())
846             {
847                 result.AppendMessageWithFormat ("Process %i resuming\n", process->GetID());
848                 if (synchronous_execution)
849                 {
850                     state = process->WaitForProcessToStop (NULL);
851 
852                     result.SetDidChangeProcessState (true);
853                     result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state));
854                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
855                 }
856                 else
857                 {
858                     result.SetStatus (eReturnStatusSuccessContinuingNoResult);
859                 }
860             }
861             else
862             {
863                 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
864                 result.SetStatus (eReturnStatusFailed);
865             }
866         }
867         else
868         {
869             result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
870                                          StateAsCString(state));
871             result.SetStatus (eReturnStatusFailed);
872         }
873         return result.Succeeded();
874     }
875 };
876 
877 //-------------------------------------------------------------------------
878 // CommandObjectProcessDetach
879 //-------------------------------------------------------------------------
880 #pragma mark CommandObjectProcessDetach
881 
882 class CommandObjectProcessDetach : public CommandObject
883 {
884 public:
885 
886     CommandObjectProcessDetach (CommandInterpreter &interpreter) :
887         CommandObject (interpreter,
888                        "process detach",
889                        "Detach from the current process being debugged.",
890                        "process detach",
891                        eFlagProcessMustBeLaunched)
892     {
893     }
894 
895     ~CommandObjectProcessDetach ()
896     {
897     }
898 
899     bool
900     Execute (Args& command,
901              CommandReturnObject &result)
902     {
903         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
904         if (process == NULL)
905         {
906             result.AppendError ("must have a valid process in order to detach");
907             result.SetStatus (eReturnStatusFailed);
908             return false;
909         }
910 
911         result.AppendMessageWithFormat ("Detaching from process %i\n", process->GetID());
912         Error error (process->Detach());
913         if (error.Success())
914         {
915             result.SetStatus (eReturnStatusSuccessFinishResult);
916         }
917         else
918         {
919             result.AppendErrorWithFormat ("Detach failed: %s\n", error.AsCString());
920             result.SetStatus (eReturnStatusFailed);
921             return false;
922         }
923         return result.Succeeded();
924     }
925 };
926 
927 //-------------------------------------------------------------------------
928 // CommandObjectProcessLoad
929 //-------------------------------------------------------------------------
930 #pragma mark CommandObjectProcessLoad
931 
932 class CommandObjectProcessLoad : public CommandObject
933 {
934 public:
935 
936     CommandObjectProcessLoad (CommandInterpreter &interpreter) :
937         CommandObject (interpreter,
938                        "process load",
939                        "Load a shared library into the current process.",
940                        "process load <filename> [<filename> ...]",
941                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
942     {
943     }
944 
945     ~CommandObjectProcessLoad ()
946     {
947     }
948 
949     bool
950     Execute (Args& command,
951              CommandReturnObject &result)
952     {
953         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
954         if (process == NULL)
955         {
956             result.AppendError ("must have a valid process in order to load a shared library");
957             result.SetStatus (eReturnStatusFailed);
958             return false;
959         }
960 
961         const uint32_t argc = command.GetArgumentCount();
962 
963         for (uint32_t i=0; i<argc; ++i)
964         {
965             Error error;
966             const char *image_path = command.GetArgumentAtIndex(i);
967             FileSpec image_spec (image_path, false);
968             uint32_t image_token = process->LoadImage(image_spec, error);
969             if (image_token != LLDB_INVALID_IMAGE_TOKEN)
970             {
971                 result.AppendMessageWithFormat ("Loading \"%s\"...ok\nImage %u loaded.\n", image_path, image_token);
972                 result.SetStatus (eReturnStatusSuccessFinishResult);
973             }
974             else
975             {
976                 result.AppendErrorWithFormat ("failed to load '%s': %s", image_path, error.AsCString());
977                 result.SetStatus (eReturnStatusFailed);
978             }
979         }
980         return result.Succeeded();
981     }
982 };
983 
984 
985 //-------------------------------------------------------------------------
986 // CommandObjectProcessUnload
987 //-------------------------------------------------------------------------
988 #pragma mark CommandObjectProcessUnload
989 
990 class CommandObjectProcessUnload : public CommandObject
991 {
992 public:
993 
994     CommandObjectProcessUnload (CommandInterpreter &interpreter) :
995         CommandObject (interpreter,
996                        "process unload",
997                        "Unload a shared library from the current process using the index returned by a previous call to \"process load\".",
998                        "process unload <index>",
999                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
1000     {
1001     }
1002 
1003     ~CommandObjectProcessUnload ()
1004     {
1005     }
1006 
1007     bool
1008     Execute (Args& command,
1009              CommandReturnObject &result)
1010     {
1011         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
1012         if (process == NULL)
1013         {
1014             result.AppendError ("must have a valid process in order to load a shared library");
1015             result.SetStatus (eReturnStatusFailed);
1016             return false;
1017         }
1018 
1019         const uint32_t argc = command.GetArgumentCount();
1020 
1021         for (uint32_t i=0; i<argc; ++i)
1022         {
1023             const char *image_token_cstr = command.GetArgumentAtIndex(i);
1024             uint32_t image_token = Args::StringToUInt32(image_token_cstr, LLDB_INVALID_IMAGE_TOKEN, 0);
1025             if (image_token == LLDB_INVALID_IMAGE_TOKEN)
1026             {
1027                 result.AppendErrorWithFormat ("invalid image index argument '%s'", image_token_cstr);
1028                 result.SetStatus (eReturnStatusFailed);
1029                 break;
1030             }
1031             else
1032             {
1033                 Error error (process->UnloadImage(image_token));
1034                 if (error.Success())
1035                 {
1036                     result.AppendMessageWithFormat ("Unloading shared library with index %u...ok\n", image_token);
1037                     result.SetStatus (eReturnStatusSuccessFinishResult);
1038                 }
1039                 else
1040                 {
1041                     result.AppendErrorWithFormat ("failed to unload image: %s", error.AsCString());
1042                     result.SetStatus (eReturnStatusFailed);
1043                     break;
1044                 }
1045             }
1046         }
1047         return result.Succeeded();
1048     }
1049 };
1050 
1051 //-------------------------------------------------------------------------
1052 // CommandObjectProcessSignal
1053 //-------------------------------------------------------------------------
1054 #pragma mark CommandObjectProcessSignal
1055 
1056 class CommandObjectProcessSignal : public CommandObject
1057 {
1058 public:
1059 
1060     CommandObjectProcessSignal (CommandInterpreter &interpreter) :
1061         CommandObject (interpreter,
1062                        "process signal",
1063                        "Send a UNIX signal to the current process being debugged.",
1064                        NULL)
1065     {
1066         CommandArgumentEntry arg;
1067         CommandArgumentData signal_arg;
1068 
1069         // Define the first (and only) variant of this arg.
1070         signal_arg.arg_type = eArgTypeUnixSignal;
1071         signal_arg.arg_repetition = eArgRepeatPlain;
1072 
1073         // There is only one variant this argument could be; put it into the argument entry.
1074         arg.push_back (signal_arg);
1075 
1076         // Push the data for the first argument into the m_arguments vector.
1077         m_arguments.push_back (arg);
1078     }
1079 
1080     ~CommandObjectProcessSignal ()
1081     {
1082     }
1083 
1084     bool
1085     Execute (Args& command,
1086              CommandReturnObject &result)
1087     {
1088         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
1089         if (process == NULL)
1090         {
1091             result.AppendError ("no process to signal");
1092             result.SetStatus (eReturnStatusFailed);
1093             return false;
1094         }
1095 
1096         if (command.GetArgumentCount() == 1)
1097         {
1098             int signo = LLDB_INVALID_SIGNAL_NUMBER;
1099 
1100             const char *signal_name = command.GetArgumentAtIndex(0);
1101             if (::isxdigit (signal_name[0]))
1102                 signo = Args::StringToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0);
1103             else
1104                 signo = process->GetUnixSignals().GetSignalNumberFromName (signal_name);
1105 
1106             if (signo == LLDB_INVALID_SIGNAL_NUMBER)
1107             {
1108                 result.AppendErrorWithFormat ("Invalid signal argument '%s'.\n", command.GetArgumentAtIndex(0));
1109                 result.SetStatus (eReturnStatusFailed);
1110             }
1111             else
1112             {
1113                 Error error (process->Signal (signo));
1114                 if (error.Success())
1115                 {
1116                     result.SetStatus (eReturnStatusSuccessFinishResult);
1117                 }
1118                 else
1119                 {
1120                     result.AppendErrorWithFormat ("Failed to send signal %i: %s\n", signo, error.AsCString());
1121                     result.SetStatus (eReturnStatusFailed);
1122                 }
1123             }
1124         }
1125         else
1126         {
1127             result.AppendErrorWithFormat("'%s' takes exactly one signal number argument:\nUsage: \n", m_cmd_name.c_str(),
1128                                         m_cmd_syntax.c_str());
1129             result.SetStatus (eReturnStatusFailed);
1130         }
1131         return result.Succeeded();
1132     }
1133 };
1134 
1135 
1136 //-------------------------------------------------------------------------
1137 // CommandObjectProcessInterrupt
1138 //-------------------------------------------------------------------------
1139 #pragma mark CommandObjectProcessInterrupt
1140 
1141 class CommandObjectProcessInterrupt : public CommandObject
1142 {
1143 public:
1144 
1145 
1146     CommandObjectProcessInterrupt (CommandInterpreter &interpreter) :
1147     CommandObject (interpreter,
1148                    "process interrupt",
1149                    "Interrupt the current process being debugged.",
1150                    "process interrupt",
1151                    eFlagProcessMustBeLaunched)
1152     {
1153     }
1154 
1155     ~CommandObjectProcessInterrupt ()
1156     {
1157     }
1158 
1159     bool
1160     Execute (Args& command,
1161              CommandReturnObject &result)
1162     {
1163         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
1164         if (process == NULL)
1165         {
1166             result.AppendError ("no process to halt");
1167             result.SetStatus (eReturnStatusFailed);
1168             return false;
1169         }
1170 
1171         if (command.GetArgumentCount() == 0)
1172         {
1173             Error error(process->Halt ());
1174             if (error.Success())
1175             {
1176                 result.SetStatus (eReturnStatusSuccessFinishResult);
1177 
1178                 // Maybe we should add a "SuspendThreadPlans so we
1179                 // can halt, and keep in place all the current thread plans.
1180                 process->GetThreadList().DiscardThreadPlans();
1181             }
1182             else
1183             {
1184                 result.AppendErrorWithFormat ("Failed to halt process: %s\n", error.AsCString());
1185                 result.SetStatus (eReturnStatusFailed);
1186             }
1187         }
1188         else
1189         {
1190             result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: \n",
1191                                         m_cmd_name.c_str(),
1192                                         m_cmd_syntax.c_str());
1193             result.SetStatus (eReturnStatusFailed);
1194         }
1195         return result.Succeeded();
1196     }
1197 };
1198 
1199 //-------------------------------------------------------------------------
1200 // CommandObjectProcessKill
1201 //-------------------------------------------------------------------------
1202 #pragma mark CommandObjectProcessKill
1203 
1204 class CommandObjectProcessKill : public CommandObject
1205 {
1206 public:
1207 
1208     CommandObjectProcessKill (CommandInterpreter &interpreter) :
1209     CommandObject (interpreter,
1210                    "process kill",
1211                    "Terminate the current process being debugged.",
1212                    "process kill",
1213                    eFlagProcessMustBeLaunched)
1214     {
1215     }
1216 
1217     ~CommandObjectProcessKill ()
1218     {
1219     }
1220 
1221     bool
1222     Execute (Args& command,
1223              CommandReturnObject &result)
1224     {
1225         Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
1226         if (process == NULL)
1227         {
1228             result.AppendError ("no process to kill");
1229             result.SetStatus (eReturnStatusFailed);
1230             return false;
1231         }
1232 
1233         if (command.GetArgumentCount() == 0)
1234         {
1235             Error error (process->Destroy());
1236             if (error.Success())
1237             {
1238                 result.SetStatus (eReturnStatusSuccessFinishResult);
1239             }
1240             else
1241             {
1242                 result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString());
1243                 result.SetStatus (eReturnStatusFailed);
1244             }
1245         }
1246         else
1247         {
1248             result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: \n",
1249                                         m_cmd_name.c_str(),
1250                                         m_cmd_syntax.c_str());
1251             result.SetStatus (eReturnStatusFailed);
1252         }
1253         return result.Succeeded();
1254     }
1255 };
1256 
1257 //-------------------------------------------------------------------------
1258 // CommandObjectProcessStatus
1259 //-------------------------------------------------------------------------
1260 #pragma mark CommandObjectProcessStatus
1261 
1262 class CommandObjectProcessStatus : public CommandObject
1263 {
1264 public:
1265     CommandObjectProcessStatus (CommandInterpreter &interpreter) :
1266     CommandObject (interpreter,
1267                    "process status",
1268                    "Show the current status and location of executing process.",
1269                    "process status",
1270                    0)
1271     {
1272     }
1273 
1274     ~CommandObjectProcessStatus()
1275     {
1276     }
1277 
1278 
1279     bool
1280     Execute
1281     (
1282         Args& command,
1283         CommandReturnObject &result
1284     )
1285     {
1286         StreamString &output_stream = result.GetOutputStream();
1287         result.SetStatus (eReturnStatusSuccessFinishNoResult);
1288         ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext());
1289         if (exe_ctx.process)
1290         {
1291             const StateType state = exe_ctx.process->GetState();
1292             if (StateIsStoppedState(state))
1293             {
1294                 if (state == eStateExited)
1295                 {
1296                     int exit_status = exe_ctx.process->GetExitStatus();
1297                     const char *exit_description = exe_ctx.process->GetExitDescription();
1298                     output_stream.Printf ("Process %d exited with status = %i (0x%8.8x) %s\n",
1299                                           exe_ctx.process->GetID(),
1300                                           exit_status,
1301                                           exit_status,
1302                                           exit_description ? exit_description : "");
1303                 }
1304                 else
1305                 {
1306                     output_stream.Printf ("Process %d %s\n", exe_ctx.process->GetID(), StateAsCString (state));
1307                     if (exe_ctx.thread == NULL)
1308                         exe_ctx.thread = exe_ctx.process->GetThreadList().GetThreadAtIndex(0).get();
1309                     if (exe_ctx.thread != NULL)
1310                     {
1311                         DisplayThreadsInfo (m_interpreter, &exe_ctx, result, true, true);
1312                     }
1313                     else
1314                     {
1315                         result.AppendError ("No valid thread found in current process.");
1316                         result.SetStatus (eReturnStatusFailed);
1317                     }
1318                 }
1319             }
1320             else
1321             {
1322                 output_stream.Printf ("Process %d is running.\n",
1323                                           exe_ctx.process->GetID());
1324             }
1325         }
1326         else
1327         {
1328             result.AppendError ("No current location or status available.");
1329             result.SetStatus (eReturnStatusFailed);
1330         }
1331         return result.Succeeded();
1332     }
1333 };
1334 
1335 //-------------------------------------------------------------------------
1336 // CommandObjectProcessHandle
1337 //-------------------------------------------------------------------------
1338 #pragma mark CommandObjectProcessHandle
1339 
1340 class CommandObjectProcessHandle : public CommandObject
1341 {
1342 public:
1343 
1344     class CommandOptions : public Options
1345     {
1346     public:
1347 
1348         CommandOptions () :
1349             Options ()
1350         {
1351             ResetOptionValues ();
1352         }
1353 
1354         ~CommandOptions ()
1355         {
1356         }
1357 
1358         Error
1359         SetOptionValue (int option_idx, const char *option_arg)
1360         {
1361             Error error;
1362             char short_option = (char) m_getopt_table[option_idx].val;
1363 
1364             switch (short_option)
1365             {
1366                 case 's':
1367                     stop = option_arg;
1368                     break;
1369                 case 'n':
1370                     notify = option_arg;
1371                     break;
1372                 case 'p':
1373                     pass = option_arg;
1374                     break;
1375                 default:
1376                     error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
1377                     break;
1378             }
1379             return error;
1380         }
1381 
1382         void
1383         ResetOptionValues ()
1384         {
1385             Options::ResetOptionValues();
1386             stop.clear();
1387             notify.clear();
1388             pass.clear();
1389         }
1390 
1391         const lldb::OptionDefinition*
1392         GetDefinitions ()
1393         {
1394             return g_option_table;
1395         }
1396 
1397         // Options table: Required for subclasses of Options.
1398 
1399         static lldb::OptionDefinition g_option_table[];
1400 
1401         // Instance variables to hold the values for command options.
1402 
1403         std::string stop;
1404         std::string notify;
1405         std::string pass;
1406     };
1407 
1408 
1409     CommandObjectProcessHandle (CommandInterpreter &interpreter) :
1410         CommandObject (interpreter,
1411                        "process handle",
1412                        "Show or update what the process and debugger should do with various signals received from the OS.",
1413                        NULL)
1414     {
1415         SetHelpLong ("If no signals are specified, update them all.  If no update option is specified, list the current values.\n");
1416         CommandArgumentEntry arg;
1417         CommandArgumentData signal_arg;
1418 
1419         signal_arg.arg_type = eArgTypeUnixSignal;
1420         signal_arg.arg_repetition = eArgRepeatStar;
1421 
1422         arg.push_back (signal_arg);
1423 
1424         m_arguments.push_back (arg);
1425     }
1426 
1427     ~CommandObjectProcessHandle ()
1428     {
1429     }
1430 
1431     Options *
1432     GetOptions ()
1433     {
1434         return &m_options;
1435     }
1436 
1437     bool
1438     VerifyCommandOptionValue (const std::string &option, int &real_value)
1439     {
1440         bool okay = true;
1441 
1442         bool success = false;
1443         bool tmp_value = Args::StringToBoolean (option.c_str(), false, &success);
1444 
1445         if (success && tmp_value)
1446             real_value = 1;
1447         else if (success && !tmp_value)
1448             real_value = 0;
1449         else
1450         {
1451             // If the value isn't 'true' or 'false', it had better be 0 or 1.
1452             real_value = Args::StringToUInt32 (option.c_str(), 3);
1453             if (real_value != 0 && real_value != 1)
1454                 okay = false;
1455         }
1456 
1457         return okay;
1458     }
1459 
1460     void
1461     PrintSignalHeader (Stream &str)
1462     {
1463         str.Printf ("NAME        PASS   STOP   NOTIFY\n");
1464         str.Printf ("==========  =====  =====  ======\n");
1465     }
1466 
1467     void
1468     PrintSignal (Stream &str, int32_t signo, const char *sig_name, UnixSignals &signals)
1469     {
1470         bool stop;
1471         bool suppress;
1472         bool notify;
1473 
1474         str.Printf ("%-10s  ", sig_name);
1475         if (signals.GetSignalInfo (signo, suppress, stop, notify))
1476         {
1477             bool pass = !suppress;
1478             str.Printf ("%s  %s  %s",
1479                         (pass ? "true " : "false"),
1480                         (stop ? "true " : "false"),
1481                         (notify ? "true " : "false"));
1482         }
1483         str.Printf ("\n");
1484     }
1485 
1486     void
1487     PrintSignalInformation (Stream &str, Args &signal_args, int num_valid_signals, UnixSignals &signals)
1488     {
1489         PrintSignalHeader (str);
1490 
1491         if (num_valid_signals > 0)
1492         {
1493             size_t num_args = signal_args.GetArgumentCount();
1494             for (size_t i = 0; i < num_args; ++i)
1495             {
1496                 int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i));
1497                 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
1498                     PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals);
1499             }
1500         }
1501         else // Print info for ALL signals
1502         {
1503             int32_t signo = signals.GetFirstSignalNumber();
1504             while (signo != LLDB_INVALID_SIGNAL_NUMBER)
1505             {
1506                 PrintSignal (str, signo, signals.GetSignalAsCString (signo), signals);
1507                 signo = signals.GetNextSignalNumber (signo);
1508             }
1509         }
1510     }
1511 
1512     bool
1513     Execute (Args &signal_args, CommandReturnObject &result)
1514     {
1515         TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
1516 
1517         if (!target_sp)
1518         {
1519             result.AppendError ("No current target;"
1520                                 " cannot handle signals until you have a valid target and process.\n");
1521             result.SetStatus (eReturnStatusFailed);
1522             return false;
1523         }
1524 
1525         ProcessSP process_sp = target_sp->GetProcessSP();
1526 
1527         if (!process_sp)
1528         {
1529             result.AppendError ("No current process; cannot handle signals until you have a valid process.\n");
1530             result.SetStatus (eReturnStatusFailed);
1531             return false;
1532         }
1533 
1534         int stop_action = -1;   // -1 means leave the current setting alone
1535         int pass_action = -1;   // -1 means leave the current setting alone
1536         int notify_action = -1; // -1 means leave the current setting alone
1537 
1538         if (! m_options.stop.empty()
1539             && ! VerifyCommandOptionValue (m_options.stop, stop_action))
1540         {
1541             result.AppendError ("Invalid argument for command option --stop; must be true or false.\n");
1542             result.SetStatus (eReturnStatusFailed);
1543             return false;
1544         }
1545 
1546         if (! m_options.notify.empty()
1547             && ! VerifyCommandOptionValue (m_options.notify, notify_action))
1548         {
1549             result.AppendError ("Invalid argument for command option --notify; must be true or false.\n");
1550             result.SetStatus (eReturnStatusFailed);
1551             return false;
1552         }
1553 
1554         if (! m_options.pass.empty()
1555             && ! VerifyCommandOptionValue (m_options.pass, pass_action))
1556         {
1557             result.AppendError ("Invalid argument for command option --pass; must be true or false.\n");
1558             result.SetStatus (eReturnStatusFailed);
1559             return false;
1560         }
1561 
1562         size_t num_args = signal_args.GetArgumentCount();
1563         UnixSignals &signals = process_sp->GetUnixSignals();
1564         int num_signals_set = 0;
1565 
1566         if (num_args > 0)
1567         {
1568             for (size_t i = 0; i < num_args; ++i)
1569             {
1570                 int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i));
1571                 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
1572                 {
1573                     // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees
1574                     // the value is either 0 or 1.
1575                     if (stop_action != -1)
1576                         signals.SetShouldStop (signo, (bool) stop_action);
1577                     if (pass_action != -1)
1578                     {
1579                         bool suppress = ! ((bool) pass_action);
1580                         signals.SetShouldSuppress (signo, suppress);
1581                     }
1582                     if (notify_action != -1)
1583                         signals.SetShouldNotify (signo, (bool) notify_action);
1584                     ++num_signals_set;
1585                 }
1586                 else
1587                 {
1588                     result.AppendErrorWithFormat ("Invalid signal name '%s'\n", signal_args.GetArgumentAtIndex (i));
1589                 }
1590             }
1591         }
1592         else
1593         {
1594             // No signal specified, if any command options were specified, update ALL signals.
1595             if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1))
1596             {
1597                 if (m_interpreter.Confirm ("Do you really want to update all the signals?", false))
1598                 {
1599                     int32_t signo = signals.GetFirstSignalNumber();
1600                     while (signo != LLDB_INVALID_SIGNAL_NUMBER)
1601                     {
1602                         if (notify_action != -1)
1603                             signals.SetShouldNotify (signo, (bool) notify_action);
1604                         if (stop_action != -1)
1605                             signals.SetShouldStop (signo, (bool) stop_action);
1606                         if (pass_action != -1)
1607                         {
1608                             bool suppress = ! ((bool) pass_action);
1609                             signals.SetShouldSuppress (signo, suppress);
1610                         }
1611                         signo = signals.GetNextSignalNumber (signo);
1612                     }
1613                 }
1614             }
1615         }
1616 
1617         PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals);
1618 
1619         if (num_signals_set > 0)
1620             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1621         else
1622             result.SetStatus (eReturnStatusFailed);
1623 
1624         return result.Succeeded();
1625     }
1626 
1627 protected:
1628 
1629     CommandOptions m_options;
1630 };
1631 
1632 lldb::OptionDefinition
1633 CommandObjectProcessHandle::CommandOptions::g_option_table[] =
1634 {
1635 { 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." },
1636 { 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." },
1637 { LLDB_OPT_SET_1, false, "pass",  'p', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." },
1638 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1639 };
1640 
1641 //-------------------------------------------------------------------------
1642 // CommandObjectMultiwordProcess
1643 //-------------------------------------------------------------------------
1644 
1645 CommandObjectMultiwordProcess::CommandObjectMultiwordProcess (CommandInterpreter &interpreter) :
1646     CommandObjectMultiword (interpreter,
1647                             "process",
1648                             "A set of commands for operating on a process.",
1649                             "process <subcommand> [<subcommand-options>]")
1650 {
1651     LoadSubCommand ("attach",      CommandObjectSP (new CommandObjectProcessAttach (interpreter)));
1652     LoadSubCommand ("launch",      CommandObjectSP (new CommandObjectProcessLaunch (interpreter)));
1653     LoadSubCommand ("continue",    CommandObjectSP (new CommandObjectProcessContinue (interpreter)));
1654     LoadSubCommand ("detach",      CommandObjectSP (new CommandObjectProcessDetach (interpreter)));
1655     LoadSubCommand ("load",        CommandObjectSP (new CommandObjectProcessLoad (interpreter)));
1656     LoadSubCommand ("unload",      CommandObjectSP (new CommandObjectProcessUnload (interpreter)));
1657     LoadSubCommand ("signal",      CommandObjectSP (new CommandObjectProcessSignal (interpreter)));
1658     LoadSubCommand ("handle",      CommandObjectSP (new CommandObjectProcessHandle (interpreter)));
1659     LoadSubCommand ("status",      CommandObjectSP (new CommandObjectProcessStatus (interpreter)));
1660     LoadSubCommand ("interrupt",   CommandObjectSP (new CommandObjectProcessInterrupt (interpreter)));
1661     LoadSubCommand ("kill",        CommandObjectSP (new CommandObjectProcessKill (interpreter)));
1662 }
1663 
1664 CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess ()
1665 {
1666 }
1667 
1668