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