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