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