1254721Semaste//===-- CommandObjectProcess.cpp --------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include "lldb/lldb-python.h"
11254721Semaste
12254721Semaste#include "CommandObjectProcess.h"
13254721Semaste
14254721Semaste// C Includes
15254721Semaste// C++ Includes
16254721Semaste// Other libraries and framework includes
17254721Semaste// Project includes
18254721Semaste#include "lldb/Breakpoint/Breakpoint.h"
19254721Semaste#include "lldb/Breakpoint/BreakpointLocation.h"
20254721Semaste#include "lldb/Breakpoint/BreakpointSite.h"
21254721Semaste#include "lldb/Core/State.h"
22254721Semaste#include "lldb/Core/Module.h"
23254721Semaste#include "lldb/Host/Host.h"
24254721Semaste#include "lldb/Interpreter/Args.h"
25254721Semaste#include "lldb/Interpreter/Options.h"
26254721Semaste#include "lldb/Interpreter/CommandInterpreter.h"
27254721Semaste#include "lldb/Interpreter/CommandReturnObject.h"
28254721Semaste#include "lldb/Target/Platform.h"
29254721Semaste#include "lldb/Target/Process.h"
30254721Semaste#include "lldb/Target/StopInfo.h"
31254721Semaste#include "lldb/Target/Target.h"
32254721Semaste#include "lldb/Target/Thread.h"
33254721Semaste
34254721Semasteusing namespace lldb;
35254721Semasteusing namespace lldb_private;
36254721Semaste
37254721Semasteclass CommandObjectProcessLaunchOrAttach : public CommandObjectParsed
38254721Semaste{
39254721Semastepublic:
40254721Semaste    CommandObjectProcessLaunchOrAttach (CommandInterpreter &interpreter,
41254721Semaste                                       const char *name,
42254721Semaste                                       const char *help,
43254721Semaste                                       const char *syntax,
44254721Semaste                                       uint32_t flags,
45254721Semaste                                       const char *new_process_action) :
46254721Semaste        CommandObjectParsed (interpreter, name, help, syntax, flags),
47254721Semaste        m_new_process_action (new_process_action) {}
48254721Semaste
49254721Semaste    virtual ~CommandObjectProcessLaunchOrAttach () {}
50254721Semasteprotected:
51254721Semaste    bool
52254721Semaste    StopProcessIfNecessary (Process *&process, StateType &state, CommandReturnObject &result)
53254721Semaste    {
54254721Semaste        state = eStateInvalid;
55254721Semaste        if (process)
56254721Semaste        {
57254721Semaste            state = process->GetState();
58254721Semaste
59254721Semaste            if (process->IsAlive() && state != eStateConnected)
60254721Semaste            {
61254721Semaste                char message[1024];
62254721Semaste                if (process->GetState() == eStateAttaching)
63254721Semaste                    ::snprintf (message, sizeof(message), "There is a pending attach, abort it and %s?", m_new_process_action.c_str());
64254721Semaste                else if (process->GetShouldDetach())
65254721Semaste                    ::snprintf (message, sizeof(message), "There is a running process, detach from it and %s?", m_new_process_action.c_str());
66254721Semaste                else
67254721Semaste                    ::snprintf (message, sizeof(message), "There is a running process, kill it and %s?", m_new_process_action.c_str());
68254721Semaste
69254721Semaste                if (!m_interpreter.Confirm (message, true))
70254721Semaste                {
71254721Semaste                    result.SetStatus (eReturnStatusFailed);
72254721Semaste                    return false;
73254721Semaste                }
74254721Semaste                else
75254721Semaste                {
76254721Semaste                    if (process->GetShouldDetach())
77254721Semaste                    {
78254721Semaste                        bool keep_stopped = false;
79254721Semaste                        Error detach_error (process->Detach(keep_stopped));
80254721Semaste                        if (detach_error.Success())
81254721Semaste                        {
82254721Semaste                            result.SetStatus (eReturnStatusSuccessFinishResult);
83254721Semaste                            process = NULL;
84254721Semaste                        }
85254721Semaste                        else
86254721Semaste                        {
87254721Semaste                            result.AppendErrorWithFormat ("Failed to detach from process: %s\n", detach_error.AsCString());
88254721Semaste                            result.SetStatus (eReturnStatusFailed);
89254721Semaste                        }
90254721Semaste                    }
91254721Semaste                    else
92254721Semaste                    {
93254721Semaste                        Error destroy_error (process->Destroy());
94254721Semaste                        if (destroy_error.Success())
95254721Semaste                        {
96254721Semaste                            result.SetStatus (eReturnStatusSuccessFinishResult);
97254721Semaste                            process = NULL;
98254721Semaste                        }
99254721Semaste                        else
100254721Semaste                        {
101254721Semaste                            result.AppendErrorWithFormat ("Failed to kill process: %s\n", destroy_error.AsCString());
102254721Semaste                            result.SetStatus (eReturnStatusFailed);
103254721Semaste                        }
104254721Semaste                    }
105254721Semaste                }
106254721Semaste            }
107254721Semaste        }
108254721Semaste        return result.Succeeded();
109254721Semaste    }
110254721Semaste    std::string m_new_process_action;
111254721Semaste};
112254721Semaste//-------------------------------------------------------------------------
113254721Semaste// CommandObjectProcessLaunch
114254721Semaste//-------------------------------------------------------------------------
115254721Semaste#pragma mark CommandObjectProcessLaunch
116254721Semasteclass CommandObjectProcessLaunch : public CommandObjectProcessLaunchOrAttach
117254721Semaste{
118254721Semastepublic:
119254721Semaste
120254721Semaste    CommandObjectProcessLaunch (CommandInterpreter &interpreter) :
121254721Semaste        CommandObjectProcessLaunchOrAttach (interpreter,
122254721Semaste                                            "process launch",
123254721Semaste                                            "Launch the executable in the debugger.",
124254721Semaste                                            NULL,
125254721Semaste                                            eFlagRequiresTarget,
126254721Semaste                                            "restart"),
127254721Semaste        m_options (interpreter)
128254721Semaste    {
129254721Semaste        CommandArgumentEntry arg;
130254721Semaste        CommandArgumentData run_args_arg;
131254721Semaste
132254721Semaste        // Define the first (and only) variant of this arg.
133254721Semaste        run_args_arg.arg_type = eArgTypeRunArgs;
134254721Semaste        run_args_arg.arg_repetition = eArgRepeatOptional;
135254721Semaste
136254721Semaste        // There is only one variant this argument could be; put it into the argument entry.
137254721Semaste        arg.push_back (run_args_arg);
138254721Semaste
139254721Semaste        // Push the data for the first argument into the m_arguments vector.
140254721Semaste        m_arguments.push_back (arg);
141254721Semaste    }
142254721Semaste
143254721Semaste
144254721Semaste    ~CommandObjectProcessLaunch ()
145254721Semaste    {
146254721Semaste    }
147254721Semaste
148254721Semaste    virtual int
149254721Semaste    HandleArgumentCompletion (Args &input,
150254721Semaste                              int &cursor_index,
151254721Semaste                              int &cursor_char_position,
152254721Semaste                              OptionElementVector &opt_element_vector,
153254721Semaste                              int match_start_point,
154254721Semaste                              int max_return_elements,
155254721Semaste                              bool &word_complete,
156254721Semaste                              StringList &matches)
157254721Semaste    {
158254721Semaste        std::string completion_str (input.GetArgumentAtIndex(cursor_index));
159254721Semaste        completion_str.erase (cursor_char_position);
160254721Semaste
161254721Semaste        CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
162254721Semaste                                                             CommandCompletions::eDiskFileCompletion,
163254721Semaste                                                             completion_str.c_str(),
164254721Semaste                                                             match_start_point,
165254721Semaste                                                             max_return_elements,
166254721Semaste                                                             NULL,
167254721Semaste                                                             word_complete,
168254721Semaste                                                             matches);
169254721Semaste        return matches.GetSize();
170254721Semaste    }
171254721Semaste
172254721Semaste    Options *
173254721Semaste    GetOptions ()
174254721Semaste    {
175254721Semaste        return &m_options;
176254721Semaste    }
177254721Semaste
178254721Semaste    virtual const char *GetRepeatCommand (Args &current_command_args, uint32_t index)
179254721Semaste    {
180254721Semaste        // No repeat for "process launch"...
181254721Semaste        return "";
182254721Semaste    }
183254721Semaste
184254721Semasteprotected:
185254721Semaste    bool
186254721Semaste    DoExecute (Args& launch_args, CommandReturnObject &result)
187254721Semaste    {
188254721Semaste        Debugger &debugger = m_interpreter.GetDebugger();
189254721Semaste        Target *target = debugger.GetSelectedTarget().get();
190254721Semaste        Error error;
191254721Semaste        // If our listener is NULL, users aren't allows to launch
192254721Semaste        char filename[PATH_MAX];
193254721Semaste        const Module *exe_module = target->GetExecutableModulePointer();
194254721Semaste
195254721Semaste        if (exe_module == NULL)
196254721Semaste        {
197254721Semaste            result.AppendError ("no file in target, create a debug target using the 'target create' command");
198254721Semaste            result.SetStatus (eReturnStatusFailed);
199254721Semaste            return false;
200254721Semaste        }
201254721Semaste
202254721Semaste        StateType state = eStateInvalid;
203254721Semaste        Process *process = m_exe_ctx.GetProcessPtr();
204254721Semaste
205254721Semaste        if (!StopProcessIfNecessary(process, state, result))
206254721Semaste            return false;
207254721Semaste
208254721Semaste        const char *target_settings_argv0 = target->GetArg0();
209254721Semaste
210254721Semaste        exe_module->GetFileSpec().GetPath (filename, sizeof(filename));
211254721Semaste
212254721Semaste        if (target_settings_argv0)
213254721Semaste        {
214254721Semaste            m_options.launch_info.GetArguments().AppendArgument (target_settings_argv0);
215254721Semaste            m_options.launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), false);
216254721Semaste        }
217254721Semaste        else
218254721Semaste        {
219254721Semaste            m_options.launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), true);
220254721Semaste        }
221254721Semaste
222254721Semaste        if (launch_args.GetArgumentCount() == 0)
223254721Semaste        {
224254721Semaste            Args target_setting_args;
225254721Semaste            if (target->GetRunArguments(target_setting_args))
226254721Semaste                m_options.launch_info.GetArguments().AppendArguments (target_setting_args);
227254721Semaste        }
228254721Semaste        else
229254721Semaste        {
230254721Semaste            m_options.launch_info.GetArguments().AppendArguments (launch_args);
231254721Semaste
232254721Semaste            // Save the arguments for subsequent runs in the current target.
233254721Semaste            target->SetRunArguments (launch_args);
234254721Semaste        }
235254721Semaste
236254721Semaste        if (target->GetDisableASLR())
237254721Semaste            m_options.launch_info.GetFlags().Set (eLaunchFlagDisableASLR);
238254721Semaste
239254721Semaste        if (target->GetDisableSTDIO())
240254721Semaste            m_options.launch_info.GetFlags().Set (eLaunchFlagDisableSTDIO);
241254721Semaste
242254721Semaste        m_options.launch_info.GetFlags().Set (eLaunchFlagDebug);
243254721Semaste
244254721Semaste        Args environment;
245254721Semaste        target->GetEnvironmentAsArgs (environment);
246254721Semaste        if (environment.GetArgumentCount() > 0)
247254721Semaste            m_options.launch_info.GetEnvironmentEntries ().AppendArguments (environment);
248254721Semaste
249254721Semaste        // Get the value of synchronous execution here.  If you wait till after you have started to
250254721Semaste        // run, then you could have hit a breakpoint, whose command might switch the value, and
251254721Semaste        // then you'll pick up that incorrect value.
252254721Semaste        bool synchronous_execution = m_interpreter.GetSynchronous ();
253254721Semaste
254254721Semaste        // Finalize the file actions, and if none were given, default to opening
255254721Semaste        // up a pseudo terminal
256254721Semaste        const bool default_to_use_pty = true;
257254721Semaste        m_options.launch_info.FinalizeFileActions (target, default_to_use_pty);
258254721Semaste
259254721Semaste        if (state == eStateConnected)
260254721Semaste        {
261254721Semaste            if (m_options.launch_info.GetFlags().Test (eLaunchFlagLaunchInTTY))
262254721Semaste            {
263254721Semaste                result.AppendWarning("can't launch in tty when launching through a remote connection");
264254721Semaste                m_options.launch_info.GetFlags().Clear (eLaunchFlagLaunchInTTY);
265254721Semaste            }
266254721Semaste        }
267254721Semaste
268254721Semaste        if (!m_options.launch_info.GetArchitecture().IsValid())
269254721Semaste            m_options.launch_info.GetArchitecture() = target->GetArchitecture();
270254721Semaste
271254721Semaste        PlatformSP platform_sp (target->GetPlatform());
272254721Semaste
273254721Semaste        if (platform_sp && platform_sp->CanDebugProcess ())
274254721Semaste        {
275254721Semaste            process = target->GetPlatform()->DebugProcess (m_options.launch_info,
276254721Semaste                                                           debugger,
277254721Semaste                                                           target,
278254721Semaste                                                           debugger.GetListener(),
279254721Semaste                                                           error).get();
280254721Semaste        }
281254721Semaste        else
282254721Semaste        {
283254721Semaste            const char *plugin_name = m_options.launch_info.GetProcessPluginName();
284254721Semaste            process = target->CreateProcess (debugger.GetListener(), plugin_name, NULL).get();
285254721Semaste            if (process)
286254721Semaste                error = process->Launch (m_options.launch_info);
287254721Semaste        }
288254721Semaste
289254721Semaste        if (process == NULL)
290254721Semaste        {
291254721Semaste            result.SetError (error, "failed to launch or debug process");
292254721Semaste            return false;
293254721Semaste        }
294254721Semaste
295254721Semaste
296254721Semaste        if (error.Success())
297254721Semaste        {
298254721Semaste            const char *archname = exe_module->GetArchitecture().GetArchitectureName();
299254721Semaste
300254721Semaste            result.AppendMessageWithFormat ("Process %" PRIu64 " launched: '%s' (%s)\n", process->GetID(), filename, archname);
301254721Semaste            result.SetDidChangeProcessState (true);
302254721Semaste            if (m_options.launch_info.GetFlags().Test(eLaunchFlagStopAtEntry) == false)
303254721Semaste            {
304254721Semaste                result.SetStatus (eReturnStatusSuccessContinuingNoResult);
305254721Semaste                StateType state = process->WaitForProcessToStop (NULL);
306254721Semaste
307254721Semaste                if (state == eStateStopped)
308254721Semaste                {
309254721Semaste                    error = process->Resume();
310254721Semaste                    if (error.Success())
311254721Semaste                    {
312254721Semaste                        if (synchronous_execution)
313254721Semaste                        {
314254721Semaste                            state = process->WaitForProcessToStop (NULL);
315254721Semaste                            const bool must_be_alive = true;
316254721Semaste                            if (!StateIsStoppedState(state, must_be_alive))
317254721Semaste                            {
318254721Semaste                                result.AppendErrorWithFormat ("process isn't stopped: %s", StateAsCString(state));
319254721Semaste                            }
320254721Semaste                            result.SetDidChangeProcessState (true);
321254721Semaste                            result.SetStatus (eReturnStatusSuccessFinishResult);
322254721Semaste                        }
323254721Semaste                        else
324254721Semaste                        {
325254721Semaste                            result.SetStatus (eReturnStatusSuccessContinuingNoResult);
326254721Semaste                        }
327254721Semaste                    }
328254721Semaste                    else
329254721Semaste                    {
330254721Semaste                        result.AppendErrorWithFormat ("process resume at entry point failed: %s", error.AsCString());
331254721Semaste                        result.SetStatus (eReturnStatusFailed);
332254721Semaste                    }
333254721Semaste                }
334254721Semaste                else
335254721Semaste                {
336254721Semaste                    result.AppendErrorWithFormat ("initial process state wasn't stopped: %s", StateAsCString(state));
337254721Semaste                    result.SetStatus (eReturnStatusFailed);
338254721Semaste                }
339254721Semaste            }
340254721Semaste        }
341254721Semaste        else
342254721Semaste        {
343254721Semaste            result.AppendErrorWithFormat ("process launch failed: %s", error.AsCString());
344254721Semaste            result.SetStatus (eReturnStatusFailed);
345254721Semaste        }
346254721Semaste
347254721Semaste        return result.Succeeded();
348254721Semaste    }
349254721Semaste
350254721Semasteprotected:
351254721Semaste    ProcessLaunchCommandOptions m_options;
352254721Semaste};
353254721Semaste
354254721Semaste
355254721Semaste//#define SET1 LLDB_OPT_SET_1
356254721Semaste//#define SET2 LLDB_OPT_SET_2
357254721Semaste//#define SET3 LLDB_OPT_SET_3
358254721Semaste//
359254721Semaste//OptionDefinition
360254721Semaste//CommandObjectProcessLaunch::CommandOptions::g_option_table[] =
361254721Semaste//{
362254721Semaste//{ 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."},
363254721Semaste//{ SET1              , false, "stdin",         'i', required_argument, NULL, 0, eArgTypeDirectoryName,    "Redirect stdin for the process to <path>."},
364254721Semaste//{ SET1              , false, "stdout",        'o', required_argument, NULL, 0, eArgTypeDirectoryName,    "Redirect stdout for the process to <path>."},
365254721Semaste//{ SET1              , false, "stderr",        'e', required_argument, NULL, 0, eArgTypeDirectoryName,    "Redirect stderr for the process to <path>."},
366254721Semaste//{ SET1 | SET2 | SET3, false, "plugin",        'p', required_argument, NULL, 0, eArgTypePlugin,  "Name of the process plugin you want to use."},
367254721Semaste//{        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."},
368254721Semaste//{               SET3, false, "no-stdio",      'n', no_argument,       NULL, 0, eArgTypeNone,    "Do not set up for terminal I/O to go to running process."},
369254721Semaste//{ SET1 | SET2 | SET3, false, "working-dir",   'w', required_argument, NULL, 0, eArgTypeDirectoryName,    "Set the current working directory to <path> when running the inferior."},
370254721Semaste//{ 0,                  false, NULL,             0,  0,                 NULL, 0, eArgTypeNone,    NULL }
371254721Semaste//};
372254721Semaste//
373254721Semaste//#undef SET1
374254721Semaste//#undef SET2
375254721Semaste//#undef SET3
376254721Semaste
377254721Semaste//-------------------------------------------------------------------------
378254721Semaste// CommandObjectProcessAttach
379254721Semaste//-------------------------------------------------------------------------
380254721Semaste#pragma mark CommandObjectProcessAttach
381254721Semasteclass CommandObjectProcessAttach : public CommandObjectProcessLaunchOrAttach
382254721Semaste{
383254721Semastepublic:
384254721Semaste
385254721Semaste    class CommandOptions : public Options
386254721Semaste    {
387254721Semaste    public:
388254721Semaste
389254721Semaste        CommandOptions (CommandInterpreter &interpreter) :
390254721Semaste            Options(interpreter)
391254721Semaste        {
392254721Semaste            // Keep default values of all options in one place: OptionParsingStarting ()
393254721Semaste            OptionParsingStarting ();
394254721Semaste        }
395254721Semaste
396254721Semaste        ~CommandOptions ()
397254721Semaste        {
398254721Semaste        }
399254721Semaste
400254721Semaste        Error
401254721Semaste        SetOptionValue (uint32_t option_idx, const char *option_arg)
402254721Semaste        {
403254721Semaste            Error error;
404254721Semaste            const int short_option = m_getopt_table[option_idx].val;
405254721Semaste            bool success = false;
406254721Semaste            switch (short_option)
407254721Semaste            {
408254721Semaste                case 'c':
409254721Semaste                    attach_info.SetContinueOnceAttached(true);
410254721Semaste                    break;
411254721Semaste
412254721Semaste                case 'p':
413254721Semaste                    {
414254721Semaste                        lldb::pid_t pid = Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success);
415254721Semaste                        if (!success || pid == LLDB_INVALID_PROCESS_ID)
416254721Semaste                        {
417254721Semaste                            error.SetErrorStringWithFormat("invalid process ID '%s'", option_arg);
418254721Semaste                        }
419254721Semaste                        else
420254721Semaste                        {
421254721Semaste                            attach_info.SetProcessID (pid);
422254721Semaste                        }
423254721Semaste                    }
424254721Semaste                    break;
425254721Semaste
426254721Semaste                case 'P':
427254721Semaste                    attach_info.SetProcessPluginName (option_arg);
428254721Semaste                    break;
429254721Semaste
430254721Semaste                case 'n':
431254721Semaste                    attach_info.GetExecutableFile().SetFile(option_arg, false);
432254721Semaste                    break;
433254721Semaste
434254721Semaste                case 'w':
435254721Semaste                    attach_info.SetWaitForLaunch(true);
436254721Semaste                    break;
437254721Semaste
438254721Semaste                case 'i':
439254721Semaste                    attach_info.SetIgnoreExisting(false);
440254721Semaste                    break;
441254721Semaste
442254721Semaste                default:
443254721Semaste                    error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
444254721Semaste                    break;
445254721Semaste            }
446254721Semaste            return error;
447254721Semaste        }
448254721Semaste
449254721Semaste        void
450254721Semaste        OptionParsingStarting ()
451254721Semaste        {
452254721Semaste            attach_info.Clear();
453254721Semaste        }
454254721Semaste
455254721Semaste        const OptionDefinition*
456254721Semaste        GetDefinitions ()
457254721Semaste        {
458254721Semaste            return g_option_table;
459254721Semaste        }
460254721Semaste
461254721Semaste        virtual bool
462254721Semaste        HandleOptionArgumentCompletion (Args &input,
463254721Semaste                                        int cursor_index,
464254721Semaste                                        int char_pos,
465254721Semaste                                        OptionElementVector &opt_element_vector,
466254721Semaste                                        int opt_element_index,
467254721Semaste                                        int match_start_point,
468254721Semaste                                        int max_return_elements,
469254721Semaste                                        bool &word_complete,
470254721Semaste                                        StringList &matches)
471254721Semaste        {
472254721Semaste            int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
473254721Semaste            int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
474254721Semaste
475254721Semaste            // We are only completing the name option for now...
476254721Semaste
477254721Semaste            const OptionDefinition *opt_defs = GetDefinitions();
478254721Semaste            if (opt_defs[opt_defs_index].short_option == 'n')
479254721Semaste            {
480254721Semaste                // Are we in the name?
481254721Semaste
482254721Semaste                // Look to see if there is a -P argument provided, and if so use that plugin, otherwise
483254721Semaste                // use the default plugin.
484254721Semaste
485254721Semaste                const char *partial_name = NULL;
486254721Semaste                partial_name = input.GetArgumentAtIndex(opt_arg_pos);
487254721Semaste
488254721Semaste                PlatformSP platform_sp (m_interpreter.GetPlatform (true));
489254721Semaste                if (platform_sp)
490254721Semaste                {
491254721Semaste                    ProcessInstanceInfoList process_infos;
492254721Semaste                    ProcessInstanceInfoMatch match_info;
493254721Semaste                    if (partial_name)
494254721Semaste                    {
495254721Semaste                        match_info.GetProcessInfo().GetExecutableFile().SetFile(partial_name, false);
496254721Semaste                        match_info.SetNameMatchType(eNameMatchStartsWith);
497254721Semaste                    }
498254721Semaste                    platform_sp->FindProcesses (match_info, process_infos);
499254721Semaste                    const size_t num_matches = process_infos.GetSize();
500254721Semaste                    if (num_matches > 0)
501254721Semaste                    {
502254721Semaste                        for (size_t i=0; i<num_matches; ++i)
503254721Semaste                        {
504254721Semaste                            matches.AppendString (process_infos.GetProcessNameAtIndex(i),
505254721Semaste                                                  process_infos.GetProcessNameLengthAtIndex(i));
506254721Semaste                        }
507254721Semaste                    }
508254721Semaste                }
509254721Semaste            }
510254721Semaste
511254721Semaste            return false;
512254721Semaste        }
513254721Semaste
514254721Semaste        // Options table: Required for subclasses of Options.
515254721Semaste
516254721Semaste        static OptionDefinition g_option_table[];
517254721Semaste
518254721Semaste        // Instance variables to hold the values for command options.
519254721Semaste
520254721Semaste        ProcessAttachInfo attach_info;
521254721Semaste    };
522254721Semaste
523254721Semaste    CommandObjectProcessAttach (CommandInterpreter &interpreter) :
524254721Semaste        CommandObjectProcessLaunchOrAttach (interpreter,
525254721Semaste                                            "process attach",
526254721Semaste                                            "Attach to a process.",
527254721Semaste                                            "process attach <cmd-options>",
528254721Semaste                                            0,
529254721Semaste                                            "attach"),
530254721Semaste        m_options (interpreter)
531254721Semaste    {
532254721Semaste    }
533254721Semaste
534254721Semaste    ~CommandObjectProcessAttach ()
535254721Semaste    {
536254721Semaste    }
537254721Semaste
538254721Semaste    Options *
539254721Semaste    GetOptions ()
540254721Semaste    {
541254721Semaste        return &m_options;
542254721Semaste    }
543254721Semaste
544254721Semasteprotected:
545254721Semaste    bool
546254721Semaste    DoExecute (Args& command,
547254721Semaste             CommandReturnObject &result)
548254721Semaste    {
549254721Semaste        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
550254721Semaste        // N.B. The attach should be synchronous.  It doesn't help much to get the prompt back between initiating the attach
551254721Semaste        // and the target actually stopping.  So even if the interpreter is set to be asynchronous, we wait for the stop
552254721Semaste        // ourselves here.
553254721Semaste
554254721Semaste        StateType state = eStateInvalid;
555254721Semaste        Process *process = m_exe_ctx.GetProcessPtr();
556254721Semaste
557254721Semaste        if (!StopProcessIfNecessary (process, state, result))
558254721Semaste            return false;
559254721Semaste
560254721Semaste        if (target == NULL)
561254721Semaste        {
562254721Semaste            // If there isn't a current target create one.
563254721Semaste            TargetSP new_target_sp;
564254721Semaste            Error error;
565254721Semaste
566254721Semaste            error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(),
567254721Semaste                                                                              NULL,
568254721Semaste                                                                              NULL,
569254721Semaste                                                                              false,
570254721Semaste                                                                              NULL, // No platform options
571254721Semaste                                                                              new_target_sp);
572254721Semaste            target = new_target_sp.get();
573254721Semaste            if (target == NULL || error.Fail())
574254721Semaste            {
575254721Semaste                result.AppendError(error.AsCString("Error creating target"));
576254721Semaste                return false;
577254721Semaste            }
578254721Semaste            m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target);
579254721Semaste        }
580254721Semaste
581254721Semaste        // Record the old executable module, we want to issue a warning if the process of attaching changed the
582254721Semaste        // current executable (like somebody said "file foo" then attached to a PID whose executable was bar.)
583254721Semaste
584254721Semaste        ModuleSP old_exec_module_sp = target->GetExecutableModule();
585254721Semaste        ArchSpec old_arch_spec = target->GetArchitecture();
586254721Semaste
587254721Semaste        if (command.GetArgumentCount())
588254721Semaste        {
589254721Semaste            result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
590254721Semaste            result.SetStatus (eReturnStatusFailed);
591254721Semaste        }
592254721Semaste        else
593254721Semaste        {
594254721Semaste            if (state != eStateConnected)
595254721Semaste            {
596254721Semaste                const char *plugin_name = m_options.attach_info.GetProcessPluginName();
597254721Semaste                process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name, NULL).get();
598254721Semaste            }
599254721Semaste
600254721Semaste            if (process)
601254721Semaste            {
602254721Semaste                Error error;
603254721Semaste                // If no process info was specified, then use the target executable
604254721Semaste                // name as the process to attach to by default
605254721Semaste                if (!m_options.attach_info.ProcessInfoSpecified ())
606254721Semaste                {
607254721Semaste                    if (old_exec_module_sp)
608254721Semaste                        m_options.attach_info.GetExecutableFile().GetFilename() = old_exec_module_sp->GetPlatformFileSpec().GetFilename();
609254721Semaste
610254721Semaste                    if (!m_options.attach_info.ProcessInfoSpecified ())
611254721Semaste                    {
612254721Semaste                        error.SetErrorString ("no process specified, create a target with a file, or specify the --pid or --name command option");
613254721Semaste                    }
614254721Semaste                }
615254721Semaste
616254721Semaste                if (error.Success())
617254721Semaste                {
618254721Semaste                    error = process->Attach (m_options.attach_info);
619254721Semaste
620254721Semaste                    if (error.Success())
621254721Semaste                    {
622254721Semaste                        result.SetStatus (eReturnStatusSuccessContinuingNoResult);
623254721Semaste                    }
624254721Semaste                    else
625254721Semaste                    {
626254721Semaste                        result.AppendErrorWithFormat ("attach failed: %s\n", error.AsCString());
627254721Semaste                        result.SetStatus (eReturnStatusFailed);
628254721Semaste                        return false;
629254721Semaste                    }
630254721Semaste                    // If we're synchronous, wait for the stopped event and report that.
631254721Semaste                    // Otherwise just return.
632254721Semaste                    // FIXME: in the async case it will now be possible to get to the command
633254721Semaste                    // interpreter with a state eStateAttaching.  Make sure we handle that correctly.
634254721Semaste                    StateType state = process->WaitForProcessToStop (NULL);
635254721Semaste
636254721Semaste                    result.SetDidChangeProcessState (true);
637254721Semaste
638254721Semaste                    if (state == eStateStopped)
639254721Semaste                    {
640254721Semaste                        result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
641254721Semaste                        result.SetStatus (eReturnStatusSuccessFinishNoResult);
642254721Semaste                    }
643254721Semaste                    else
644254721Semaste                    {
645254721Semaste                        result.AppendError ("attach failed: process did not stop (no such process or permission problem?)");
646254721Semaste                        process->Destroy();
647254721Semaste                        result.SetStatus (eReturnStatusFailed);
648254721Semaste                        return false;
649254721Semaste                    }
650254721Semaste                }
651254721Semaste            }
652254721Semaste        }
653254721Semaste
654254721Semaste        if (result.Succeeded())
655254721Semaste        {
656254721Semaste            // Okay, we're done.  Last step is to warn if the executable module has changed:
657254721Semaste            char new_path[PATH_MAX];
658254721Semaste            ModuleSP new_exec_module_sp (target->GetExecutableModule());
659254721Semaste            if (!old_exec_module_sp)
660254721Semaste            {
661254721Semaste                // We might not have a module if we attached to a raw pid...
662254721Semaste                if (new_exec_module_sp)
663254721Semaste                {
664254721Semaste                    new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX);
665254721Semaste                    result.AppendMessageWithFormat("Executable module set to \"%s\".\n", new_path);
666254721Semaste                }
667254721Semaste            }
668254721Semaste            else if (old_exec_module_sp->GetFileSpec() != new_exec_module_sp->GetFileSpec())
669254721Semaste            {
670254721Semaste                char old_path[PATH_MAX];
671254721Semaste
672254721Semaste                old_exec_module_sp->GetFileSpec().GetPath (old_path, PATH_MAX);
673254721Semaste                new_exec_module_sp->GetFileSpec().GetPath (new_path, PATH_MAX);
674254721Semaste
675254721Semaste                result.AppendWarningWithFormat("Executable module changed from \"%s\" to \"%s\".\n",
676254721Semaste                                                    old_path, new_path);
677254721Semaste            }
678254721Semaste
679254721Semaste            if (!old_arch_spec.IsValid())
680254721Semaste            {
681254721Semaste                result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().GetTriple().getTriple().c_str());
682254721Semaste            }
683254721Semaste            else if (!old_arch_spec.IsExactMatch(target->GetArchitecture()))
684254721Semaste            {
685254721Semaste                result.AppendWarningWithFormat("Architecture changed from %s to %s.\n",
686254721Semaste                                               old_arch_spec.GetTriple().getTriple().c_str(),
687254721Semaste                                               target->GetArchitecture().GetTriple().getTriple().c_str());
688254721Semaste            }
689254721Semaste
690254721Semaste            // This supports the use-case scenario of immediately continuing the process once attached.
691254721Semaste            if (m_options.attach_info.GetContinueOnceAttached())
692254721Semaste                m_interpreter.HandleCommand("process continue", eLazyBoolNo, result);
693254721Semaste        }
694254721Semaste        return result.Succeeded();
695254721Semaste    }
696254721Semaste
697254721Semaste    CommandOptions m_options;
698254721Semaste};
699254721Semaste
700254721Semaste
701254721SemasteOptionDefinition
702254721SemasteCommandObjectProcessAttach::CommandOptions::g_option_table[] =
703254721Semaste{
704254721Semaste{ LLDB_OPT_SET_ALL, false, "continue",'c', no_argument,         NULL, 0, eArgTypeNone,         "Immediately continue the process once attached."},
705254721Semaste{ LLDB_OPT_SET_ALL, false, "plugin",  'P', required_argument,   NULL, 0, eArgTypePlugin,       "Name of the process plugin you want to use."},
706254721Semaste{ LLDB_OPT_SET_1,   false, "pid",     'p', required_argument,   NULL, 0, eArgTypePid,          "The process ID of an existing process to attach to."},
707254721Semaste{ LLDB_OPT_SET_2,   false, "name",    'n', required_argument,   NULL, 0, eArgTypeProcessName,  "The name of the process to attach to."},
708254721Semaste{ LLDB_OPT_SET_2,   false, "include-existing", 'i', no_argument, NULL, 0, eArgTypeNone,         "Include existing processes when doing attach -w."},
709254721Semaste{ LLDB_OPT_SET_2,   false, "waitfor", 'w', no_argument,         NULL, 0, eArgTypeNone,         "Wait for the process with <process-name> to launch."},
710254721Semaste{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
711254721Semaste};
712254721Semaste
713254721Semaste//-------------------------------------------------------------------------
714254721Semaste// CommandObjectProcessContinue
715254721Semaste//-------------------------------------------------------------------------
716254721Semaste#pragma mark CommandObjectProcessContinue
717254721Semaste
718254721Semasteclass CommandObjectProcessContinue : public CommandObjectParsed
719254721Semaste{
720254721Semastepublic:
721254721Semaste
722254721Semaste    CommandObjectProcessContinue (CommandInterpreter &interpreter) :
723254721Semaste        CommandObjectParsed (interpreter,
724254721Semaste                             "process continue",
725254721Semaste                             "Continue execution of all threads in the current process.",
726254721Semaste                             "process continue",
727254721Semaste                             eFlagRequiresProcess       |
728254721Semaste                             eFlagTryTargetAPILock      |
729254721Semaste                             eFlagProcessMustBeLaunched |
730254721Semaste                             eFlagProcessMustBePaused   ),
731254721Semaste        m_options(interpreter)
732254721Semaste    {
733254721Semaste    }
734254721Semaste
735254721Semaste
736254721Semaste    ~CommandObjectProcessContinue ()
737254721Semaste    {
738254721Semaste    }
739254721Semaste
740254721Semasteprotected:
741254721Semaste
742254721Semaste    class CommandOptions : public Options
743254721Semaste    {
744254721Semaste    public:
745254721Semaste
746254721Semaste        CommandOptions (CommandInterpreter &interpreter) :
747254721Semaste            Options(interpreter)
748254721Semaste        {
749254721Semaste            // Keep default values of all options in one place: OptionParsingStarting ()
750254721Semaste            OptionParsingStarting ();
751254721Semaste        }
752254721Semaste
753254721Semaste        ~CommandOptions ()
754254721Semaste        {
755254721Semaste        }
756254721Semaste
757254721Semaste        Error
758254721Semaste        SetOptionValue (uint32_t option_idx, const char *option_arg)
759254721Semaste        {
760254721Semaste            Error error;
761254721Semaste            const int short_option = m_getopt_table[option_idx].val;
762254721Semaste            bool success = false;
763254721Semaste            switch (short_option)
764254721Semaste            {
765254721Semaste                case 'i':
766254721Semaste                    m_ignore = Args::StringToUInt32 (option_arg, 0, 0, &success);
767254721Semaste                    if (!success)
768254721Semaste                        error.SetErrorStringWithFormat ("invalid value for ignore option: \"%s\", should be a number.", option_arg);
769254721Semaste                    break;
770254721Semaste
771254721Semaste                default:
772254721Semaste                    error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
773254721Semaste                    break;
774254721Semaste            }
775254721Semaste            return error;
776254721Semaste        }
777254721Semaste
778254721Semaste        void
779254721Semaste        OptionParsingStarting ()
780254721Semaste        {
781254721Semaste            m_ignore = 0;
782254721Semaste        }
783254721Semaste
784254721Semaste        const OptionDefinition*
785254721Semaste        GetDefinitions ()
786254721Semaste        {
787254721Semaste            return g_option_table;
788254721Semaste        }
789254721Semaste
790254721Semaste        // Options table: Required for subclasses of Options.
791254721Semaste
792254721Semaste        static OptionDefinition g_option_table[];
793254721Semaste
794254721Semaste        uint32_t m_ignore;
795254721Semaste    };
796254721Semaste
797254721Semaste    bool
798254721Semaste    DoExecute (Args& command, CommandReturnObject &result)
799254721Semaste    {
800254721Semaste        Process *process = m_exe_ctx.GetProcessPtr();
801254721Semaste        bool synchronous_execution = m_interpreter.GetSynchronous ();
802254721Semaste        StateType state = process->GetState();
803254721Semaste        if (state == eStateStopped)
804254721Semaste        {
805254721Semaste            if (command.GetArgumentCount() != 0)
806254721Semaste            {
807254721Semaste                result.AppendErrorWithFormat ("The '%s' command does not take any arguments.\n", m_cmd_name.c_str());
808254721Semaste                result.SetStatus (eReturnStatusFailed);
809254721Semaste                return false;
810254721Semaste            }
811254721Semaste
812254721Semaste            if (m_options.m_ignore > 0)
813254721Semaste            {
814254721Semaste                ThreadSP sel_thread_sp(process->GetThreadList().GetSelectedThread());
815254721Semaste                if (sel_thread_sp)
816254721Semaste                {
817254721Semaste                    StopInfoSP stop_info_sp = sel_thread_sp->GetStopInfo();
818254721Semaste                    if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonBreakpoint)
819254721Semaste                    {
820254721Semaste                        lldb::break_id_t bp_site_id = (lldb::break_id_t)stop_info_sp->GetValue();
821254721Semaste                        BreakpointSiteSP bp_site_sp(process->GetBreakpointSiteList().FindByID(bp_site_id));
822254721Semaste                        if (bp_site_sp)
823254721Semaste                        {
824254721Semaste                            const size_t num_owners = bp_site_sp->GetNumberOfOwners();
825254721Semaste                            for (size_t i = 0; i < num_owners; i++)
826254721Semaste                            {
827254721Semaste                                Breakpoint &bp_ref = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
828254721Semaste                                if (!bp_ref.IsInternal())
829254721Semaste                                {
830254721Semaste                                    bp_ref.SetIgnoreCount(m_options.m_ignore);
831254721Semaste                                }
832254721Semaste                            }
833254721Semaste                        }
834254721Semaste                    }
835254721Semaste                }
836254721Semaste            }
837254721Semaste
838254721Semaste            {  // Scope for thread list mutex:
839254721Semaste                Mutex::Locker locker (process->GetThreadList().GetMutex());
840254721Semaste                const uint32_t num_threads = process->GetThreadList().GetSize();
841254721Semaste
842254721Semaste                // Set the actions that the threads should each take when resuming
843254721Semaste                for (uint32_t idx=0; idx<num_threads; ++idx)
844254721Semaste                {
845254721Semaste                    process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState (eStateRunning);
846254721Semaste                }
847254721Semaste            }
848254721Semaste
849254721Semaste            Error error(process->Resume());
850254721Semaste            if (error.Success())
851254721Semaste            {
852254721Semaste                result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
853254721Semaste                if (synchronous_execution)
854254721Semaste                {
855254721Semaste                    state = process->WaitForProcessToStop (NULL);
856254721Semaste
857254721Semaste                    result.SetDidChangeProcessState (true);
858254721Semaste                    result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
859254721Semaste                    result.SetStatus (eReturnStatusSuccessFinishNoResult);
860254721Semaste                }
861254721Semaste                else
862254721Semaste                {
863254721Semaste                    result.SetStatus (eReturnStatusSuccessContinuingNoResult);
864254721Semaste                }
865254721Semaste            }
866254721Semaste            else
867254721Semaste            {
868254721Semaste                result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
869254721Semaste                result.SetStatus (eReturnStatusFailed);
870254721Semaste            }
871254721Semaste        }
872254721Semaste        else
873254721Semaste        {
874254721Semaste            result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
875254721Semaste                                         StateAsCString(state));
876254721Semaste            result.SetStatus (eReturnStatusFailed);
877254721Semaste        }
878254721Semaste        return result.Succeeded();
879254721Semaste    }
880254721Semaste
881254721Semaste    Options *
882254721Semaste    GetOptions ()
883254721Semaste    {
884254721Semaste        return &m_options;
885254721Semaste    }
886254721Semaste
887254721Semaste    CommandOptions m_options;
888254721Semaste
889254721Semaste};
890254721Semaste
891254721SemasteOptionDefinition
892254721SemasteCommandObjectProcessContinue::CommandOptions::g_option_table[] =
893254721Semaste{
894254721Semaste{ LLDB_OPT_SET_ALL, false, "ignore-count",'i', required_argument,         NULL, 0, eArgTypeUnsignedInteger,
895254721Semaste                           "Ignore <N> crossings of the breakpoint (if it exists) for the currently selected thread."},
896254721Semaste{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
897254721Semaste};
898254721Semaste
899254721Semaste//-------------------------------------------------------------------------
900254721Semaste// CommandObjectProcessDetach
901254721Semaste//-------------------------------------------------------------------------
902254721Semaste#pragma mark CommandObjectProcessDetach
903254721Semaste
904254721Semasteclass CommandObjectProcessDetach : public CommandObjectParsed
905254721Semaste{
906254721Semastepublic:
907254721Semaste    class CommandOptions : public Options
908254721Semaste    {
909254721Semaste    public:
910254721Semaste
911254721Semaste        CommandOptions (CommandInterpreter &interpreter) :
912254721Semaste            Options (interpreter)
913254721Semaste        {
914254721Semaste            OptionParsingStarting ();
915254721Semaste        }
916254721Semaste
917254721Semaste        ~CommandOptions ()
918254721Semaste        {
919254721Semaste        }
920254721Semaste
921254721Semaste        Error
922254721Semaste        SetOptionValue (uint32_t option_idx, const char *option_arg)
923254721Semaste        {
924254721Semaste            Error error;
925254721Semaste            const int short_option = m_getopt_table[option_idx].val;
926254721Semaste
927254721Semaste            switch (short_option)
928254721Semaste            {
929254721Semaste                case 's':
930254721Semaste                    bool tmp_result;
931254721Semaste                    bool success;
932254721Semaste                    tmp_result = Args::StringToBoolean(option_arg, false, &success);
933254721Semaste                    if (!success)
934254721Semaste                        error.SetErrorStringWithFormat("invalid boolean option: \"%s\"", option_arg);
935254721Semaste                    else
936254721Semaste                    {
937254721Semaste                        if (tmp_result)
938254721Semaste                            m_keep_stopped = eLazyBoolYes;
939254721Semaste                        else
940254721Semaste                            m_keep_stopped = eLazyBoolNo;
941254721Semaste                    }
942254721Semaste                    break;
943254721Semaste                default:
944254721Semaste                    error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
945254721Semaste                    break;
946254721Semaste            }
947254721Semaste            return error;
948254721Semaste        }
949254721Semaste
950254721Semaste        void
951254721Semaste        OptionParsingStarting ()
952254721Semaste        {
953254721Semaste            m_keep_stopped = eLazyBoolCalculate;
954254721Semaste        }
955254721Semaste
956254721Semaste        const OptionDefinition*
957254721Semaste        GetDefinitions ()
958254721Semaste        {
959254721Semaste            return g_option_table;
960254721Semaste        }
961254721Semaste
962254721Semaste        // Options table: Required for subclasses of Options.
963254721Semaste
964254721Semaste        static OptionDefinition g_option_table[];
965254721Semaste
966254721Semaste        // Instance variables to hold the values for command options.
967254721Semaste        LazyBool m_keep_stopped;
968254721Semaste    };
969254721Semaste
970254721Semaste    CommandObjectProcessDetach (CommandInterpreter &interpreter) :
971254721Semaste        CommandObjectParsed (interpreter,
972254721Semaste                             "process detach",
973254721Semaste                             "Detach from the current process being debugged.",
974254721Semaste                             "process detach",
975254721Semaste                             eFlagRequiresProcess      |
976254721Semaste                             eFlagTryTargetAPILock     |
977254721Semaste                             eFlagProcessMustBeLaunched),
978254721Semaste        m_options(interpreter)
979254721Semaste    {
980254721Semaste    }
981254721Semaste
982254721Semaste    ~CommandObjectProcessDetach ()
983254721Semaste    {
984254721Semaste    }
985254721Semaste
986254721Semaste    Options *
987254721Semaste    GetOptions ()
988254721Semaste    {
989254721Semaste        return &m_options;
990254721Semaste    }
991254721Semaste
992254721Semaste
993254721Semasteprotected:
994254721Semaste    bool
995254721Semaste    DoExecute (Args& command, CommandReturnObject &result)
996254721Semaste    {
997254721Semaste        Process *process = m_exe_ctx.GetProcessPtr();
998254721Semaste        result.AppendMessageWithFormat ("Detaching from process %" PRIu64 "\n", process->GetID());
999254721Semaste        // FIXME: This will be a Command Option:
1000254721Semaste        bool keep_stopped;
1001254721Semaste        if (m_options.m_keep_stopped == eLazyBoolCalculate)
1002254721Semaste        {
1003254721Semaste            // Check the process default:
1004254721Semaste            if (process->GetDetachKeepsStopped())
1005254721Semaste                keep_stopped = true;
1006254721Semaste            else
1007254721Semaste                keep_stopped = false;
1008254721Semaste        }
1009254721Semaste        else if (m_options.m_keep_stopped == eLazyBoolYes)
1010254721Semaste            keep_stopped = true;
1011254721Semaste        else
1012254721Semaste            keep_stopped = false;
1013254721Semaste
1014254721Semaste        Error error (process->Detach(keep_stopped));
1015254721Semaste        if (error.Success())
1016254721Semaste        {
1017254721Semaste            result.SetStatus (eReturnStatusSuccessFinishResult);
1018254721Semaste        }
1019254721Semaste        else
1020254721Semaste        {
1021254721Semaste            result.AppendErrorWithFormat ("Detach failed: %s\n", error.AsCString());
1022254721Semaste            result.SetStatus (eReturnStatusFailed);
1023254721Semaste            return false;
1024254721Semaste        }
1025254721Semaste        return result.Succeeded();
1026254721Semaste    }
1027254721Semaste
1028254721Semaste    CommandOptions m_options;
1029254721Semaste};
1030254721Semaste
1031254721SemasteOptionDefinition
1032254721SemasteCommandObjectProcessDetach::CommandOptions::g_option_table[] =
1033254721Semaste{
1034254721Semaste{ 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)." },
1035254721Semaste{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1036254721Semaste};
1037254721Semaste
1038254721Semaste//-------------------------------------------------------------------------
1039254721Semaste// CommandObjectProcessConnect
1040254721Semaste//-------------------------------------------------------------------------
1041254721Semaste#pragma mark CommandObjectProcessConnect
1042254721Semaste
1043254721Semasteclass CommandObjectProcessConnect : public CommandObjectParsed
1044254721Semaste{
1045254721Semastepublic:
1046254721Semaste
1047254721Semaste    class CommandOptions : public Options
1048254721Semaste    {
1049254721Semaste    public:
1050254721Semaste
1051254721Semaste        CommandOptions (CommandInterpreter &interpreter) :
1052254721Semaste            Options(interpreter)
1053254721Semaste        {
1054254721Semaste            // Keep default values of all options in one place: OptionParsingStarting ()
1055254721Semaste            OptionParsingStarting ();
1056254721Semaste        }
1057254721Semaste
1058254721Semaste        ~CommandOptions ()
1059254721Semaste        {
1060254721Semaste        }
1061254721Semaste
1062254721Semaste        Error
1063254721Semaste        SetOptionValue (uint32_t option_idx, const char *option_arg)
1064254721Semaste        {
1065254721Semaste            Error error;
1066254721Semaste            const int short_option = m_getopt_table[option_idx].val;
1067254721Semaste
1068254721Semaste            switch (short_option)
1069254721Semaste            {
1070254721Semaste            case 'p':
1071254721Semaste                plugin_name.assign (option_arg);
1072254721Semaste                break;
1073254721Semaste
1074254721Semaste            default:
1075254721Semaste                error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
1076254721Semaste                break;
1077254721Semaste            }
1078254721Semaste            return error;
1079254721Semaste        }
1080254721Semaste
1081254721Semaste        void
1082254721Semaste        OptionParsingStarting ()
1083254721Semaste        {
1084254721Semaste            plugin_name.clear();
1085254721Semaste        }
1086254721Semaste
1087254721Semaste        const OptionDefinition*
1088254721Semaste        GetDefinitions ()
1089254721Semaste        {
1090254721Semaste            return g_option_table;
1091254721Semaste        }
1092254721Semaste
1093254721Semaste        // Options table: Required for subclasses of Options.
1094254721Semaste
1095254721Semaste        static OptionDefinition g_option_table[];
1096254721Semaste
1097254721Semaste        // Instance variables to hold the values for command options.
1098254721Semaste
1099254721Semaste        std::string plugin_name;
1100254721Semaste    };
1101254721Semaste
1102254721Semaste    CommandObjectProcessConnect (CommandInterpreter &interpreter) :
1103254721Semaste        CommandObjectParsed (interpreter,
1104254721Semaste                             "process connect",
1105254721Semaste                             "Connect to a remote debug service.",
1106254721Semaste                             "process connect <remote-url>",
1107254721Semaste                             0),
1108254721Semaste        m_options (interpreter)
1109254721Semaste    {
1110254721Semaste    }
1111254721Semaste
1112254721Semaste    ~CommandObjectProcessConnect ()
1113254721Semaste    {
1114254721Semaste    }
1115254721Semaste
1116254721Semaste
1117254721Semaste    Options *
1118254721Semaste    GetOptions ()
1119254721Semaste    {
1120254721Semaste        return &m_options;
1121254721Semaste    }
1122254721Semaste
1123254721Semasteprotected:
1124254721Semaste    bool
1125254721Semaste    DoExecute (Args& command,
1126254721Semaste             CommandReturnObject &result)
1127254721Semaste    {
1128254721Semaste
1129254721Semaste        TargetSP target_sp (m_interpreter.GetDebugger().GetSelectedTarget());
1130254721Semaste        Error error;
1131254721Semaste        Process *process = m_exe_ctx.GetProcessPtr();
1132254721Semaste        if (process)
1133254721Semaste        {
1134254721Semaste            if (process->IsAlive())
1135254721Semaste            {
1136254721Semaste                result.AppendErrorWithFormat ("Process %" PRIu64 " is currently being debugged, kill the process before connecting.\n",
1137254721Semaste                                              process->GetID());
1138254721Semaste                result.SetStatus (eReturnStatusFailed);
1139254721Semaste                return false;
1140254721Semaste            }
1141254721Semaste        }
1142254721Semaste
1143254721Semaste        if (!target_sp)
1144254721Semaste        {
1145254721Semaste            // If there isn't a current target create one.
1146254721Semaste
1147254721Semaste            error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(),
1148254721Semaste                                                                              NULL,
1149254721Semaste                                                                              NULL,
1150254721Semaste                                                                              false,
1151254721Semaste                                                                              NULL, // No platform options
1152254721Semaste                                                                              target_sp);
1153254721Semaste            if (!target_sp || error.Fail())
1154254721Semaste            {
1155254721Semaste                result.AppendError(error.AsCString("Error creating target"));
1156254721Semaste                result.SetStatus (eReturnStatusFailed);
1157254721Semaste                return false;
1158254721Semaste            }
1159254721Semaste            m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target_sp.get());
1160254721Semaste        }
1161254721Semaste
1162254721Semaste        if (command.GetArgumentCount() == 1)
1163254721Semaste        {
1164254721Semaste            const char *plugin_name = NULL;
1165254721Semaste            if (!m_options.plugin_name.empty())
1166254721Semaste                plugin_name = m_options.plugin_name.c_str();
1167254721Semaste
1168254721Semaste            const char *remote_url = command.GetArgumentAtIndex(0);
1169254721Semaste            process = target_sp->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name, NULL).get();
1170254721Semaste
1171254721Semaste            if (process)
1172254721Semaste            {
1173254721Semaste                error = process->ConnectRemote (&process->GetTarget().GetDebugger().GetOutputStream(), remote_url);
1174254721Semaste
1175254721Semaste                if (error.Fail())
1176254721Semaste                {
1177254721Semaste                    result.AppendError(error.AsCString("Remote connect failed"));
1178254721Semaste                    result.SetStatus (eReturnStatusFailed);
1179254721Semaste                    target_sp->DeleteCurrentProcess();
1180254721Semaste                    return false;
1181254721Semaste                }
1182254721Semaste            }
1183254721Semaste            else
1184254721Semaste            {
1185254721Semaste                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",
1186254721Semaste                                              remote_url);
1187254721Semaste                result.SetStatus (eReturnStatusFailed);
1188254721Semaste            }
1189254721Semaste        }
1190254721Semaste        else
1191254721Semaste        {
1192254721Semaste            result.AppendErrorWithFormat ("'%s' takes exactly one argument:\nUsage: %s\n",
1193254721Semaste                                          m_cmd_name.c_str(),
1194254721Semaste                                          m_cmd_syntax.c_str());
1195254721Semaste            result.SetStatus (eReturnStatusFailed);
1196254721Semaste        }
1197254721Semaste        return result.Succeeded();
1198254721Semaste    }
1199254721Semaste
1200254721Semaste    CommandOptions m_options;
1201254721Semaste};
1202254721Semaste
1203254721SemasteOptionDefinition
1204254721SemasteCommandObjectProcessConnect::CommandOptions::g_option_table[] =
1205254721Semaste{
1206254721Semaste    { LLDB_OPT_SET_ALL, false, "plugin", 'p', required_argument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."},
1207254721Semaste    { 0,                false, NULL,      0 , 0,                 NULL, 0, eArgTypeNone,   NULL }
1208254721Semaste};
1209254721Semaste
1210254721Semaste//-------------------------------------------------------------------------
1211254721Semaste// CommandObjectProcessPlugin
1212254721Semaste//-------------------------------------------------------------------------
1213254721Semaste#pragma mark CommandObjectProcessPlugin
1214254721Semaste
1215254721Semasteclass CommandObjectProcessPlugin : public CommandObjectProxy
1216254721Semaste{
1217254721Semastepublic:
1218254721Semaste
1219254721Semaste    CommandObjectProcessPlugin (CommandInterpreter &interpreter) :
1220254721Semaste        CommandObjectProxy (interpreter,
1221254721Semaste                            "process plugin",
1222254721Semaste                            "Send a custom command to the current process plug-in.",
1223254721Semaste                            "process plugin <args>",
1224254721Semaste                            0)
1225254721Semaste    {
1226254721Semaste    }
1227254721Semaste
1228254721Semaste    ~CommandObjectProcessPlugin ()
1229254721Semaste    {
1230254721Semaste    }
1231254721Semaste
1232254721Semaste    virtual CommandObject *
1233254721Semaste    GetProxyCommandObject()
1234254721Semaste    {
1235254721Semaste        Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
1236254721Semaste        if (process)
1237254721Semaste            return process->GetPluginCommandObject();
1238254721Semaste        return NULL;
1239254721Semaste    }
1240254721Semaste};
1241254721Semaste
1242254721Semaste
1243254721Semaste//-------------------------------------------------------------------------
1244254721Semaste// CommandObjectProcessLoad
1245254721Semaste//-------------------------------------------------------------------------
1246254721Semaste#pragma mark CommandObjectProcessLoad
1247254721Semaste
1248254721Semasteclass CommandObjectProcessLoad : public CommandObjectParsed
1249254721Semaste{
1250254721Semastepublic:
1251254721Semaste
1252254721Semaste    CommandObjectProcessLoad (CommandInterpreter &interpreter) :
1253254721Semaste        CommandObjectParsed (interpreter,
1254254721Semaste                             "process load",
1255254721Semaste                             "Load a shared library into the current process.",
1256254721Semaste                             "process load <filename> [<filename> ...]",
1257254721Semaste                             eFlagRequiresProcess       |
1258254721Semaste                             eFlagTryTargetAPILock      |
1259254721Semaste                             eFlagProcessMustBeLaunched |
1260254721Semaste                             eFlagProcessMustBePaused   )
1261254721Semaste    {
1262254721Semaste    }
1263254721Semaste
1264254721Semaste    ~CommandObjectProcessLoad ()
1265254721Semaste    {
1266254721Semaste    }
1267254721Semaste
1268254721Semasteprotected:
1269254721Semaste    bool
1270254721Semaste    DoExecute (Args& command,
1271254721Semaste             CommandReturnObject &result)
1272254721Semaste    {
1273254721Semaste        Process *process = m_exe_ctx.GetProcessPtr();
1274254721Semaste
1275254721Semaste        const size_t argc = command.GetArgumentCount();
1276254721Semaste
1277254721Semaste        for (uint32_t i=0; i<argc; ++i)
1278254721Semaste        {
1279254721Semaste            Error error;
1280254721Semaste            const char *image_path = command.GetArgumentAtIndex(i);
1281254721Semaste            FileSpec image_spec (image_path, false);
1282254721Semaste            process->GetTarget().GetPlatform()->ResolveRemotePath(image_spec, image_spec);
1283254721Semaste            uint32_t image_token = process->LoadImage(image_spec, error);
1284254721Semaste            if (image_token != LLDB_INVALID_IMAGE_TOKEN)
1285254721Semaste            {
1286254721Semaste                result.AppendMessageWithFormat ("Loading \"%s\"...ok\nImage %u loaded.\n", image_path, image_token);
1287254721Semaste                result.SetStatus (eReturnStatusSuccessFinishResult);
1288254721Semaste            }
1289254721Semaste            else
1290254721Semaste            {
1291254721Semaste                result.AppendErrorWithFormat ("failed to load '%s': %s", image_path, error.AsCString());
1292254721Semaste                result.SetStatus (eReturnStatusFailed);
1293254721Semaste            }
1294254721Semaste        }
1295254721Semaste        return result.Succeeded();
1296254721Semaste    }
1297254721Semaste};
1298254721Semaste
1299254721Semaste
1300254721Semaste//-------------------------------------------------------------------------
1301254721Semaste// CommandObjectProcessUnload
1302254721Semaste//-------------------------------------------------------------------------
1303254721Semaste#pragma mark CommandObjectProcessUnload
1304254721Semaste
1305254721Semasteclass CommandObjectProcessUnload : public CommandObjectParsed
1306254721Semaste{
1307254721Semastepublic:
1308254721Semaste
1309254721Semaste    CommandObjectProcessUnload (CommandInterpreter &interpreter) :
1310254721Semaste        CommandObjectParsed (interpreter,
1311254721Semaste                             "process unload",
1312254721Semaste                             "Unload a shared library from the current process using the index returned by a previous call to \"process load\".",
1313254721Semaste                             "process unload <index>",
1314254721Semaste                             eFlagRequiresProcess       |
1315254721Semaste                             eFlagTryTargetAPILock      |
1316254721Semaste                             eFlagProcessMustBeLaunched |
1317254721Semaste                             eFlagProcessMustBePaused   )
1318254721Semaste    {
1319254721Semaste    }
1320254721Semaste
1321254721Semaste    ~CommandObjectProcessUnload ()
1322254721Semaste    {
1323254721Semaste    }
1324254721Semaste
1325254721Semasteprotected:
1326254721Semaste    bool
1327254721Semaste    DoExecute (Args& command,
1328254721Semaste             CommandReturnObject &result)
1329254721Semaste    {
1330254721Semaste        Process *process = m_exe_ctx.GetProcessPtr();
1331254721Semaste
1332254721Semaste        const size_t argc = command.GetArgumentCount();
1333254721Semaste
1334254721Semaste        for (uint32_t i=0; i<argc; ++i)
1335254721Semaste        {
1336254721Semaste            const char *image_token_cstr = command.GetArgumentAtIndex(i);
1337254721Semaste            uint32_t image_token = Args::StringToUInt32(image_token_cstr, LLDB_INVALID_IMAGE_TOKEN, 0);
1338254721Semaste            if (image_token == LLDB_INVALID_IMAGE_TOKEN)
1339254721Semaste            {
1340254721Semaste                result.AppendErrorWithFormat ("invalid image index argument '%s'", image_token_cstr);
1341254721Semaste                result.SetStatus (eReturnStatusFailed);
1342254721Semaste                break;
1343254721Semaste            }
1344254721Semaste            else
1345254721Semaste            {
1346254721Semaste                Error error (process->UnloadImage(image_token));
1347254721Semaste                if (error.Success())
1348254721Semaste                {
1349254721Semaste                    result.AppendMessageWithFormat ("Unloading shared library with index %u...ok\n", image_token);
1350254721Semaste                    result.SetStatus (eReturnStatusSuccessFinishResult);
1351254721Semaste                }
1352254721Semaste                else
1353254721Semaste                {
1354254721Semaste                    result.AppendErrorWithFormat ("failed to unload image: %s", error.AsCString());
1355254721Semaste                    result.SetStatus (eReturnStatusFailed);
1356254721Semaste                    break;
1357254721Semaste                }
1358254721Semaste            }
1359254721Semaste        }
1360254721Semaste        return result.Succeeded();
1361254721Semaste    }
1362254721Semaste};
1363254721Semaste
1364254721Semaste//-------------------------------------------------------------------------
1365254721Semaste// CommandObjectProcessSignal
1366254721Semaste//-------------------------------------------------------------------------
1367254721Semaste#pragma mark CommandObjectProcessSignal
1368254721Semaste
1369254721Semasteclass CommandObjectProcessSignal : public CommandObjectParsed
1370254721Semaste{
1371254721Semastepublic:
1372254721Semaste
1373254721Semaste    CommandObjectProcessSignal (CommandInterpreter &interpreter) :
1374254721Semaste        CommandObjectParsed (interpreter,
1375254721Semaste                             "process signal",
1376254721Semaste                             "Send a UNIX signal to the current process being debugged.",
1377254721Semaste                             NULL,
1378254721Semaste                             eFlagRequiresProcess | eFlagTryTargetAPILock)
1379254721Semaste    {
1380254721Semaste        CommandArgumentEntry arg;
1381254721Semaste        CommandArgumentData signal_arg;
1382254721Semaste
1383254721Semaste        // Define the first (and only) variant of this arg.
1384254721Semaste        signal_arg.arg_type = eArgTypeUnixSignal;
1385254721Semaste        signal_arg.arg_repetition = eArgRepeatPlain;
1386254721Semaste
1387254721Semaste        // There is only one variant this argument could be; put it into the argument entry.
1388254721Semaste        arg.push_back (signal_arg);
1389254721Semaste
1390254721Semaste        // Push the data for the first argument into the m_arguments vector.
1391254721Semaste        m_arguments.push_back (arg);
1392254721Semaste    }
1393254721Semaste
1394254721Semaste    ~CommandObjectProcessSignal ()
1395254721Semaste    {
1396254721Semaste    }
1397254721Semaste
1398254721Semasteprotected:
1399254721Semaste    bool
1400254721Semaste    DoExecute (Args& command,
1401254721Semaste             CommandReturnObject &result)
1402254721Semaste    {
1403254721Semaste        Process *process = m_exe_ctx.GetProcessPtr();
1404254721Semaste
1405254721Semaste        if (command.GetArgumentCount() == 1)
1406254721Semaste        {
1407254721Semaste            int signo = LLDB_INVALID_SIGNAL_NUMBER;
1408254721Semaste
1409254721Semaste            const char *signal_name = command.GetArgumentAtIndex(0);
1410254721Semaste            if (::isxdigit (signal_name[0]))
1411254721Semaste                signo = Args::StringToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0);
1412254721Semaste            else
1413254721Semaste                signo = process->GetUnixSignals().GetSignalNumberFromName (signal_name);
1414254721Semaste
1415254721Semaste            if (signo == LLDB_INVALID_SIGNAL_NUMBER)
1416254721Semaste            {
1417254721Semaste                result.AppendErrorWithFormat ("Invalid signal argument '%s'.\n", command.GetArgumentAtIndex(0));
1418254721Semaste                result.SetStatus (eReturnStatusFailed);
1419254721Semaste            }
1420254721Semaste            else
1421254721Semaste            {
1422254721Semaste                Error error (process->Signal (signo));
1423254721Semaste                if (error.Success())
1424254721Semaste                {
1425254721Semaste                    result.SetStatus (eReturnStatusSuccessFinishResult);
1426254721Semaste                }
1427254721Semaste                else
1428254721Semaste                {
1429254721Semaste                    result.AppendErrorWithFormat ("Failed to send signal %i: %s\n", signo, error.AsCString());
1430254721Semaste                    result.SetStatus (eReturnStatusFailed);
1431254721Semaste                }
1432254721Semaste            }
1433254721Semaste        }
1434254721Semaste        else
1435254721Semaste        {
1436254721Semaste            result.AppendErrorWithFormat("'%s' takes exactly one signal number argument:\nUsage: %s\n", m_cmd_name.c_str(),
1437254721Semaste                                        m_cmd_syntax.c_str());
1438254721Semaste            result.SetStatus (eReturnStatusFailed);
1439254721Semaste        }
1440254721Semaste        return result.Succeeded();
1441254721Semaste    }
1442254721Semaste};
1443254721Semaste
1444254721Semaste
1445254721Semaste//-------------------------------------------------------------------------
1446254721Semaste// CommandObjectProcessInterrupt
1447254721Semaste//-------------------------------------------------------------------------
1448254721Semaste#pragma mark CommandObjectProcessInterrupt
1449254721Semaste
1450254721Semasteclass CommandObjectProcessInterrupt : public CommandObjectParsed
1451254721Semaste{
1452254721Semastepublic:
1453254721Semaste
1454254721Semaste
1455254721Semaste    CommandObjectProcessInterrupt (CommandInterpreter &interpreter) :
1456254721Semaste        CommandObjectParsed (interpreter,
1457254721Semaste                             "process interrupt",
1458254721Semaste                             "Interrupt the current process being debugged.",
1459254721Semaste                             "process interrupt",
1460254721Semaste                             eFlagRequiresProcess      |
1461254721Semaste                             eFlagTryTargetAPILock     |
1462254721Semaste                             eFlagProcessMustBeLaunched)
1463254721Semaste    {
1464254721Semaste    }
1465254721Semaste
1466254721Semaste    ~CommandObjectProcessInterrupt ()
1467254721Semaste    {
1468254721Semaste    }
1469254721Semaste
1470254721Semasteprotected:
1471254721Semaste    bool
1472254721Semaste    DoExecute (Args& command,
1473254721Semaste               CommandReturnObject &result)
1474254721Semaste    {
1475254721Semaste        Process *process = m_exe_ctx.GetProcessPtr();
1476254721Semaste        if (process == NULL)
1477254721Semaste        {
1478254721Semaste            result.AppendError ("no process to halt");
1479254721Semaste            result.SetStatus (eReturnStatusFailed);
1480254721Semaste            return false;
1481254721Semaste        }
1482254721Semaste
1483254721Semaste        if (command.GetArgumentCount() == 0)
1484254721Semaste        {
1485254721Semaste            bool clear_thread_plans = true;
1486254721Semaste            Error error(process->Halt (clear_thread_plans));
1487254721Semaste            if (error.Success())
1488254721Semaste            {
1489254721Semaste                result.SetStatus (eReturnStatusSuccessFinishResult);
1490254721Semaste            }
1491254721Semaste            else
1492254721Semaste            {
1493254721Semaste                result.AppendErrorWithFormat ("Failed to halt process: %s\n", error.AsCString());
1494254721Semaste                result.SetStatus (eReturnStatusFailed);
1495254721Semaste            }
1496254721Semaste        }
1497254721Semaste        else
1498254721Semaste        {
1499254721Semaste            result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n",
1500254721Semaste                                        m_cmd_name.c_str(),
1501254721Semaste                                        m_cmd_syntax.c_str());
1502254721Semaste            result.SetStatus (eReturnStatusFailed);
1503254721Semaste        }
1504254721Semaste        return result.Succeeded();
1505254721Semaste    }
1506254721Semaste};
1507254721Semaste
1508254721Semaste//-------------------------------------------------------------------------
1509254721Semaste// CommandObjectProcessKill
1510254721Semaste//-------------------------------------------------------------------------
1511254721Semaste#pragma mark CommandObjectProcessKill
1512254721Semaste
1513254721Semasteclass CommandObjectProcessKill : public CommandObjectParsed
1514254721Semaste{
1515254721Semastepublic:
1516254721Semaste
1517254721Semaste    CommandObjectProcessKill (CommandInterpreter &interpreter) :
1518254721Semaste        CommandObjectParsed (interpreter,
1519254721Semaste                             "process kill",
1520254721Semaste                             "Terminate the current process being debugged.",
1521254721Semaste                             "process kill",
1522254721Semaste                             eFlagRequiresProcess      |
1523254721Semaste                             eFlagTryTargetAPILock     |
1524254721Semaste                             eFlagProcessMustBeLaunched)
1525254721Semaste    {
1526254721Semaste    }
1527254721Semaste
1528254721Semaste    ~CommandObjectProcessKill ()
1529254721Semaste    {
1530254721Semaste    }
1531254721Semaste
1532254721Semasteprotected:
1533254721Semaste    bool
1534254721Semaste    DoExecute (Args& command,
1535254721Semaste             CommandReturnObject &result)
1536254721Semaste    {
1537254721Semaste        Process *process = m_exe_ctx.GetProcessPtr();
1538254721Semaste        if (process == NULL)
1539254721Semaste        {
1540254721Semaste            result.AppendError ("no process to kill");
1541254721Semaste            result.SetStatus (eReturnStatusFailed);
1542254721Semaste            return false;
1543254721Semaste        }
1544254721Semaste
1545254721Semaste        if (command.GetArgumentCount() == 0)
1546254721Semaste        {
1547254721Semaste            Error error (process->Destroy());
1548254721Semaste            if (error.Success())
1549254721Semaste            {
1550254721Semaste                result.SetStatus (eReturnStatusSuccessFinishResult);
1551254721Semaste            }
1552254721Semaste            else
1553254721Semaste            {
1554254721Semaste                result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString());
1555254721Semaste                result.SetStatus (eReturnStatusFailed);
1556254721Semaste            }
1557254721Semaste        }
1558254721Semaste        else
1559254721Semaste        {
1560254721Semaste            result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n",
1561254721Semaste                                        m_cmd_name.c_str(),
1562254721Semaste                                        m_cmd_syntax.c_str());
1563254721Semaste            result.SetStatus (eReturnStatusFailed);
1564254721Semaste        }
1565254721Semaste        return result.Succeeded();
1566254721Semaste    }
1567254721Semaste};
1568254721Semaste
1569254721Semaste//-------------------------------------------------------------------------
1570254721Semaste// CommandObjectProcessStatus
1571254721Semaste//-------------------------------------------------------------------------
1572254721Semaste#pragma mark CommandObjectProcessStatus
1573254721Semaste
1574254721Semasteclass CommandObjectProcessStatus : public CommandObjectParsed
1575254721Semaste{
1576254721Semastepublic:
1577254721Semaste    CommandObjectProcessStatus (CommandInterpreter &interpreter) :
1578254721Semaste        CommandObjectParsed (interpreter,
1579254721Semaste                             "process status",
1580254721Semaste                             "Show the current status and location of executing process.",
1581254721Semaste                             "process status",
1582254721Semaste                             eFlagRequiresProcess | eFlagTryTargetAPILock)
1583254721Semaste    {
1584254721Semaste    }
1585254721Semaste
1586254721Semaste    ~CommandObjectProcessStatus()
1587254721Semaste    {
1588254721Semaste    }
1589254721Semaste
1590254721Semaste
1591254721Semaste    bool
1592254721Semaste    DoExecute (Args& command, CommandReturnObject &result)
1593254721Semaste    {
1594254721Semaste        Stream &strm = result.GetOutputStream();
1595254721Semaste        result.SetStatus (eReturnStatusSuccessFinishNoResult);
1596254721Semaste        // No need to check "process" for validity as eFlagRequiresProcess ensures it is valid
1597254721Semaste        Process *process = m_exe_ctx.GetProcessPtr();
1598254721Semaste        const bool only_threads_with_stop_reason = true;
1599254721Semaste        const uint32_t start_frame = 0;
1600254721Semaste        const uint32_t num_frames = 1;
1601254721Semaste        const uint32_t num_frames_with_source = 1;
1602254721Semaste        process->GetStatus(strm);
1603254721Semaste        process->GetThreadStatus (strm,
1604254721Semaste                                  only_threads_with_stop_reason,
1605254721Semaste                                  start_frame,
1606254721Semaste                                  num_frames,
1607254721Semaste                                  num_frames_with_source);
1608254721Semaste        return result.Succeeded();
1609254721Semaste    }
1610254721Semaste};
1611254721Semaste
1612254721Semaste//-------------------------------------------------------------------------
1613254721Semaste// CommandObjectProcessHandle
1614254721Semaste//-------------------------------------------------------------------------
1615254721Semaste#pragma mark CommandObjectProcessHandle
1616254721Semaste
1617254721Semasteclass CommandObjectProcessHandle : public CommandObjectParsed
1618254721Semaste{
1619254721Semastepublic:
1620254721Semaste
1621254721Semaste    class CommandOptions : public Options
1622254721Semaste    {
1623254721Semaste    public:
1624254721Semaste
1625254721Semaste        CommandOptions (CommandInterpreter &interpreter) :
1626254721Semaste            Options (interpreter)
1627254721Semaste        {
1628254721Semaste            OptionParsingStarting ();
1629254721Semaste        }
1630254721Semaste
1631254721Semaste        ~CommandOptions ()
1632254721Semaste        {
1633254721Semaste        }
1634254721Semaste
1635254721Semaste        Error
1636254721Semaste        SetOptionValue (uint32_t option_idx, const char *option_arg)
1637254721Semaste        {
1638254721Semaste            Error error;
1639254721Semaste            const int short_option = m_getopt_table[option_idx].val;
1640254721Semaste
1641254721Semaste            switch (short_option)
1642254721Semaste            {
1643254721Semaste                case 's':
1644254721Semaste                    stop = option_arg;
1645254721Semaste                    break;
1646254721Semaste                case 'n':
1647254721Semaste                    notify = option_arg;
1648254721Semaste                    break;
1649254721Semaste                case 'p':
1650254721Semaste                    pass = option_arg;
1651254721Semaste                    break;
1652254721Semaste                default:
1653254721Semaste                    error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
1654254721Semaste                    break;
1655254721Semaste            }
1656254721Semaste            return error;
1657254721Semaste        }
1658254721Semaste
1659254721Semaste        void
1660254721Semaste        OptionParsingStarting ()
1661254721Semaste        {
1662254721Semaste            stop.clear();
1663254721Semaste            notify.clear();
1664254721Semaste            pass.clear();
1665254721Semaste        }
1666254721Semaste
1667254721Semaste        const OptionDefinition*
1668254721Semaste        GetDefinitions ()
1669254721Semaste        {
1670254721Semaste            return g_option_table;
1671254721Semaste        }
1672254721Semaste
1673254721Semaste        // Options table: Required for subclasses of Options.
1674254721Semaste
1675254721Semaste        static OptionDefinition g_option_table[];
1676254721Semaste
1677254721Semaste        // Instance variables to hold the values for command options.
1678254721Semaste
1679254721Semaste        std::string stop;
1680254721Semaste        std::string notify;
1681254721Semaste        std::string pass;
1682254721Semaste    };
1683254721Semaste
1684254721Semaste
1685254721Semaste    CommandObjectProcessHandle (CommandInterpreter &interpreter) :
1686254721Semaste        CommandObjectParsed (interpreter,
1687254721Semaste                             "process handle",
1688254721Semaste                             "Show or update what the process and debugger should do with various signals received from the OS.",
1689254721Semaste                             NULL),
1690254721Semaste        m_options (interpreter)
1691254721Semaste    {
1692254721Semaste        SetHelpLong ("If no signals are specified, update them all.  If no update option is specified, list the current values.\n");
1693254721Semaste        CommandArgumentEntry arg;
1694254721Semaste        CommandArgumentData signal_arg;
1695254721Semaste
1696254721Semaste        signal_arg.arg_type = eArgTypeUnixSignal;
1697254721Semaste        signal_arg.arg_repetition = eArgRepeatStar;
1698254721Semaste
1699254721Semaste        arg.push_back (signal_arg);
1700254721Semaste
1701254721Semaste        m_arguments.push_back (arg);
1702254721Semaste    }
1703254721Semaste
1704254721Semaste    ~CommandObjectProcessHandle ()
1705254721Semaste    {
1706254721Semaste    }
1707254721Semaste
1708254721Semaste    Options *
1709254721Semaste    GetOptions ()
1710254721Semaste    {
1711254721Semaste        return &m_options;
1712254721Semaste    }
1713254721Semaste
1714254721Semaste    bool
1715254721Semaste    VerifyCommandOptionValue (const std::string &option, int &real_value)
1716254721Semaste    {
1717254721Semaste        bool okay = true;
1718254721Semaste
1719254721Semaste        bool success = false;
1720254721Semaste        bool tmp_value = Args::StringToBoolean (option.c_str(), false, &success);
1721254721Semaste
1722254721Semaste        if (success && tmp_value)
1723254721Semaste            real_value = 1;
1724254721Semaste        else if (success && !tmp_value)
1725254721Semaste            real_value = 0;
1726254721Semaste        else
1727254721Semaste        {
1728254721Semaste            // If the value isn't 'true' or 'false', it had better be 0 or 1.
1729254721Semaste            real_value = Args::StringToUInt32 (option.c_str(), 3);
1730254721Semaste            if (real_value != 0 && real_value != 1)
1731254721Semaste                okay = false;
1732254721Semaste        }
1733254721Semaste
1734254721Semaste        return okay;
1735254721Semaste    }
1736254721Semaste
1737254721Semaste    void
1738254721Semaste    PrintSignalHeader (Stream &str)
1739254721Semaste    {
1740254721Semaste        str.Printf ("NAME        PASS   STOP   NOTIFY\n");
1741254721Semaste        str.Printf ("==========  =====  =====  ======\n");
1742254721Semaste    }
1743254721Semaste
1744254721Semaste    void
1745254721Semaste    PrintSignal (Stream &str, int32_t signo, const char *sig_name, UnixSignals &signals)
1746254721Semaste    {
1747254721Semaste        bool stop;
1748254721Semaste        bool suppress;
1749254721Semaste        bool notify;
1750254721Semaste
1751254721Semaste        str.Printf ("%-10s  ", sig_name);
1752254721Semaste        if (signals.GetSignalInfo (signo, suppress, stop, notify))
1753254721Semaste        {
1754254721Semaste            bool pass = !suppress;
1755254721Semaste            str.Printf ("%s  %s  %s",
1756254721Semaste                        (pass ? "true " : "false"),
1757254721Semaste                        (stop ? "true " : "false"),
1758254721Semaste                        (notify ? "true " : "false"));
1759254721Semaste        }
1760254721Semaste        str.Printf ("\n");
1761254721Semaste    }
1762254721Semaste
1763254721Semaste    void
1764254721Semaste    PrintSignalInformation (Stream &str, Args &signal_args, int num_valid_signals, UnixSignals &signals)
1765254721Semaste    {
1766254721Semaste        PrintSignalHeader (str);
1767254721Semaste
1768254721Semaste        if (num_valid_signals > 0)
1769254721Semaste        {
1770254721Semaste            size_t num_args = signal_args.GetArgumentCount();
1771254721Semaste            for (size_t i = 0; i < num_args; ++i)
1772254721Semaste            {
1773254721Semaste                int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i));
1774254721Semaste                if (signo != LLDB_INVALID_SIGNAL_NUMBER)
1775254721Semaste                    PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals);
1776254721Semaste            }
1777254721Semaste        }
1778254721Semaste        else // Print info for ALL signals
1779254721Semaste        {
1780254721Semaste            int32_t signo = signals.GetFirstSignalNumber();
1781254721Semaste            while (signo != LLDB_INVALID_SIGNAL_NUMBER)
1782254721Semaste            {
1783254721Semaste                PrintSignal (str, signo, signals.GetSignalAsCString (signo), signals);
1784254721Semaste                signo = signals.GetNextSignalNumber (signo);
1785254721Semaste            }
1786254721Semaste        }
1787254721Semaste    }
1788254721Semaste
1789254721Semasteprotected:
1790254721Semaste    bool
1791254721Semaste    DoExecute (Args &signal_args, CommandReturnObject &result)
1792254721Semaste    {
1793254721Semaste        TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
1794254721Semaste
1795254721Semaste        if (!target_sp)
1796254721Semaste        {
1797254721Semaste            result.AppendError ("No current target;"
1798254721Semaste                                " cannot handle signals until you have a valid target and process.\n");
1799254721Semaste            result.SetStatus (eReturnStatusFailed);
1800254721Semaste            return false;
1801254721Semaste        }
1802254721Semaste
1803254721Semaste        ProcessSP process_sp = target_sp->GetProcessSP();
1804254721Semaste
1805254721Semaste        if (!process_sp)
1806254721Semaste        {
1807254721Semaste            result.AppendError ("No current process; cannot handle signals until you have a valid process.\n");
1808254721Semaste            result.SetStatus (eReturnStatusFailed);
1809254721Semaste            return false;
1810254721Semaste        }
1811254721Semaste
1812254721Semaste        int stop_action = -1;   // -1 means leave the current setting alone
1813254721Semaste        int pass_action = -1;   // -1 means leave the current setting alone
1814254721Semaste        int notify_action = -1; // -1 means leave the current setting alone
1815254721Semaste
1816254721Semaste        if (! m_options.stop.empty()
1817254721Semaste            && ! VerifyCommandOptionValue (m_options.stop, stop_action))
1818254721Semaste        {
1819254721Semaste            result.AppendError ("Invalid argument for command option --stop; must be true or false.\n");
1820254721Semaste            result.SetStatus (eReturnStatusFailed);
1821254721Semaste            return false;
1822254721Semaste        }
1823254721Semaste
1824254721Semaste        if (! m_options.notify.empty()
1825254721Semaste            && ! VerifyCommandOptionValue (m_options.notify, notify_action))
1826254721Semaste        {
1827254721Semaste            result.AppendError ("Invalid argument for command option --notify; must be true or false.\n");
1828254721Semaste            result.SetStatus (eReturnStatusFailed);
1829254721Semaste            return false;
1830254721Semaste        }
1831254721Semaste
1832254721Semaste        if (! m_options.pass.empty()
1833254721Semaste            && ! VerifyCommandOptionValue (m_options.pass, pass_action))
1834254721Semaste        {
1835254721Semaste            result.AppendError ("Invalid argument for command option --pass; must be true or false.\n");
1836254721Semaste            result.SetStatus (eReturnStatusFailed);
1837254721Semaste            return false;
1838254721Semaste        }
1839254721Semaste
1840254721Semaste        size_t num_args = signal_args.GetArgumentCount();
1841254721Semaste        UnixSignals &signals = process_sp->GetUnixSignals();
1842254721Semaste        int num_signals_set = 0;
1843254721Semaste
1844254721Semaste        if (num_args > 0)
1845254721Semaste        {
1846254721Semaste            for (size_t i = 0; i < num_args; ++i)
1847254721Semaste            {
1848254721Semaste                int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i));
1849254721Semaste                if (signo != LLDB_INVALID_SIGNAL_NUMBER)
1850254721Semaste                {
1851254721Semaste                    // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees
1852254721Semaste                    // the value is either 0 or 1.
1853254721Semaste                    if (stop_action != -1)
1854254721Semaste                        signals.SetShouldStop (signo, (bool) stop_action);
1855254721Semaste                    if (pass_action != -1)
1856254721Semaste                    {
1857254721Semaste                        bool suppress = ! ((bool) pass_action);
1858254721Semaste                        signals.SetShouldSuppress (signo, suppress);
1859254721Semaste                    }
1860254721Semaste                    if (notify_action != -1)
1861254721Semaste                        signals.SetShouldNotify (signo, (bool) notify_action);
1862254721Semaste                    ++num_signals_set;
1863254721Semaste                }
1864254721Semaste                else
1865254721Semaste                {
1866254721Semaste                    result.AppendErrorWithFormat ("Invalid signal name '%s'\n", signal_args.GetArgumentAtIndex (i));
1867254721Semaste                }
1868254721Semaste            }
1869254721Semaste        }
1870254721Semaste        else
1871254721Semaste        {
1872254721Semaste            // No signal specified, if any command options were specified, update ALL signals.
1873254721Semaste            if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1))
1874254721Semaste            {
1875254721Semaste                if (m_interpreter.Confirm ("Do you really want to update all the signals?", false))
1876254721Semaste                {
1877254721Semaste                    int32_t signo = signals.GetFirstSignalNumber();
1878254721Semaste                    while (signo != LLDB_INVALID_SIGNAL_NUMBER)
1879254721Semaste                    {
1880254721Semaste                        if (notify_action != -1)
1881254721Semaste                            signals.SetShouldNotify (signo, (bool) notify_action);
1882254721Semaste                        if (stop_action != -1)
1883254721Semaste                            signals.SetShouldStop (signo, (bool) stop_action);
1884254721Semaste                        if (pass_action != -1)
1885254721Semaste                        {
1886254721Semaste                            bool suppress = ! ((bool) pass_action);
1887254721Semaste                            signals.SetShouldSuppress (signo, suppress);
1888254721Semaste                        }
1889254721Semaste                        signo = signals.GetNextSignalNumber (signo);
1890254721Semaste                    }
1891254721Semaste                }
1892254721Semaste            }
1893254721Semaste        }
1894254721Semaste
1895254721Semaste        PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals);
1896254721Semaste
1897254721Semaste        if (num_signals_set > 0)
1898254721Semaste            result.SetStatus (eReturnStatusSuccessFinishNoResult);
1899254721Semaste        else
1900254721Semaste            result.SetStatus (eReturnStatusFailed);
1901254721Semaste
1902254721Semaste        return result.Succeeded();
1903254721Semaste    }
1904254721Semaste
1905254721Semaste    CommandOptions m_options;
1906254721Semaste};
1907254721Semaste
1908254721SemasteOptionDefinition
1909254721SemasteCommandObjectProcessHandle::CommandOptions::g_option_table[] =
1910254721Semaste{
1911254721Semaste{ 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." },
1912254721Semaste{ 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." },
1913254721Semaste{ LLDB_OPT_SET_1, false, "pass",  'p', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." },
1914254721Semaste{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1915254721Semaste};
1916254721Semaste
1917254721Semaste//-------------------------------------------------------------------------
1918254721Semaste// CommandObjectMultiwordProcess
1919254721Semaste//-------------------------------------------------------------------------
1920254721Semaste
1921254721SemasteCommandObjectMultiwordProcess::CommandObjectMultiwordProcess (CommandInterpreter &interpreter) :
1922254721Semaste    CommandObjectMultiword (interpreter,
1923254721Semaste                            "process",
1924254721Semaste                            "A set of commands for operating on a process.",
1925254721Semaste                            "process <subcommand> [<subcommand-options>]")
1926254721Semaste{
1927254721Semaste    LoadSubCommand ("attach",      CommandObjectSP (new CommandObjectProcessAttach    (interpreter)));
1928254721Semaste    LoadSubCommand ("launch",      CommandObjectSP (new CommandObjectProcessLaunch    (interpreter)));
1929254721Semaste    LoadSubCommand ("continue",    CommandObjectSP (new CommandObjectProcessContinue  (interpreter)));
1930254721Semaste    LoadSubCommand ("connect",     CommandObjectSP (new CommandObjectProcessConnect   (interpreter)));
1931254721Semaste    LoadSubCommand ("detach",      CommandObjectSP (new CommandObjectProcessDetach    (interpreter)));
1932254721Semaste    LoadSubCommand ("load",        CommandObjectSP (new CommandObjectProcessLoad      (interpreter)));
1933254721Semaste    LoadSubCommand ("unload",      CommandObjectSP (new CommandObjectProcessUnload    (interpreter)));
1934254721Semaste    LoadSubCommand ("signal",      CommandObjectSP (new CommandObjectProcessSignal    (interpreter)));
1935254721Semaste    LoadSubCommand ("handle",      CommandObjectSP (new CommandObjectProcessHandle    (interpreter)));
1936254721Semaste    LoadSubCommand ("status",      CommandObjectSP (new CommandObjectProcessStatus    (interpreter)));
1937254721Semaste    LoadSubCommand ("interrupt",   CommandObjectSP (new CommandObjectProcessInterrupt (interpreter)));
1938254721Semaste    LoadSubCommand ("kill",        CommandObjectSP (new CommandObjectProcessKill      (interpreter)));
1939254721Semaste    LoadSubCommand ("plugin",      CommandObjectSP (new CommandObjectProcessPlugin    (interpreter)));
1940254721Semaste}
1941254721Semaste
1942254721SemasteCommandObjectMultiwordProcess::~CommandObjectMultiwordProcess ()
1943254721Semaste{
1944254721Semaste}
1945254721Semaste
1946