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