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