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