xref: /llvm-project/lldb/source/Commands/CommandObjectProcess.cpp (revision 7260f6206f4f38273b5bef39361543c7245c99dd)
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, set executable file using 'file' 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->GetExecutableModule().get();
166 
167         if (exe_module == NULL)
168         {
169             result.AppendError ("no file in target, set executable file using 'file' 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             if (!old_exec_module_sp)
766             {
767                 // We might not have a module if we attached to a raw pid...
768                 ModuleSP new_module_sp (target->GetExecutableModule());
769                 if (new_module_sp)
770                 {
771                     new_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() != target->GetExecutableModule()->GetFileSpec())
776             {
777                 char old_path[PATH_MAX];
778 
779                 old_exec_module_sp->GetFileSpec().GetPath(old_path, PATH_MAX);
780                 target->GetExecutableModule()->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             uint32_t image_token = process->LoadImage(image_spec, error);
1176             if (image_token != LLDB_INVALID_IMAGE_TOKEN)
1177             {
1178                 result.AppendMessageWithFormat ("Loading \"%s\"...ok\nImage %u loaded.\n", image_path, image_token);
1179                 result.SetStatus (eReturnStatusSuccessFinishResult);
1180             }
1181             else
1182             {
1183                 result.AppendErrorWithFormat ("failed to load '%s': %s", image_path, error.AsCString());
1184                 result.SetStatus (eReturnStatusFailed);
1185             }
1186         }
1187         return result.Succeeded();
1188     }
1189 };
1190 
1191 
1192 //-------------------------------------------------------------------------
1193 // CommandObjectProcessUnload
1194 //-------------------------------------------------------------------------
1195 #pragma mark CommandObjectProcessUnload
1196 
1197 class CommandObjectProcessUnload : public CommandObject
1198 {
1199 public:
1200 
1201     CommandObjectProcessUnload (CommandInterpreter &interpreter) :
1202         CommandObject (interpreter,
1203                        "process unload",
1204                        "Unload a shared library from the current process using the index returned by a previous call to \"process load\".",
1205                        "process unload <index>",
1206                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
1207     {
1208     }
1209 
1210     ~CommandObjectProcessUnload ()
1211     {
1212     }
1213 
1214     bool
1215     Execute (Args& command,
1216              CommandReturnObject &result)
1217     {
1218         Process *process = m_interpreter.GetExecutionContext().process;
1219         if (process == NULL)
1220         {
1221             result.AppendError ("must have a valid process in order to load a shared library");
1222             result.SetStatus (eReturnStatusFailed);
1223             return false;
1224         }
1225 
1226         const uint32_t argc = command.GetArgumentCount();
1227 
1228         for (uint32_t i=0; i<argc; ++i)
1229         {
1230             const char *image_token_cstr = command.GetArgumentAtIndex(i);
1231             uint32_t image_token = Args::StringToUInt32(image_token_cstr, LLDB_INVALID_IMAGE_TOKEN, 0);
1232             if (image_token == LLDB_INVALID_IMAGE_TOKEN)
1233             {
1234                 result.AppendErrorWithFormat ("invalid image index argument '%s'", image_token_cstr);
1235                 result.SetStatus (eReturnStatusFailed);
1236                 break;
1237             }
1238             else
1239             {
1240                 Error error (process->UnloadImage(image_token));
1241                 if (error.Success())
1242                 {
1243                     result.AppendMessageWithFormat ("Unloading shared library with index %u...ok\n", image_token);
1244                     result.SetStatus (eReturnStatusSuccessFinishResult);
1245                 }
1246                 else
1247                 {
1248                     result.AppendErrorWithFormat ("failed to unload image: %s", error.AsCString());
1249                     result.SetStatus (eReturnStatusFailed);
1250                     break;
1251                 }
1252             }
1253         }
1254         return result.Succeeded();
1255     }
1256 };
1257 
1258 //-------------------------------------------------------------------------
1259 // CommandObjectProcessSignal
1260 //-------------------------------------------------------------------------
1261 #pragma mark CommandObjectProcessSignal
1262 
1263 class CommandObjectProcessSignal : public CommandObject
1264 {
1265 public:
1266 
1267     CommandObjectProcessSignal (CommandInterpreter &interpreter) :
1268         CommandObject (interpreter,
1269                        "process signal",
1270                        "Send a UNIX signal to the current process being debugged.",
1271                        NULL)
1272     {
1273         CommandArgumentEntry arg;
1274         CommandArgumentData signal_arg;
1275 
1276         // Define the first (and only) variant of this arg.
1277         signal_arg.arg_type = eArgTypeUnixSignal;
1278         signal_arg.arg_repetition = eArgRepeatPlain;
1279 
1280         // There is only one variant this argument could be; put it into the argument entry.
1281         arg.push_back (signal_arg);
1282 
1283         // Push the data for the first argument into the m_arguments vector.
1284         m_arguments.push_back (arg);
1285     }
1286 
1287     ~CommandObjectProcessSignal ()
1288     {
1289     }
1290 
1291     bool
1292     Execute (Args& command,
1293              CommandReturnObject &result)
1294     {
1295         Process *process = m_interpreter.GetExecutionContext().process;
1296         if (process == NULL)
1297         {
1298             result.AppendError ("no process to signal");
1299             result.SetStatus (eReturnStatusFailed);
1300             return false;
1301         }
1302 
1303         if (command.GetArgumentCount() == 1)
1304         {
1305             int signo = LLDB_INVALID_SIGNAL_NUMBER;
1306 
1307             const char *signal_name = command.GetArgumentAtIndex(0);
1308             if (::isxdigit (signal_name[0]))
1309                 signo = Args::StringToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0);
1310             else
1311                 signo = process->GetUnixSignals().GetSignalNumberFromName (signal_name);
1312 
1313             if (signo == LLDB_INVALID_SIGNAL_NUMBER)
1314             {
1315                 result.AppendErrorWithFormat ("Invalid signal argument '%s'.\n", command.GetArgumentAtIndex(0));
1316                 result.SetStatus (eReturnStatusFailed);
1317             }
1318             else
1319             {
1320                 Error error (process->Signal (signo));
1321                 if (error.Success())
1322                 {
1323                     result.SetStatus (eReturnStatusSuccessFinishResult);
1324                 }
1325                 else
1326                 {
1327                     result.AppendErrorWithFormat ("Failed to send signal %i: %s\n", signo, error.AsCString());
1328                     result.SetStatus (eReturnStatusFailed);
1329                 }
1330             }
1331         }
1332         else
1333         {
1334             result.AppendErrorWithFormat("'%s' takes exactly one signal number argument:\nUsage: \n", m_cmd_name.c_str(),
1335                                         m_cmd_syntax.c_str());
1336             result.SetStatus (eReturnStatusFailed);
1337         }
1338         return result.Succeeded();
1339     }
1340 };
1341 
1342 
1343 //-------------------------------------------------------------------------
1344 // CommandObjectProcessInterrupt
1345 //-------------------------------------------------------------------------
1346 #pragma mark CommandObjectProcessInterrupt
1347 
1348 class CommandObjectProcessInterrupt : public CommandObject
1349 {
1350 public:
1351 
1352 
1353     CommandObjectProcessInterrupt (CommandInterpreter &interpreter) :
1354     CommandObject (interpreter,
1355                    "process interrupt",
1356                    "Interrupt the current process being debugged.",
1357                    "process interrupt",
1358                    eFlagProcessMustBeLaunched)
1359     {
1360     }
1361 
1362     ~CommandObjectProcessInterrupt ()
1363     {
1364     }
1365 
1366     bool
1367     Execute (Args& command,
1368              CommandReturnObject &result)
1369     {
1370         Process *process = m_interpreter.GetExecutionContext().process;
1371         if (process == NULL)
1372         {
1373             result.AppendError ("no process to halt");
1374             result.SetStatus (eReturnStatusFailed);
1375             return false;
1376         }
1377 
1378         if (command.GetArgumentCount() == 0)
1379         {
1380             Error error(process->Halt ());
1381             if (error.Success())
1382             {
1383                 result.SetStatus (eReturnStatusSuccessFinishResult);
1384 
1385                 // Maybe we should add a "SuspendThreadPlans so we
1386                 // can halt, and keep in place all the current thread plans.
1387                 process->GetThreadList().DiscardThreadPlans();
1388             }
1389             else
1390             {
1391                 result.AppendErrorWithFormat ("Failed to halt process: %s\n", error.AsCString());
1392                 result.SetStatus (eReturnStatusFailed);
1393             }
1394         }
1395         else
1396         {
1397             result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: \n",
1398                                         m_cmd_name.c_str(),
1399                                         m_cmd_syntax.c_str());
1400             result.SetStatus (eReturnStatusFailed);
1401         }
1402         return result.Succeeded();
1403     }
1404 };
1405 
1406 //-------------------------------------------------------------------------
1407 // CommandObjectProcessKill
1408 //-------------------------------------------------------------------------
1409 #pragma mark CommandObjectProcessKill
1410 
1411 class CommandObjectProcessKill : public CommandObject
1412 {
1413 public:
1414 
1415     CommandObjectProcessKill (CommandInterpreter &interpreter) :
1416     CommandObject (interpreter,
1417                    "process kill",
1418                    "Terminate the current process being debugged.",
1419                    "process kill",
1420                    eFlagProcessMustBeLaunched)
1421     {
1422     }
1423 
1424     ~CommandObjectProcessKill ()
1425     {
1426     }
1427 
1428     bool
1429     Execute (Args& command,
1430              CommandReturnObject &result)
1431     {
1432         Process *process = m_interpreter.GetExecutionContext().process;
1433         if (process == NULL)
1434         {
1435             result.AppendError ("no process to kill");
1436             result.SetStatus (eReturnStatusFailed);
1437             return false;
1438         }
1439 
1440         if (command.GetArgumentCount() == 0)
1441         {
1442             Error error (process->Destroy());
1443             if (error.Success())
1444             {
1445                 result.SetStatus (eReturnStatusSuccessFinishResult);
1446             }
1447             else
1448             {
1449                 result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString());
1450                 result.SetStatus (eReturnStatusFailed);
1451             }
1452         }
1453         else
1454         {
1455             result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: \n",
1456                                         m_cmd_name.c_str(),
1457                                         m_cmd_syntax.c_str());
1458             result.SetStatus (eReturnStatusFailed);
1459         }
1460         return result.Succeeded();
1461     }
1462 };
1463 
1464 //-------------------------------------------------------------------------
1465 // CommandObjectProcessStatus
1466 //-------------------------------------------------------------------------
1467 #pragma mark CommandObjectProcessStatus
1468 
1469 class CommandObjectProcessStatus : public CommandObject
1470 {
1471 public:
1472     CommandObjectProcessStatus (CommandInterpreter &interpreter) :
1473     CommandObject (interpreter,
1474                    "process status",
1475                    "Show the current status and location of executing process.",
1476                    "process status",
1477                    0)
1478     {
1479     }
1480 
1481     ~CommandObjectProcessStatus()
1482     {
1483     }
1484 
1485 
1486     bool
1487     Execute
1488     (
1489         Args& command,
1490         CommandReturnObject &result
1491     )
1492     {
1493         Stream &strm = result.GetOutputStream();
1494         result.SetStatus (eReturnStatusSuccessFinishNoResult);
1495         ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
1496         if (exe_ctx.process)
1497         {
1498             const bool only_threads_with_stop_reason = true;
1499             const uint32_t start_frame = 0;
1500             const uint32_t num_frames = 1;
1501             const uint32_t num_frames_with_source = 1;
1502             exe_ctx.process->GetStatus(strm);
1503             exe_ctx.process->GetThreadStatus (strm,
1504                                               only_threads_with_stop_reason,
1505                                               start_frame,
1506                                               num_frames,
1507                                               num_frames_with_source);
1508 
1509         }
1510         else
1511         {
1512             result.AppendError ("No process.");
1513             result.SetStatus (eReturnStatusFailed);
1514         }
1515         return result.Succeeded();
1516     }
1517 };
1518 
1519 //-------------------------------------------------------------------------
1520 // CommandObjectProcessHandle
1521 //-------------------------------------------------------------------------
1522 #pragma mark CommandObjectProcessHandle
1523 
1524 class CommandObjectProcessHandle : public CommandObject
1525 {
1526 public:
1527 
1528     class CommandOptions : public Options
1529     {
1530     public:
1531 
1532         CommandOptions (CommandInterpreter &interpreter) :
1533             Options (interpreter)
1534         {
1535             OptionParsingStarting ();
1536         }
1537 
1538         ~CommandOptions ()
1539         {
1540         }
1541 
1542         Error
1543         SetOptionValue (uint32_t option_idx, const char *option_arg)
1544         {
1545             Error error;
1546             char short_option = (char) m_getopt_table[option_idx].val;
1547 
1548             switch (short_option)
1549             {
1550                 case 's':
1551                     stop = option_arg;
1552                     break;
1553                 case 'n':
1554                     notify = option_arg;
1555                     break;
1556                 case 'p':
1557                     pass = option_arg;
1558                     break;
1559                 default:
1560                     error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
1561                     break;
1562             }
1563             return error;
1564         }
1565 
1566         void
1567         OptionParsingStarting ()
1568         {
1569             stop.clear();
1570             notify.clear();
1571             pass.clear();
1572         }
1573 
1574         const OptionDefinition*
1575         GetDefinitions ()
1576         {
1577             return g_option_table;
1578         }
1579 
1580         // Options table: Required for subclasses of Options.
1581 
1582         static OptionDefinition g_option_table[];
1583 
1584         // Instance variables to hold the values for command options.
1585 
1586         std::string stop;
1587         std::string notify;
1588         std::string pass;
1589     };
1590 
1591 
1592     CommandObjectProcessHandle (CommandInterpreter &interpreter) :
1593         CommandObject (interpreter,
1594                        "process handle",
1595                        "Show or update what the process and debugger should do with various signals received from the OS.",
1596                        NULL),
1597         m_options (interpreter)
1598     {
1599         SetHelpLong ("If no signals are specified, update them all.  If no update option is specified, list the current values.\n");
1600         CommandArgumentEntry arg;
1601         CommandArgumentData signal_arg;
1602 
1603         signal_arg.arg_type = eArgTypeUnixSignal;
1604         signal_arg.arg_repetition = eArgRepeatStar;
1605 
1606         arg.push_back (signal_arg);
1607 
1608         m_arguments.push_back (arg);
1609     }
1610 
1611     ~CommandObjectProcessHandle ()
1612     {
1613     }
1614 
1615     Options *
1616     GetOptions ()
1617     {
1618         return &m_options;
1619     }
1620 
1621     bool
1622     VerifyCommandOptionValue (const std::string &option, int &real_value)
1623     {
1624         bool okay = true;
1625 
1626         bool success = false;
1627         bool tmp_value = Args::StringToBoolean (option.c_str(), false, &success);
1628 
1629         if (success && tmp_value)
1630             real_value = 1;
1631         else if (success && !tmp_value)
1632             real_value = 0;
1633         else
1634         {
1635             // If the value isn't 'true' or 'false', it had better be 0 or 1.
1636             real_value = Args::StringToUInt32 (option.c_str(), 3);
1637             if (real_value != 0 && real_value != 1)
1638                 okay = false;
1639         }
1640 
1641         return okay;
1642     }
1643 
1644     void
1645     PrintSignalHeader (Stream &str)
1646     {
1647         str.Printf ("NAME        PASS   STOP   NOTIFY\n");
1648         str.Printf ("==========  =====  =====  ======\n");
1649     }
1650 
1651     void
1652     PrintSignal (Stream &str, int32_t signo, const char *sig_name, UnixSignals &signals)
1653     {
1654         bool stop;
1655         bool suppress;
1656         bool notify;
1657 
1658         str.Printf ("%-10s  ", sig_name);
1659         if (signals.GetSignalInfo (signo, suppress, stop, notify))
1660         {
1661             bool pass = !suppress;
1662             str.Printf ("%s  %s  %s",
1663                         (pass ? "true " : "false"),
1664                         (stop ? "true " : "false"),
1665                         (notify ? "true " : "false"));
1666         }
1667         str.Printf ("\n");
1668     }
1669 
1670     void
1671     PrintSignalInformation (Stream &str, Args &signal_args, int num_valid_signals, UnixSignals &signals)
1672     {
1673         PrintSignalHeader (str);
1674 
1675         if (num_valid_signals > 0)
1676         {
1677             size_t num_args = signal_args.GetArgumentCount();
1678             for (size_t i = 0; i < num_args; ++i)
1679             {
1680                 int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i));
1681                 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
1682                     PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals);
1683             }
1684         }
1685         else // Print info for ALL signals
1686         {
1687             int32_t signo = signals.GetFirstSignalNumber();
1688             while (signo != LLDB_INVALID_SIGNAL_NUMBER)
1689             {
1690                 PrintSignal (str, signo, signals.GetSignalAsCString (signo), signals);
1691                 signo = signals.GetNextSignalNumber (signo);
1692             }
1693         }
1694     }
1695 
1696     bool
1697     Execute (Args &signal_args, CommandReturnObject &result)
1698     {
1699         TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
1700 
1701         if (!target_sp)
1702         {
1703             result.AppendError ("No current target;"
1704                                 " cannot handle signals until you have a valid target and process.\n");
1705             result.SetStatus (eReturnStatusFailed);
1706             return false;
1707         }
1708 
1709         ProcessSP process_sp = target_sp->GetProcessSP();
1710 
1711         if (!process_sp)
1712         {
1713             result.AppendError ("No current process; cannot handle signals until you have a valid process.\n");
1714             result.SetStatus (eReturnStatusFailed);
1715             return false;
1716         }
1717 
1718         int stop_action = -1;   // -1 means leave the current setting alone
1719         int pass_action = -1;   // -1 means leave the current setting alone
1720         int notify_action = -1; // -1 means leave the current setting alone
1721 
1722         if (! m_options.stop.empty()
1723             && ! VerifyCommandOptionValue (m_options.stop, stop_action))
1724         {
1725             result.AppendError ("Invalid argument for command option --stop; must be true or false.\n");
1726             result.SetStatus (eReturnStatusFailed);
1727             return false;
1728         }
1729 
1730         if (! m_options.notify.empty()
1731             && ! VerifyCommandOptionValue (m_options.notify, notify_action))
1732         {
1733             result.AppendError ("Invalid argument for command option --notify; must be true or false.\n");
1734             result.SetStatus (eReturnStatusFailed);
1735             return false;
1736         }
1737 
1738         if (! m_options.pass.empty()
1739             && ! VerifyCommandOptionValue (m_options.pass, pass_action))
1740         {
1741             result.AppendError ("Invalid argument for command option --pass; must be true or false.\n");
1742             result.SetStatus (eReturnStatusFailed);
1743             return false;
1744         }
1745 
1746         size_t num_args = signal_args.GetArgumentCount();
1747         UnixSignals &signals = process_sp->GetUnixSignals();
1748         int num_signals_set = 0;
1749 
1750         if (num_args > 0)
1751         {
1752             for (size_t i = 0; i < num_args; ++i)
1753             {
1754                 int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i));
1755                 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
1756                 {
1757                     // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees
1758                     // the value is either 0 or 1.
1759                     if (stop_action != -1)
1760                         signals.SetShouldStop (signo, (bool) stop_action);
1761                     if (pass_action != -1)
1762                     {
1763                         bool suppress = ! ((bool) pass_action);
1764                         signals.SetShouldSuppress (signo, suppress);
1765                     }
1766                     if (notify_action != -1)
1767                         signals.SetShouldNotify (signo, (bool) notify_action);
1768                     ++num_signals_set;
1769                 }
1770                 else
1771                 {
1772                     result.AppendErrorWithFormat ("Invalid signal name '%s'\n", signal_args.GetArgumentAtIndex (i));
1773                 }
1774             }
1775         }
1776         else
1777         {
1778             // No signal specified, if any command options were specified, update ALL signals.
1779             if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1))
1780             {
1781                 if (m_interpreter.Confirm ("Do you really want to update all the signals?", false))
1782                 {
1783                     int32_t signo = signals.GetFirstSignalNumber();
1784                     while (signo != LLDB_INVALID_SIGNAL_NUMBER)
1785                     {
1786                         if (notify_action != -1)
1787                             signals.SetShouldNotify (signo, (bool) notify_action);
1788                         if (stop_action != -1)
1789                             signals.SetShouldStop (signo, (bool) stop_action);
1790                         if (pass_action != -1)
1791                         {
1792                             bool suppress = ! ((bool) pass_action);
1793                             signals.SetShouldSuppress (signo, suppress);
1794                         }
1795                         signo = signals.GetNextSignalNumber (signo);
1796                     }
1797                 }
1798             }
1799         }
1800 
1801         PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals);
1802 
1803         if (num_signals_set > 0)
1804             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1805         else
1806             result.SetStatus (eReturnStatusFailed);
1807 
1808         return result.Succeeded();
1809     }
1810 
1811 protected:
1812 
1813     CommandOptions m_options;
1814 };
1815 
1816 OptionDefinition
1817 CommandObjectProcessHandle::CommandOptions::g_option_table[] =
1818 {
1819 { 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." },
1820 { 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." },
1821 { LLDB_OPT_SET_1, false, "pass",  'p', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." },
1822 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1823 };
1824 
1825 //-------------------------------------------------------------------------
1826 // CommandObjectMultiwordProcess
1827 //-------------------------------------------------------------------------
1828 
1829 CommandObjectMultiwordProcess::CommandObjectMultiwordProcess (CommandInterpreter &interpreter) :
1830     CommandObjectMultiword (interpreter,
1831                             "process",
1832                             "A set of commands for operating on a process.",
1833                             "process <subcommand> [<subcommand-options>]")
1834 {
1835     LoadSubCommand ("attach",      CommandObjectSP (new CommandObjectProcessAttach (interpreter)));
1836     LoadSubCommand ("launch",      CommandObjectSP (new CommandObjectProcessLaunch (interpreter)));
1837     LoadSubCommand ("continue",    CommandObjectSP (new CommandObjectProcessContinue (interpreter)));
1838     LoadSubCommand ("connect",     CommandObjectSP (new CommandObjectProcessConnect (interpreter)));
1839     LoadSubCommand ("detach",      CommandObjectSP (new CommandObjectProcessDetach (interpreter)));
1840     LoadSubCommand ("load",        CommandObjectSP (new CommandObjectProcessLoad (interpreter)));
1841     LoadSubCommand ("unload",      CommandObjectSP (new CommandObjectProcessUnload (interpreter)));
1842     LoadSubCommand ("signal",      CommandObjectSP (new CommandObjectProcessSignal (interpreter)));
1843     LoadSubCommand ("handle",      CommandObjectSP (new CommandObjectProcessHandle (interpreter)));
1844     LoadSubCommand ("status",      CommandObjectSP (new CommandObjectProcessStatus (interpreter)));
1845     LoadSubCommand ("interrupt",   CommandObjectSP (new CommandObjectProcessInterrupt (interpreter)));
1846     LoadSubCommand ("kill",        CommandObjectSP (new CommandObjectProcessKill (interpreter)));
1847 }
1848 
1849 CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess ()
1850 {
1851 }
1852 
1853