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