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