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