1ac7ddfbfSEd Maste //===-- CommandObjectProcess.cpp --------------------------------*- C++ -*-===//
2ac7ddfbfSEd Maste //
3ac7ddfbfSEd Maste //                     The LLVM Compiler Infrastructure
4ac7ddfbfSEd Maste //
5ac7ddfbfSEd Maste // This file is distributed under the University of Illinois Open Source
6ac7ddfbfSEd Maste // License. See LICENSE.TXT for details.
7ac7ddfbfSEd Maste //
8ac7ddfbfSEd Maste //===----------------------------------------------------------------------===//
9ac7ddfbfSEd Maste 
10ac7ddfbfSEd Maste #include "CommandObjectProcess.h"
11ac7ddfbfSEd Maste 
12ac7ddfbfSEd Maste // C Includes
13ac7ddfbfSEd Maste // C++ Includes
14ac7ddfbfSEd Maste // Other libraries and framework includes
15ac7ddfbfSEd Maste // Project includes
16ac7ddfbfSEd Maste #include "lldb/Breakpoint/Breakpoint.h"
17ac7ddfbfSEd Maste #include "lldb/Breakpoint/BreakpointLocation.h"
18ac7ddfbfSEd Maste #include "lldb/Breakpoint/BreakpointSite.h"
19ac7ddfbfSEd Maste #include "lldb/Core/State.h"
20ac7ddfbfSEd Maste #include "lldb/Core/Module.h"
210127ef0fSEd Maste #include "lldb/Core/PluginManager.h"
22ac7ddfbfSEd Maste #include "lldb/Host/Host.h"
231c3bbb01SEd Maste #include "lldb/Host/StringConvert.h"
24ac7ddfbfSEd Maste #include "lldb/Interpreter/Args.h"
25ac7ddfbfSEd Maste #include "lldb/Interpreter/Options.h"
26ac7ddfbfSEd Maste #include "lldb/Interpreter/CommandInterpreter.h"
27ac7ddfbfSEd Maste #include "lldb/Interpreter/CommandReturnObject.h"
28ac7ddfbfSEd Maste #include "lldb/Target/Platform.h"
29ac7ddfbfSEd Maste #include "lldb/Target/Process.h"
30ac7ddfbfSEd Maste #include "lldb/Target/StopInfo.h"
31ac7ddfbfSEd Maste #include "lldb/Target/Target.h"
32ac7ddfbfSEd Maste #include "lldb/Target/Thread.h"
331c3bbb01SEd Maste #include "lldb/Target/UnixSignals.h"
34ac7ddfbfSEd Maste 
35ac7ddfbfSEd Maste using namespace lldb;
36ac7ddfbfSEd Maste using namespace lldb_private;
37ac7ddfbfSEd Maste 
38ac7ddfbfSEd Maste class CommandObjectProcessLaunchOrAttach : public CommandObjectParsed
39ac7ddfbfSEd Maste {
40ac7ddfbfSEd Maste public:
41ac7ddfbfSEd Maste     CommandObjectProcessLaunchOrAttach (CommandInterpreter &interpreter,
42ac7ddfbfSEd Maste                                        const char *name,
43ac7ddfbfSEd Maste                                        const char *help,
44ac7ddfbfSEd Maste                                        const char *syntax,
45ac7ddfbfSEd Maste                                        uint32_t flags,
46ac7ddfbfSEd Maste                                        const char *new_process_action) :
47ac7ddfbfSEd Maste         CommandObjectParsed (interpreter, name, help, syntax, flags),
48ac7ddfbfSEd Maste         m_new_process_action (new_process_action) {}
49ac7ddfbfSEd Maste 
509f2f44ceSEd Maste     ~CommandObjectProcessLaunchOrAttach () override {}
51ac7ddfbfSEd Maste protected:
52ac7ddfbfSEd Maste     bool
5312b93ac6SEd Maste     StopProcessIfNecessary (Process *process, StateType &state, CommandReturnObject &result)
54ac7ddfbfSEd Maste     {
55ac7ddfbfSEd Maste         state = eStateInvalid;
56ac7ddfbfSEd Maste         if (process)
57ac7ddfbfSEd Maste         {
58ac7ddfbfSEd Maste             state = process->GetState();
59ac7ddfbfSEd Maste 
60ac7ddfbfSEd Maste             if (process->IsAlive() && state != eStateConnected)
61ac7ddfbfSEd Maste             {
62ac7ddfbfSEd Maste                 char message[1024];
63ac7ddfbfSEd Maste                 if (process->GetState() == eStateAttaching)
64ac7ddfbfSEd Maste                     ::snprintf (message, sizeof(message), "There is a pending attach, abort it and %s?", m_new_process_action.c_str());
65ac7ddfbfSEd Maste                 else if (process->GetShouldDetach())
66ac7ddfbfSEd Maste                     ::snprintf (message, sizeof(message), "There is a running process, detach from it and %s?", m_new_process_action.c_str());
67ac7ddfbfSEd Maste                 else
68ac7ddfbfSEd Maste                     ::snprintf (message, sizeof(message), "There is a running process, kill it and %s?", m_new_process_action.c_str());
69ac7ddfbfSEd Maste 
70ac7ddfbfSEd Maste                 if (!m_interpreter.Confirm (message, true))
71ac7ddfbfSEd Maste                 {
72ac7ddfbfSEd Maste                     result.SetStatus (eReturnStatusFailed);
73ac7ddfbfSEd Maste                     return false;
74ac7ddfbfSEd Maste                 }
75ac7ddfbfSEd Maste                 else
76ac7ddfbfSEd Maste                 {
77ac7ddfbfSEd Maste                     if (process->GetShouldDetach())
78ac7ddfbfSEd Maste                     {
79ac7ddfbfSEd Maste                         bool keep_stopped = false;
80ac7ddfbfSEd Maste                         Error detach_error (process->Detach(keep_stopped));
81ac7ddfbfSEd Maste                         if (detach_error.Success())
82ac7ddfbfSEd Maste                         {
83ac7ddfbfSEd Maste                             result.SetStatus (eReturnStatusSuccessFinishResult);
84ac7ddfbfSEd Maste                             process = NULL;
85ac7ddfbfSEd Maste                         }
86ac7ddfbfSEd Maste                         else
87ac7ddfbfSEd Maste                         {
88ac7ddfbfSEd Maste                             result.AppendErrorWithFormat ("Failed to detach from process: %s\n", detach_error.AsCString());
89ac7ddfbfSEd Maste                             result.SetStatus (eReturnStatusFailed);
90ac7ddfbfSEd Maste                         }
91ac7ddfbfSEd Maste                     }
92ac7ddfbfSEd Maste                     else
93ac7ddfbfSEd Maste                     {
941c3bbb01SEd Maste                         Error destroy_error (process->Destroy(false));
95ac7ddfbfSEd Maste                         if (destroy_error.Success())
96ac7ddfbfSEd Maste                         {
97ac7ddfbfSEd Maste                             result.SetStatus (eReturnStatusSuccessFinishResult);
98ac7ddfbfSEd Maste                             process = NULL;
99ac7ddfbfSEd Maste                         }
100ac7ddfbfSEd Maste                         else
101ac7ddfbfSEd Maste                         {
102ac7ddfbfSEd Maste                             result.AppendErrorWithFormat ("Failed to kill process: %s\n", destroy_error.AsCString());
103ac7ddfbfSEd Maste                             result.SetStatus (eReturnStatusFailed);
104ac7ddfbfSEd Maste                         }
105ac7ddfbfSEd Maste                     }
106ac7ddfbfSEd Maste                 }
107ac7ddfbfSEd Maste             }
108ac7ddfbfSEd Maste         }
109ac7ddfbfSEd Maste         return result.Succeeded();
110ac7ddfbfSEd Maste     }
111ac7ddfbfSEd Maste     std::string m_new_process_action;
112ac7ddfbfSEd Maste };
113ac7ddfbfSEd Maste //-------------------------------------------------------------------------
114ac7ddfbfSEd Maste // CommandObjectProcessLaunch
115ac7ddfbfSEd Maste //-------------------------------------------------------------------------
116ac7ddfbfSEd Maste #pragma mark CommandObjectProcessLaunch
117ac7ddfbfSEd Maste class CommandObjectProcessLaunch : public CommandObjectProcessLaunchOrAttach
118ac7ddfbfSEd Maste {
119ac7ddfbfSEd Maste public:
120ac7ddfbfSEd Maste 
121ac7ddfbfSEd Maste     CommandObjectProcessLaunch (CommandInterpreter &interpreter) :
122ac7ddfbfSEd Maste         CommandObjectProcessLaunchOrAttach (interpreter,
123ac7ddfbfSEd Maste                                             "process launch",
124ac7ddfbfSEd Maste                                             "Launch the executable in the debugger.",
125ac7ddfbfSEd Maste                                             NULL,
1261c3bbb01SEd Maste                                             eCommandRequiresTarget,
127ac7ddfbfSEd Maste                                             "restart"),
128ac7ddfbfSEd Maste         m_options (interpreter)
129ac7ddfbfSEd Maste     {
130ac7ddfbfSEd Maste         CommandArgumentEntry arg;
131ac7ddfbfSEd Maste         CommandArgumentData run_args_arg;
132ac7ddfbfSEd Maste 
133ac7ddfbfSEd Maste         // Define the first (and only) variant of this arg.
134ac7ddfbfSEd Maste         run_args_arg.arg_type = eArgTypeRunArgs;
135ac7ddfbfSEd Maste         run_args_arg.arg_repetition = eArgRepeatOptional;
136ac7ddfbfSEd Maste 
137ac7ddfbfSEd Maste         // There is only one variant this argument could be; put it into the argument entry.
138ac7ddfbfSEd Maste         arg.push_back (run_args_arg);
139ac7ddfbfSEd Maste 
140ac7ddfbfSEd Maste         // Push the data for the first argument into the m_arguments vector.
141ac7ddfbfSEd Maste         m_arguments.push_back (arg);
142ac7ddfbfSEd Maste     }
143ac7ddfbfSEd Maste 
144ac7ddfbfSEd Maste 
1459f2f44ceSEd Maste     ~CommandObjectProcessLaunch () override
146ac7ddfbfSEd Maste     {
147ac7ddfbfSEd Maste     }
148ac7ddfbfSEd Maste 
1499f2f44ceSEd Maste     int
150ac7ddfbfSEd Maste     HandleArgumentCompletion (Args &input,
151ac7ddfbfSEd Maste                               int &cursor_index,
152ac7ddfbfSEd Maste                               int &cursor_char_position,
153ac7ddfbfSEd Maste                               OptionElementVector &opt_element_vector,
154ac7ddfbfSEd Maste                               int match_start_point,
155ac7ddfbfSEd Maste                               int max_return_elements,
156ac7ddfbfSEd Maste                               bool &word_complete,
1579f2f44ceSEd Maste                               StringList &matches) override
158ac7ddfbfSEd Maste     {
159ac7ddfbfSEd Maste         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
160ac7ddfbfSEd Maste         completion_str.erase (cursor_char_position);
161ac7ddfbfSEd Maste 
162ac7ddfbfSEd Maste         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
163ac7ddfbfSEd Maste                                                              CommandCompletions::eDiskFileCompletion,
164ac7ddfbfSEd Maste                                                              completion_str.c_str(),
165ac7ddfbfSEd Maste                                                              match_start_point,
166ac7ddfbfSEd Maste                                                              max_return_elements,
167ac7ddfbfSEd Maste                                                              NULL,
168ac7ddfbfSEd Maste                                                              word_complete,
169ac7ddfbfSEd Maste                                                              matches);
170ac7ddfbfSEd Maste         return matches.GetSize();
171ac7ddfbfSEd Maste     }
172ac7ddfbfSEd Maste 
173ac7ddfbfSEd Maste     Options *
1749f2f44ceSEd Maste     GetOptions () override
175ac7ddfbfSEd Maste     {
176ac7ddfbfSEd Maste         return &m_options;
177ac7ddfbfSEd Maste     }
178ac7ddfbfSEd Maste 
1799f2f44ceSEd Maste     const char *
1809f2f44ceSEd Maste     GetRepeatCommand (Args &current_command_args, uint32_t index) override
181ac7ddfbfSEd Maste     {
182ac7ddfbfSEd Maste         // No repeat for "process launch"...
183ac7ddfbfSEd Maste         return "";
184ac7ddfbfSEd Maste     }
185ac7ddfbfSEd Maste 
186ac7ddfbfSEd Maste protected:
187ac7ddfbfSEd Maste     bool
1889f2f44ceSEd Maste     DoExecute (Args& launch_args, CommandReturnObject &result) override
189ac7ddfbfSEd Maste     {
190ac7ddfbfSEd Maste         Debugger &debugger = m_interpreter.GetDebugger();
191ac7ddfbfSEd Maste         Target *target = debugger.GetSelectedTarget().get();
192ac7ddfbfSEd Maste         // If our listener is NULL, users aren't allows to launch
19312b93ac6SEd Maste         ModuleSP exe_module_sp = target->GetExecutableModule();
194ac7ddfbfSEd Maste 
19512b93ac6SEd Maste         if (exe_module_sp == NULL)
196ac7ddfbfSEd Maste         {
197ac7ddfbfSEd Maste             result.AppendError ("no file in target, create a debug target using the 'target create' command");
198ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
199ac7ddfbfSEd Maste             return false;
200ac7ddfbfSEd Maste         }
201ac7ddfbfSEd Maste 
202ac7ddfbfSEd Maste         StateType state = eStateInvalid;
203ac7ddfbfSEd Maste 
20412b93ac6SEd Maste         if (!StopProcessIfNecessary(m_exe_ctx.GetProcessPtr(), state, result))
205ac7ddfbfSEd Maste             return false;
206ac7ddfbfSEd Maste 
207ac7ddfbfSEd Maste         const char *target_settings_argv0 = target->GetArg0();
208ac7ddfbfSEd Maste 
2090127ef0fSEd Maste         // Determine whether we will disable ASLR or leave it in the default state (i.e. enabled if the platform supports it).
2100127ef0fSEd Maste         // First check if the process launch options explicitly turn on/off disabling ASLR.  If so, use that setting;
2110127ef0fSEd Maste         // otherwise, use the 'settings target.disable-aslr' setting.
2120127ef0fSEd Maste         bool disable_aslr = false;
2130127ef0fSEd Maste         if (m_options.disable_aslr != eLazyBoolCalculate)
2140127ef0fSEd Maste         {
2150127ef0fSEd Maste             // The user specified an explicit setting on the process launch line.  Use it.
2160127ef0fSEd Maste             disable_aslr = (m_options.disable_aslr == eLazyBoolYes);
2170127ef0fSEd Maste         }
2180127ef0fSEd Maste         else
2190127ef0fSEd Maste         {
2200127ef0fSEd Maste             // The user did not explicitly specify whether to disable ASLR.  Fall back to the target.disable-aslr setting.
2210127ef0fSEd Maste             disable_aslr = target->GetDisableASLR ();
2220127ef0fSEd Maste         }
2230127ef0fSEd Maste 
2240127ef0fSEd Maste         if (disable_aslr)
22512b93ac6SEd Maste             m_options.launch_info.GetFlags().Set (eLaunchFlagDisableASLR);
2260127ef0fSEd Maste         else
2270127ef0fSEd Maste             m_options.launch_info.GetFlags().Clear (eLaunchFlagDisableASLR);
2280127ef0fSEd Maste 
2290127ef0fSEd Maste         if (target->GetDetachOnError())
2300127ef0fSEd Maste             m_options.launch_info.GetFlags().Set (eLaunchFlagDetachOnError);
23112b93ac6SEd Maste 
23212b93ac6SEd Maste         if (target->GetDisableSTDIO())
23312b93ac6SEd Maste             m_options.launch_info.GetFlags().Set (eLaunchFlagDisableSTDIO);
23412b93ac6SEd Maste 
23512b93ac6SEd Maste         Args environment;
23612b93ac6SEd Maste         target->GetEnvironmentAsArgs (environment);
23712b93ac6SEd Maste         if (environment.GetArgumentCount() > 0)
23812b93ac6SEd Maste             m_options.launch_info.GetEnvironmentEntries ().AppendArguments (environment);
239ac7ddfbfSEd Maste 
240ac7ddfbfSEd Maste         if (target_settings_argv0)
241ac7ddfbfSEd Maste         {
242ac7ddfbfSEd Maste             m_options.launch_info.GetArguments().AppendArgument (target_settings_argv0);
24312b93ac6SEd Maste             m_options.launch_info.SetExecutableFile(exe_module_sp->GetPlatformFileSpec(), false);
244ac7ddfbfSEd Maste         }
245ac7ddfbfSEd Maste         else
246ac7ddfbfSEd Maste         {
24712b93ac6SEd Maste             m_options.launch_info.SetExecutableFile(exe_module_sp->GetPlatformFileSpec(), true);
248ac7ddfbfSEd Maste         }
249ac7ddfbfSEd Maste 
250ac7ddfbfSEd Maste         if (launch_args.GetArgumentCount() == 0)
251ac7ddfbfSEd Maste         {
2521c3bbb01SEd Maste             m_options.launch_info.GetArguments().AppendArguments (target->GetProcessLaunchInfo().GetArguments());
253ac7ddfbfSEd Maste         }
254ac7ddfbfSEd Maste         else
255ac7ddfbfSEd Maste         {
256ac7ddfbfSEd Maste             m_options.launch_info.GetArguments().AppendArguments (launch_args);
257ac7ddfbfSEd Maste             // Save the arguments for subsequent runs in the current target.
258ac7ddfbfSEd Maste             target->SetRunArguments (launch_args);
259ac7ddfbfSEd Maste         }
260ac7ddfbfSEd Maste 
2617aa51b79SEd Maste         StreamString stream;
2627aa51b79SEd Maste         Error error = target->Launch(m_options.launch_info, &stream);
263ac7ddfbfSEd Maste 
264ac7ddfbfSEd Maste         if (error.Success())
265ac7ddfbfSEd Maste         {
26612b93ac6SEd Maste             ProcessSP process_sp (target->GetProcessSP());
26712b93ac6SEd Maste             if (process_sp)
268ac7ddfbfSEd Maste             {
2691c3bbb01SEd Maste                 // There is a race condition where this thread will return up the call stack to the main command
2701c3bbb01SEd Maste                 // handler and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has
2711c3bbb01SEd Maste                 // a chance to call PushProcessIOHandler().
2721c3bbb01SEd Maste                 process_sp->SyncIOHandler (0, 2000);
2731c3bbb01SEd Maste 
2747aa51b79SEd Maste                 const char *data = stream.GetData();
2757aa51b79SEd Maste                 if (data && strlen(data) > 0)
2767aa51b79SEd Maste                     result.AppendMessage(stream.GetData());
2771c3bbb01SEd Maste                 const char *archname = exe_module_sp->GetArchitecture().GetArchitectureName();
27812b93ac6SEd Maste                 result.AppendMessageWithFormat ("Process %" PRIu64 " launched: '%s' (%s)\n", process_sp->GetID(), exe_module_sp->GetFileSpec().GetPath().c_str(), archname);
279ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusSuccessFinishResult);
28012b93ac6SEd Maste                 result.SetDidChangeProcessState (true);
281ac7ddfbfSEd Maste             }
282ac7ddfbfSEd Maste             else
283ac7ddfbfSEd Maste             {
28412b93ac6SEd Maste                 result.AppendError("no error returned from Target::Launch, and target has no process");
285ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusFailed);
286ac7ddfbfSEd Maste             }
287ac7ddfbfSEd Maste         }
288ac7ddfbfSEd Maste         else
289ac7ddfbfSEd Maste         {
29012b93ac6SEd Maste             result.AppendError(error.AsCString());
291ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
292ac7ddfbfSEd Maste         }
293ac7ddfbfSEd Maste         return result.Succeeded();
294ac7ddfbfSEd Maste     }
295ac7ddfbfSEd Maste 
296ac7ddfbfSEd Maste protected:
297ac7ddfbfSEd Maste     ProcessLaunchCommandOptions m_options;
298ac7ddfbfSEd Maste };
299ac7ddfbfSEd Maste 
300ac7ddfbfSEd Maste 
301ac7ddfbfSEd Maste //#define SET1 LLDB_OPT_SET_1
302ac7ddfbfSEd Maste //#define SET2 LLDB_OPT_SET_2
303ac7ddfbfSEd Maste //#define SET3 LLDB_OPT_SET_3
304ac7ddfbfSEd Maste //
305ac7ddfbfSEd Maste //OptionDefinition
306ac7ddfbfSEd Maste //CommandObjectProcessLaunch::CommandOptions::g_option_table[] =
307ac7ddfbfSEd Maste //{
30835617911SEd Maste //{ SET1 | SET2 | SET3, false, "stop-at-entry", 's', OptionParser::eNoArgument,       NULL, 0, eArgTypeNone,    "Stop at the entry point of the program when launching a process."},
30935617911SEd Maste //{ SET1              , false, "stdin",         'i', OptionParser::eRequiredArgument, NULL, 0, eArgTypeDirectoryName,    "Redirect stdin for the process to <path>."},
31035617911SEd Maste //{ SET1              , false, "stdout",        'o', OptionParser::eRequiredArgument, NULL, 0, eArgTypeDirectoryName,    "Redirect stdout for the process to <path>."},
31135617911SEd Maste //{ SET1              , false, "stderr",        'e', OptionParser::eRequiredArgument, NULL, 0, eArgTypeDirectoryName,    "Redirect stderr for the process to <path>."},
31235617911SEd Maste //{ SET1 | SET2 | SET3, false, "plugin",        'p', OptionParser::eRequiredArgument, NULL, 0, eArgTypePlugin,  "Name of the process plugin you want to use."},
31335617911SEd Maste //{        SET2       , false, "tty",           't', OptionParser::eOptionalArgument, NULL, 0, eArgTypeDirectoryName,    "Start the process in a terminal. If <path> is specified, look for a terminal whose name contains <path>, else start the process in a new terminal."},
31435617911SEd Maste //{               SET3, false, "no-stdio",      'n', OptionParser::eNoArgument,       NULL, 0, eArgTypeNone,    "Do not set up for terminal I/O to go to running process."},
31535617911SEd Maste //{ SET1 | SET2 | SET3, false, "working-dir",   'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeDirectoryName,    "Set the current working directory to <path> when running the inferior."},
316ac7ddfbfSEd Maste //{ 0,                  false, NULL,             0,  0,                 NULL, 0, eArgTypeNone,    NULL }
317ac7ddfbfSEd Maste //};
318ac7ddfbfSEd Maste //
319ac7ddfbfSEd Maste //#undef SET1
320ac7ddfbfSEd Maste //#undef SET2
321ac7ddfbfSEd Maste //#undef SET3
322ac7ddfbfSEd Maste 
323ac7ddfbfSEd Maste //-------------------------------------------------------------------------
324ac7ddfbfSEd Maste // CommandObjectProcessAttach
325ac7ddfbfSEd Maste //-------------------------------------------------------------------------
326ac7ddfbfSEd Maste #pragma mark CommandObjectProcessAttach
327ac7ddfbfSEd Maste class CommandObjectProcessAttach : public CommandObjectProcessLaunchOrAttach
328ac7ddfbfSEd Maste {
329ac7ddfbfSEd Maste public:
330ac7ddfbfSEd Maste 
331ac7ddfbfSEd Maste     class CommandOptions : public Options
332ac7ddfbfSEd Maste     {
333ac7ddfbfSEd Maste     public:
334ac7ddfbfSEd Maste 
335ac7ddfbfSEd Maste         CommandOptions (CommandInterpreter &interpreter) :
336ac7ddfbfSEd Maste             Options(interpreter)
337ac7ddfbfSEd Maste         {
338ac7ddfbfSEd Maste             // Keep default values of all options in one place: OptionParsingStarting ()
339ac7ddfbfSEd Maste             OptionParsingStarting ();
340ac7ddfbfSEd Maste         }
341ac7ddfbfSEd Maste 
3429f2f44ceSEd Maste         ~CommandOptions () override
343ac7ddfbfSEd Maste         {
344ac7ddfbfSEd Maste         }
345ac7ddfbfSEd Maste 
346ac7ddfbfSEd Maste         Error
3479f2f44ceSEd Maste         SetOptionValue (uint32_t option_idx, const char *option_arg) override
348ac7ddfbfSEd Maste         {
349ac7ddfbfSEd Maste             Error error;
350ac7ddfbfSEd Maste             const int short_option = m_getopt_table[option_idx].val;
351ac7ddfbfSEd Maste             bool success = false;
352ac7ddfbfSEd Maste             switch (short_option)
353ac7ddfbfSEd Maste             {
354ac7ddfbfSEd Maste                 case 'c':
355ac7ddfbfSEd Maste                     attach_info.SetContinueOnceAttached(true);
356ac7ddfbfSEd Maste                     break;
357ac7ddfbfSEd Maste 
358ac7ddfbfSEd Maste                 case 'p':
359ac7ddfbfSEd Maste                     {
3601c3bbb01SEd Maste                         lldb::pid_t pid = StringConvert::ToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success);
361ac7ddfbfSEd Maste                         if (!success || pid == LLDB_INVALID_PROCESS_ID)
362ac7ddfbfSEd Maste                         {
363ac7ddfbfSEd Maste                             error.SetErrorStringWithFormat("invalid process ID '%s'", option_arg);
364ac7ddfbfSEd Maste                         }
365ac7ddfbfSEd Maste                         else
366ac7ddfbfSEd Maste                         {
367ac7ddfbfSEd Maste                             attach_info.SetProcessID (pid);
368ac7ddfbfSEd Maste                         }
369ac7ddfbfSEd Maste                     }
370ac7ddfbfSEd Maste                     break;
371ac7ddfbfSEd Maste 
372ac7ddfbfSEd Maste                 case 'P':
373ac7ddfbfSEd Maste                     attach_info.SetProcessPluginName (option_arg);
374ac7ddfbfSEd Maste                     break;
375ac7ddfbfSEd Maste 
376ac7ddfbfSEd Maste                 case 'n':
377ac7ddfbfSEd Maste                     attach_info.GetExecutableFile().SetFile(option_arg, false);
378ac7ddfbfSEd Maste                     break;
379ac7ddfbfSEd Maste 
380ac7ddfbfSEd Maste                 case 'w':
381ac7ddfbfSEd Maste                     attach_info.SetWaitForLaunch(true);
382ac7ddfbfSEd Maste                     break;
383ac7ddfbfSEd Maste 
384ac7ddfbfSEd Maste                 case 'i':
385ac7ddfbfSEd Maste                     attach_info.SetIgnoreExisting(false);
386ac7ddfbfSEd Maste                     break;
387ac7ddfbfSEd Maste 
388ac7ddfbfSEd Maste                 default:
389ac7ddfbfSEd Maste                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
390ac7ddfbfSEd Maste                     break;
391ac7ddfbfSEd Maste             }
392ac7ddfbfSEd Maste             return error;
393ac7ddfbfSEd Maste         }
394ac7ddfbfSEd Maste 
395ac7ddfbfSEd Maste         void
3969f2f44ceSEd Maste         OptionParsingStarting () override
397ac7ddfbfSEd Maste         {
398ac7ddfbfSEd Maste             attach_info.Clear();
399ac7ddfbfSEd Maste         }
400ac7ddfbfSEd Maste 
401ac7ddfbfSEd Maste         const OptionDefinition*
4029f2f44ceSEd Maste         GetDefinitions () override
403ac7ddfbfSEd Maste         {
404ac7ddfbfSEd Maste             return g_option_table;
405ac7ddfbfSEd Maste         }
406ac7ddfbfSEd Maste 
4079f2f44ceSEd Maste         bool
408ac7ddfbfSEd Maste         HandleOptionArgumentCompletion (Args &input,
409ac7ddfbfSEd Maste                                         int cursor_index,
410ac7ddfbfSEd Maste                                         int char_pos,
411ac7ddfbfSEd Maste                                         OptionElementVector &opt_element_vector,
412ac7ddfbfSEd Maste                                         int opt_element_index,
413ac7ddfbfSEd Maste                                         int match_start_point,
414ac7ddfbfSEd Maste                                         int max_return_elements,
415ac7ddfbfSEd Maste                                         bool &word_complete,
4169f2f44ceSEd Maste                                         StringList &matches) override
417ac7ddfbfSEd Maste         {
418ac7ddfbfSEd Maste             int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
419ac7ddfbfSEd Maste             int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
420ac7ddfbfSEd Maste 
421ac7ddfbfSEd Maste             // We are only completing the name option for now...
422ac7ddfbfSEd Maste 
423ac7ddfbfSEd Maste             const OptionDefinition *opt_defs = GetDefinitions();
424ac7ddfbfSEd Maste             if (opt_defs[opt_defs_index].short_option == 'n')
425ac7ddfbfSEd Maste             {
426ac7ddfbfSEd Maste                 // Are we in the name?
427ac7ddfbfSEd Maste 
428ac7ddfbfSEd Maste                 // Look to see if there is a -P argument provided, and if so use that plugin, otherwise
429ac7ddfbfSEd Maste                 // use the default plugin.
430ac7ddfbfSEd Maste 
431ac7ddfbfSEd Maste                 const char *partial_name = NULL;
432ac7ddfbfSEd Maste                 partial_name = input.GetArgumentAtIndex(opt_arg_pos);
433ac7ddfbfSEd Maste 
434ac7ddfbfSEd Maste                 PlatformSP platform_sp (m_interpreter.GetPlatform (true));
435ac7ddfbfSEd Maste                 if (platform_sp)
436ac7ddfbfSEd Maste                 {
437ac7ddfbfSEd Maste                     ProcessInstanceInfoList process_infos;
438ac7ddfbfSEd Maste                     ProcessInstanceInfoMatch match_info;
439ac7ddfbfSEd Maste                     if (partial_name)
440ac7ddfbfSEd Maste                     {
441ac7ddfbfSEd Maste                         match_info.GetProcessInfo().GetExecutableFile().SetFile(partial_name, false);
442ac7ddfbfSEd Maste                         match_info.SetNameMatchType(eNameMatchStartsWith);
443ac7ddfbfSEd Maste                     }
444ac7ddfbfSEd Maste                     platform_sp->FindProcesses (match_info, process_infos);
445ac7ddfbfSEd Maste                     const size_t num_matches = process_infos.GetSize();
446ac7ddfbfSEd Maste                     if (num_matches > 0)
447ac7ddfbfSEd Maste                     {
448ac7ddfbfSEd Maste                         for (size_t i=0; i<num_matches; ++i)
449ac7ddfbfSEd Maste                         {
450ac7ddfbfSEd Maste                             matches.AppendString (process_infos.GetProcessNameAtIndex(i),
451ac7ddfbfSEd Maste                                                   process_infos.GetProcessNameLengthAtIndex(i));
452ac7ddfbfSEd Maste                         }
453ac7ddfbfSEd Maste                     }
454ac7ddfbfSEd Maste                 }
455ac7ddfbfSEd Maste             }
456ac7ddfbfSEd Maste 
457ac7ddfbfSEd Maste             return false;
458ac7ddfbfSEd Maste         }
459ac7ddfbfSEd Maste 
460ac7ddfbfSEd Maste         // Options table: Required for subclasses of Options.
461ac7ddfbfSEd Maste 
462ac7ddfbfSEd Maste         static OptionDefinition g_option_table[];
463ac7ddfbfSEd Maste 
464ac7ddfbfSEd Maste         // Instance variables to hold the values for command options.
465ac7ddfbfSEd Maste 
466ac7ddfbfSEd Maste         ProcessAttachInfo attach_info;
467ac7ddfbfSEd Maste     };
468ac7ddfbfSEd Maste 
469ac7ddfbfSEd Maste     CommandObjectProcessAttach (CommandInterpreter &interpreter) :
470ac7ddfbfSEd Maste         CommandObjectProcessLaunchOrAttach (interpreter,
471ac7ddfbfSEd Maste                                             "process attach",
472ac7ddfbfSEd Maste                                             "Attach to a process.",
473ac7ddfbfSEd Maste                                             "process attach <cmd-options>",
474ac7ddfbfSEd Maste                                             0,
475ac7ddfbfSEd Maste                                             "attach"),
476ac7ddfbfSEd Maste         m_options (interpreter)
477ac7ddfbfSEd Maste     {
478ac7ddfbfSEd Maste     }
479ac7ddfbfSEd Maste 
4809f2f44ceSEd Maste     ~CommandObjectProcessAttach () override
481ac7ddfbfSEd Maste     {
482ac7ddfbfSEd Maste     }
483ac7ddfbfSEd Maste 
484ac7ddfbfSEd Maste     Options *
4859f2f44ceSEd Maste     GetOptions () override
486ac7ddfbfSEd Maste     {
487ac7ddfbfSEd Maste         return &m_options;
488ac7ddfbfSEd Maste     }
489ac7ddfbfSEd Maste 
490ac7ddfbfSEd Maste protected:
491ac7ddfbfSEd Maste     bool
4929f2f44ceSEd Maste     DoExecute (Args& command, CommandReturnObject &result) override
493ac7ddfbfSEd Maste     {
4941c3bbb01SEd Maste         PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
4951c3bbb01SEd Maste 
496ac7ddfbfSEd Maste         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
497ac7ddfbfSEd Maste         // N.B. The attach should be synchronous.  It doesn't help much to get the prompt back between initiating the attach
498ac7ddfbfSEd Maste         // and the target actually stopping.  So even if the interpreter is set to be asynchronous, we wait for the stop
499ac7ddfbfSEd Maste         // ourselves here.
500ac7ddfbfSEd Maste 
501ac7ddfbfSEd Maste         StateType state = eStateInvalid;
502ac7ddfbfSEd Maste         Process *process = m_exe_ctx.GetProcessPtr();
503ac7ddfbfSEd Maste 
504ac7ddfbfSEd Maste         if (!StopProcessIfNecessary (process, state, result))
505ac7ddfbfSEd Maste             return false;
506ac7ddfbfSEd Maste 
507ac7ddfbfSEd Maste         if (target == NULL)
508ac7ddfbfSEd Maste         {
509ac7ddfbfSEd Maste             // If there isn't a current target create one.
510ac7ddfbfSEd Maste             TargetSP new_target_sp;
511ac7ddfbfSEd Maste             Error error;
512ac7ddfbfSEd Maste 
513ac7ddfbfSEd Maste             error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(),
514ac7ddfbfSEd Maste                                                                               NULL,
515ac7ddfbfSEd Maste                                                                               NULL,
516ac7ddfbfSEd Maste                                                                               false,
517ac7ddfbfSEd Maste                                                                               NULL, // No platform options
518ac7ddfbfSEd Maste                                                                               new_target_sp);
519ac7ddfbfSEd Maste             target = new_target_sp.get();
520ac7ddfbfSEd Maste             if (target == NULL || error.Fail())
521ac7ddfbfSEd Maste             {
522ac7ddfbfSEd Maste                 result.AppendError(error.AsCString("Error creating target"));
523ac7ddfbfSEd Maste                 return false;
524ac7ddfbfSEd Maste             }
525ac7ddfbfSEd Maste             m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target);
526ac7ddfbfSEd Maste         }
527ac7ddfbfSEd Maste 
528ac7ddfbfSEd Maste         // Record the old executable module, we want to issue a warning if the process of attaching changed the
529ac7ddfbfSEd Maste         // current executable (like somebody said "file foo" then attached to a PID whose executable was bar.)
530ac7ddfbfSEd Maste 
531ac7ddfbfSEd Maste         ModuleSP old_exec_module_sp = target->GetExecutableModule();
532ac7ddfbfSEd Maste         ArchSpec old_arch_spec = target->GetArchitecture();
533ac7ddfbfSEd Maste 
534ac7ddfbfSEd Maste         if (command.GetArgumentCount())
535ac7ddfbfSEd Maste         {
536ac7ddfbfSEd Maste             result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
537ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
5381c3bbb01SEd Maste             return false;
539ac7ddfbfSEd Maste         }
540ac7ddfbfSEd Maste 
5411c3bbb01SEd Maste         m_interpreter.UpdateExecutionContext(nullptr);
5427aa51b79SEd Maste         StreamString stream;
5431c3bbb01SEd Maste         const auto error = target->Attach(m_options.attach_info, &stream);
5441c3bbb01SEd Maste         if (error.Success())
5451c3bbb01SEd Maste         {
5461c3bbb01SEd Maste             ProcessSP process_sp (target->GetProcessSP());
5471c3bbb01SEd Maste             if (process_sp)
5481c3bbb01SEd Maste             {
5497aa51b79SEd Maste                 if (stream.GetData())
5507aa51b79SEd Maste                     result.AppendMessage(stream.GetData());
551ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
5521c3bbb01SEd Maste                 result.SetDidChangeProcessState (true);
553ac7ddfbfSEd Maste             }
554ac7ddfbfSEd Maste             else
555ac7ddfbfSEd Maste             {
5561c3bbb01SEd Maste                 result.AppendError("no error returned from Target::Attach, and target has no process");
557ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusFailed);
55812b93ac6SEd Maste             }
55912b93ac6SEd Maste         }
56012b93ac6SEd Maste         else
56112b93ac6SEd Maste         {
56212b93ac6SEd Maste             result.AppendErrorWithFormat ("attach failed: %s\n", error.AsCString());
56312b93ac6SEd Maste             result.SetStatus (eReturnStatusFailed);
564ac7ddfbfSEd Maste         }
565ac7ddfbfSEd Maste 
5661c3bbb01SEd Maste         if (!result.Succeeded())
5671c3bbb01SEd Maste             return false;
5681c3bbb01SEd Maste 
569ac7ddfbfSEd Maste         // Okay, we're done.  Last step is to warn if the executable module has changed:
570ac7ddfbfSEd Maste         char new_path[PATH_MAX];
571ac7ddfbfSEd Maste         ModuleSP new_exec_module_sp (target->GetExecutableModule());
572ac7ddfbfSEd Maste         if (!old_exec_module_sp)
573ac7ddfbfSEd Maste         {
574ac7ddfbfSEd Maste             // We might not have a module if we attached to a raw pid...
575ac7ddfbfSEd Maste             if (new_exec_module_sp)
576ac7ddfbfSEd Maste             {
577ac7ddfbfSEd Maste                 new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX);
578ac7ddfbfSEd Maste                 result.AppendMessageWithFormat("Executable module set to \"%s\".\n", new_path);
579ac7ddfbfSEd Maste             }
580ac7ddfbfSEd Maste         }
581ac7ddfbfSEd Maste         else if (old_exec_module_sp->GetFileSpec() != new_exec_module_sp->GetFileSpec())
582ac7ddfbfSEd Maste         {
583ac7ddfbfSEd Maste             char old_path[PATH_MAX];
584ac7ddfbfSEd Maste 
585ac7ddfbfSEd Maste             old_exec_module_sp->GetFileSpec().GetPath (old_path, PATH_MAX);
586ac7ddfbfSEd Maste             new_exec_module_sp->GetFileSpec().GetPath (new_path, PATH_MAX);
587ac7ddfbfSEd Maste 
588ac7ddfbfSEd Maste             result.AppendWarningWithFormat("Executable module changed from \"%s\" to \"%s\".\n",
589ac7ddfbfSEd Maste                                                 old_path, new_path);
590ac7ddfbfSEd Maste         }
591ac7ddfbfSEd Maste 
592ac7ddfbfSEd Maste         if (!old_arch_spec.IsValid())
593ac7ddfbfSEd Maste         {
594ac7ddfbfSEd Maste             result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().GetTriple().getTriple().c_str());
595ac7ddfbfSEd Maste         }
596ac7ddfbfSEd Maste         else if (!old_arch_spec.IsExactMatch(target->GetArchitecture()))
597ac7ddfbfSEd Maste         {
598ac7ddfbfSEd Maste             result.AppendWarningWithFormat("Architecture changed from %s to %s.\n",
599ac7ddfbfSEd Maste                                            old_arch_spec.GetTriple().getTriple().c_str(),
600ac7ddfbfSEd Maste                                            target->GetArchitecture().GetTriple().getTriple().c_str());
601ac7ddfbfSEd Maste         }
602ac7ddfbfSEd Maste 
603ac7ddfbfSEd Maste         // This supports the use-case scenario of immediately continuing the process once attached.
604ac7ddfbfSEd Maste         if (m_options.attach_info.GetContinueOnceAttached())
605ac7ddfbfSEd Maste             m_interpreter.HandleCommand("process continue", eLazyBoolNo, result);
6061c3bbb01SEd Maste 
607ac7ddfbfSEd Maste         return result.Succeeded();
608ac7ddfbfSEd Maste     }
609ac7ddfbfSEd Maste 
610ac7ddfbfSEd Maste     CommandOptions m_options;
611ac7ddfbfSEd Maste };
612ac7ddfbfSEd Maste 
613ac7ddfbfSEd Maste 
614ac7ddfbfSEd Maste OptionDefinition
615ac7ddfbfSEd Maste CommandObjectProcessAttach::CommandOptions::g_option_table[] =
616ac7ddfbfSEd Maste {
6170127ef0fSEd Maste { LLDB_OPT_SET_ALL, false, "continue",'c', OptionParser::eNoArgument,         NULL, NULL, 0, eArgTypeNone,         "Immediately continue the process once attached."},
6180127ef0fSEd Maste { LLDB_OPT_SET_ALL, false, "plugin",  'P', OptionParser::eRequiredArgument,   NULL, NULL, 0, eArgTypePlugin,       "Name of the process plugin you want to use."},
6190127ef0fSEd Maste { LLDB_OPT_SET_1,   false, "pid",     'p', OptionParser::eRequiredArgument,   NULL, NULL, 0, eArgTypePid,          "The process ID of an existing process to attach to."},
6200127ef0fSEd Maste { LLDB_OPT_SET_2,   false, "name",    'n', OptionParser::eRequiredArgument,   NULL, NULL, 0, eArgTypeProcessName,  "The name of the process to attach to."},
6210127ef0fSEd Maste { LLDB_OPT_SET_2,   false, "include-existing", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,         "Include existing processes when doing attach -w."},
6220127ef0fSEd Maste { LLDB_OPT_SET_2,   false, "waitfor", 'w', OptionParser::eNoArgument,         NULL, NULL, 0, eArgTypeNone,         "Wait for the process with <process-name> to launch."},
6230127ef0fSEd Maste { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
624ac7ddfbfSEd Maste };
625ac7ddfbfSEd Maste 
626ac7ddfbfSEd Maste //-------------------------------------------------------------------------
627ac7ddfbfSEd Maste // CommandObjectProcessContinue
628ac7ddfbfSEd Maste //-------------------------------------------------------------------------
629ac7ddfbfSEd Maste #pragma mark CommandObjectProcessContinue
630ac7ddfbfSEd Maste 
631ac7ddfbfSEd Maste class CommandObjectProcessContinue : public CommandObjectParsed
632ac7ddfbfSEd Maste {
633ac7ddfbfSEd Maste public:
634ac7ddfbfSEd Maste 
635ac7ddfbfSEd Maste     CommandObjectProcessContinue (CommandInterpreter &interpreter) :
636ac7ddfbfSEd Maste         CommandObjectParsed (interpreter,
637ac7ddfbfSEd Maste                              "process continue",
638ac7ddfbfSEd Maste                              "Continue execution of all threads in the current process.",
639ac7ddfbfSEd Maste                              "process continue",
6401c3bbb01SEd Maste                              eCommandRequiresProcess       |
6411c3bbb01SEd Maste                              eCommandTryTargetAPILock      |
6421c3bbb01SEd Maste                              eCommandProcessMustBeLaunched |
6431c3bbb01SEd Maste                              eCommandProcessMustBePaused   ),
644ac7ddfbfSEd Maste         m_options(interpreter)
645ac7ddfbfSEd Maste     {
646ac7ddfbfSEd Maste     }
647ac7ddfbfSEd Maste 
648ac7ddfbfSEd Maste 
6499f2f44ceSEd Maste     ~CommandObjectProcessContinue () override
650ac7ddfbfSEd Maste     {
651ac7ddfbfSEd Maste     }
652ac7ddfbfSEd Maste 
653ac7ddfbfSEd Maste protected:
654ac7ddfbfSEd Maste 
655ac7ddfbfSEd Maste     class CommandOptions : public Options
656ac7ddfbfSEd Maste     {
657ac7ddfbfSEd Maste     public:
658ac7ddfbfSEd Maste 
659ac7ddfbfSEd Maste         CommandOptions (CommandInterpreter &interpreter) :
660ac7ddfbfSEd Maste             Options(interpreter)
661ac7ddfbfSEd Maste         {
662ac7ddfbfSEd Maste             // Keep default values of all options in one place: OptionParsingStarting ()
663ac7ddfbfSEd Maste             OptionParsingStarting ();
664ac7ddfbfSEd Maste         }
665ac7ddfbfSEd Maste 
6669f2f44ceSEd Maste         ~CommandOptions () override
667ac7ddfbfSEd Maste         {
668ac7ddfbfSEd Maste         }
669ac7ddfbfSEd Maste 
670ac7ddfbfSEd Maste         Error
6719f2f44ceSEd Maste         SetOptionValue (uint32_t option_idx, const char *option_arg) override
672ac7ddfbfSEd Maste         {
673ac7ddfbfSEd Maste             Error error;
674ac7ddfbfSEd Maste             const int short_option = m_getopt_table[option_idx].val;
675ac7ddfbfSEd Maste             bool success = false;
676ac7ddfbfSEd Maste             switch (short_option)
677ac7ddfbfSEd Maste             {
678ac7ddfbfSEd Maste                 case 'i':
6791c3bbb01SEd Maste                     m_ignore = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
680ac7ddfbfSEd Maste                     if (!success)
681ac7ddfbfSEd Maste                         error.SetErrorStringWithFormat ("invalid value for ignore option: \"%s\", should be a number.", option_arg);
682ac7ddfbfSEd Maste                     break;
683ac7ddfbfSEd Maste 
684ac7ddfbfSEd Maste                 default:
685ac7ddfbfSEd Maste                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
686ac7ddfbfSEd Maste                     break;
687ac7ddfbfSEd Maste             }
688ac7ddfbfSEd Maste             return error;
689ac7ddfbfSEd Maste         }
690ac7ddfbfSEd Maste 
691ac7ddfbfSEd Maste         void
6929f2f44ceSEd Maste         OptionParsingStarting () override
693ac7ddfbfSEd Maste         {
694ac7ddfbfSEd Maste             m_ignore = 0;
695ac7ddfbfSEd Maste         }
696ac7ddfbfSEd Maste 
697ac7ddfbfSEd Maste         const OptionDefinition*
6989f2f44ceSEd Maste         GetDefinitions () override
699ac7ddfbfSEd Maste         {
700ac7ddfbfSEd Maste             return g_option_table;
701ac7ddfbfSEd Maste         }
702ac7ddfbfSEd Maste 
703ac7ddfbfSEd Maste         // Options table: Required for subclasses of Options.
704ac7ddfbfSEd Maste 
705ac7ddfbfSEd Maste         static OptionDefinition g_option_table[];
706ac7ddfbfSEd Maste 
707ac7ddfbfSEd Maste         uint32_t m_ignore;
708ac7ddfbfSEd Maste     };
709ac7ddfbfSEd Maste 
710ac7ddfbfSEd Maste     bool
7119f2f44ceSEd Maste     DoExecute (Args& command, CommandReturnObject &result) override
712ac7ddfbfSEd Maste     {
713ac7ddfbfSEd Maste         Process *process = m_exe_ctx.GetProcessPtr();
714ac7ddfbfSEd Maste         bool synchronous_execution = m_interpreter.GetSynchronous ();
715ac7ddfbfSEd Maste         StateType state = process->GetState();
716ac7ddfbfSEd Maste         if (state == eStateStopped)
717ac7ddfbfSEd Maste         {
718ac7ddfbfSEd Maste             if (command.GetArgumentCount() != 0)
719ac7ddfbfSEd Maste             {
720ac7ddfbfSEd Maste                 result.AppendErrorWithFormat ("The '%s' command does not take any arguments.\n", m_cmd_name.c_str());
721ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusFailed);
722ac7ddfbfSEd Maste                 return false;
723ac7ddfbfSEd Maste             }
724ac7ddfbfSEd Maste 
725ac7ddfbfSEd Maste             if (m_options.m_ignore > 0)
726ac7ddfbfSEd Maste             {
727ac7ddfbfSEd Maste                 ThreadSP sel_thread_sp(process->GetThreadList().GetSelectedThread());
728ac7ddfbfSEd Maste                 if (sel_thread_sp)
729ac7ddfbfSEd Maste                 {
730ac7ddfbfSEd Maste                     StopInfoSP stop_info_sp = sel_thread_sp->GetStopInfo();
731ac7ddfbfSEd Maste                     if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonBreakpoint)
732ac7ddfbfSEd Maste                     {
733ac7ddfbfSEd Maste                         lldb::break_id_t bp_site_id = (lldb::break_id_t)stop_info_sp->GetValue();
734ac7ddfbfSEd Maste                         BreakpointSiteSP bp_site_sp(process->GetBreakpointSiteList().FindByID(bp_site_id));
735ac7ddfbfSEd Maste                         if (bp_site_sp)
736ac7ddfbfSEd Maste                         {
737ac7ddfbfSEd Maste                             const size_t num_owners = bp_site_sp->GetNumberOfOwners();
738ac7ddfbfSEd Maste                             for (size_t i = 0; i < num_owners; i++)
739ac7ddfbfSEd Maste                             {
740ac7ddfbfSEd Maste                                 Breakpoint &bp_ref = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
741ac7ddfbfSEd Maste                                 if (!bp_ref.IsInternal())
742ac7ddfbfSEd Maste                                 {
743ac7ddfbfSEd Maste                                     bp_ref.SetIgnoreCount(m_options.m_ignore);
744ac7ddfbfSEd Maste                                 }
745ac7ddfbfSEd Maste                             }
746ac7ddfbfSEd Maste                         }
747ac7ddfbfSEd Maste                     }
748ac7ddfbfSEd Maste                 }
749ac7ddfbfSEd Maste             }
750ac7ddfbfSEd Maste 
751ac7ddfbfSEd Maste             {  // Scope for thread list mutex:
752ac7ddfbfSEd Maste                 Mutex::Locker locker (process->GetThreadList().GetMutex());
753ac7ddfbfSEd Maste                 const uint32_t num_threads = process->GetThreadList().GetSize();
754ac7ddfbfSEd Maste 
755ac7ddfbfSEd Maste                 // Set the actions that the threads should each take when resuming
756ac7ddfbfSEd Maste                 for (uint32_t idx=0; idx<num_threads; ++idx)
757ac7ddfbfSEd Maste                 {
7580127ef0fSEd Maste                     const bool override_suspend = false;
7590127ef0fSEd Maste                     process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState (eStateRunning, override_suspend);
760ac7ddfbfSEd Maste                 }
761ac7ddfbfSEd Maste             }
762ac7ddfbfSEd Maste 
7631c3bbb01SEd Maste             const uint32_t iohandler_id = process->GetIOHandlerID();
7641c3bbb01SEd Maste 
7657aa51b79SEd Maste             StreamString stream;
7667aa51b79SEd Maste             Error error;
7677aa51b79SEd Maste             if (synchronous_execution)
7687aa51b79SEd Maste                 error = process->ResumeSynchronous (&stream);
7697aa51b79SEd Maste             else
7707aa51b79SEd Maste                 error = process->Resume ();
7710127ef0fSEd Maste 
772ac7ddfbfSEd Maste             if (error.Success())
773ac7ddfbfSEd Maste             {
7740127ef0fSEd Maste                 // There is a race condition where this thread will return up the call stack to the main command
7750127ef0fSEd Maste                  // handler and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has
7760127ef0fSEd Maste                  // a chance to call PushProcessIOHandler().
7771c3bbb01SEd Maste                 process->SyncIOHandler(iohandler_id, 2000);
7780127ef0fSEd Maste 
779ac7ddfbfSEd Maste                 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
780ac7ddfbfSEd Maste                 if (synchronous_execution)
781ac7ddfbfSEd Maste                 {
7827aa51b79SEd Maste                     // If any state changed events had anything to say, add that to the result
7837aa51b79SEd Maste                     if (stream.GetData())
7847aa51b79SEd Maste                         result.AppendMessage(stream.GetData());
785ac7ddfbfSEd Maste 
786ac7ddfbfSEd Maste                     result.SetDidChangeProcessState (true);
787ac7ddfbfSEd Maste                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
788ac7ddfbfSEd Maste                 }
789ac7ddfbfSEd Maste                 else
790ac7ddfbfSEd Maste                 {
791ac7ddfbfSEd Maste                     result.SetStatus (eReturnStatusSuccessContinuingNoResult);
792ac7ddfbfSEd Maste                 }
793ac7ddfbfSEd Maste             }
794ac7ddfbfSEd Maste             else
795ac7ddfbfSEd Maste             {
796ac7ddfbfSEd Maste                 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
797ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusFailed);
798ac7ddfbfSEd Maste             }
799ac7ddfbfSEd Maste         }
800ac7ddfbfSEd Maste         else
801ac7ddfbfSEd Maste         {
802ac7ddfbfSEd Maste             result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
803ac7ddfbfSEd Maste                                          StateAsCString(state));
804ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
805ac7ddfbfSEd Maste         }
806ac7ddfbfSEd Maste         return result.Succeeded();
807ac7ddfbfSEd Maste     }
808ac7ddfbfSEd Maste 
809ac7ddfbfSEd Maste     Options *
8109f2f44ceSEd Maste     GetOptions () override
811ac7ddfbfSEd Maste     {
812ac7ddfbfSEd Maste         return &m_options;
813ac7ddfbfSEd Maste     }
814ac7ddfbfSEd Maste 
815ac7ddfbfSEd Maste     CommandOptions m_options;
816ac7ddfbfSEd Maste 
817ac7ddfbfSEd Maste };
818ac7ddfbfSEd Maste 
819ac7ddfbfSEd Maste OptionDefinition
820ac7ddfbfSEd Maste CommandObjectProcessContinue::CommandOptions::g_option_table[] =
821ac7ddfbfSEd Maste {
8220127ef0fSEd Maste { LLDB_OPT_SET_ALL, false, "ignore-count",'i', OptionParser::eRequiredArgument,         NULL, NULL, 0, eArgTypeUnsignedInteger,
823ac7ddfbfSEd Maste                            "Ignore <N> crossings of the breakpoint (if it exists) for the currently selected thread."},
8240127ef0fSEd Maste { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
825ac7ddfbfSEd Maste };
826ac7ddfbfSEd Maste 
827ac7ddfbfSEd Maste //-------------------------------------------------------------------------
828ac7ddfbfSEd Maste // CommandObjectProcessDetach
829ac7ddfbfSEd Maste //-------------------------------------------------------------------------
830ac7ddfbfSEd Maste #pragma mark CommandObjectProcessDetach
831ac7ddfbfSEd Maste 
832ac7ddfbfSEd Maste class CommandObjectProcessDetach : public CommandObjectParsed
833ac7ddfbfSEd Maste {
834ac7ddfbfSEd Maste public:
835ac7ddfbfSEd Maste     class CommandOptions : public Options
836ac7ddfbfSEd Maste     {
837ac7ddfbfSEd Maste     public:
838ac7ddfbfSEd Maste 
839ac7ddfbfSEd Maste         CommandOptions (CommandInterpreter &interpreter) :
840ac7ddfbfSEd Maste             Options (interpreter)
841ac7ddfbfSEd Maste         {
842ac7ddfbfSEd Maste             OptionParsingStarting ();
843ac7ddfbfSEd Maste         }
844ac7ddfbfSEd Maste 
8459f2f44ceSEd Maste         ~CommandOptions () override
846ac7ddfbfSEd Maste         {
847ac7ddfbfSEd Maste         }
848ac7ddfbfSEd Maste 
849ac7ddfbfSEd Maste         Error
8509f2f44ceSEd Maste         SetOptionValue (uint32_t option_idx, const char *option_arg) override
851ac7ddfbfSEd Maste         {
852ac7ddfbfSEd Maste             Error error;
853ac7ddfbfSEd Maste             const int short_option = m_getopt_table[option_idx].val;
854ac7ddfbfSEd Maste 
855ac7ddfbfSEd Maste             switch (short_option)
856ac7ddfbfSEd Maste             {
857ac7ddfbfSEd Maste                 case 's':
858ac7ddfbfSEd Maste                     bool tmp_result;
859ac7ddfbfSEd Maste                     bool success;
860ac7ddfbfSEd Maste                     tmp_result = Args::StringToBoolean(option_arg, false, &success);
861ac7ddfbfSEd Maste                     if (!success)
862ac7ddfbfSEd Maste                         error.SetErrorStringWithFormat("invalid boolean option: \"%s\"", option_arg);
863ac7ddfbfSEd Maste                     else
864ac7ddfbfSEd Maste                     {
865ac7ddfbfSEd Maste                         if (tmp_result)
866ac7ddfbfSEd Maste                             m_keep_stopped = eLazyBoolYes;
867ac7ddfbfSEd Maste                         else
868ac7ddfbfSEd Maste                             m_keep_stopped = eLazyBoolNo;
869ac7ddfbfSEd Maste                     }
870ac7ddfbfSEd Maste                     break;
871ac7ddfbfSEd Maste                 default:
872ac7ddfbfSEd Maste                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
873ac7ddfbfSEd Maste                     break;
874ac7ddfbfSEd Maste             }
875ac7ddfbfSEd Maste             return error;
876ac7ddfbfSEd Maste         }
877ac7ddfbfSEd Maste 
878ac7ddfbfSEd Maste         void
8799f2f44ceSEd Maste         OptionParsingStarting () override
880ac7ddfbfSEd Maste         {
881ac7ddfbfSEd Maste             m_keep_stopped = eLazyBoolCalculate;
882ac7ddfbfSEd Maste         }
883ac7ddfbfSEd Maste 
884ac7ddfbfSEd Maste         const OptionDefinition*
8859f2f44ceSEd Maste         GetDefinitions () override
886ac7ddfbfSEd Maste         {
887ac7ddfbfSEd Maste             return g_option_table;
888ac7ddfbfSEd Maste         }
889ac7ddfbfSEd Maste 
890ac7ddfbfSEd Maste         // Options table: Required for subclasses of Options.
891ac7ddfbfSEd Maste 
892ac7ddfbfSEd Maste         static OptionDefinition g_option_table[];
893ac7ddfbfSEd Maste 
894ac7ddfbfSEd Maste         // Instance variables to hold the values for command options.
895ac7ddfbfSEd Maste         LazyBool m_keep_stopped;
896ac7ddfbfSEd Maste     };
897ac7ddfbfSEd Maste 
898ac7ddfbfSEd Maste     CommandObjectProcessDetach (CommandInterpreter &interpreter) :
899ac7ddfbfSEd Maste         CommandObjectParsed (interpreter,
900ac7ddfbfSEd Maste                              "process detach",
901ac7ddfbfSEd Maste                              "Detach from the current process being debugged.",
902ac7ddfbfSEd Maste                              "process detach",
9031c3bbb01SEd Maste                              eCommandRequiresProcess      |
9041c3bbb01SEd Maste                              eCommandTryTargetAPILock     |
9051c3bbb01SEd Maste                              eCommandProcessMustBeLaunched),
906ac7ddfbfSEd Maste         m_options(interpreter)
907ac7ddfbfSEd Maste     {
908ac7ddfbfSEd Maste     }
909ac7ddfbfSEd Maste 
9109f2f44ceSEd Maste     ~CommandObjectProcessDetach () override
911ac7ddfbfSEd Maste     {
912ac7ddfbfSEd Maste     }
913ac7ddfbfSEd Maste 
914ac7ddfbfSEd Maste     Options *
9159f2f44ceSEd Maste     GetOptions () override
916ac7ddfbfSEd Maste     {
917ac7ddfbfSEd Maste         return &m_options;
918ac7ddfbfSEd Maste     }
919ac7ddfbfSEd Maste 
920ac7ddfbfSEd Maste 
921ac7ddfbfSEd Maste protected:
922ac7ddfbfSEd Maste     bool
9239f2f44ceSEd Maste     DoExecute (Args& command, CommandReturnObject &result) override
924ac7ddfbfSEd Maste     {
925ac7ddfbfSEd Maste         Process *process = m_exe_ctx.GetProcessPtr();
926ac7ddfbfSEd Maste         // FIXME: This will be a Command Option:
927ac7ddfbfSEd Maste         bool keep_stopped;
928ac7ddfbfSEd Maste         if (m_options.m_keep_stopped == eLazyBoolCalculate)
929ac7ddfbfSEd Maste         {
930ac7ddfbfSEd Maste             // Check the process default:
931ac7ddfbfSEd Maste             if (process->GetDetachKeepsStopped())
932ac7ddfbfSEd Maste                 keep_stopped = true;
933ac7ddfbfSEd Maste             else
934ac7ddfbfSEd Maste                 keep_stopped = false;
935ac7ddfbfSEd Maste         }
936ac7ddfbfSEd Maste         else if (m_options.m_keep_stopped == eLazyBoolYes)
937ac7ddfbfSEd Maste             keep_stopped = true;
938ac7ddfbfSEd Maste         else
939ac7ddfbfSEd Maste             keep_stopped = false;
940ac7ddfbfSEd Maste 
941ac7ddfbfSEd Maste         Error error (process->Detach(keep_stopped));
942ac7ddfbfSEd Maste         if (error.Success())
943ac7ddfbfSEd Maste         {
944ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusSuccessFinishResult);
945ac7ddfbfSEd Maste         }
946ac7ddfbfSEd Maste         else
947ac7ddfbfSEd Maste         {
948ac7ddfbfSEd Maste             result.AppendErrorWithFormat ("Detach failed: %s\n", error.AsCString());
949ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
950ac7ddfbfSEd Maste             return false;
951ac7ddfbfSEd Maste         }
952ac7ddfbfSEd Maste         return result.Succeeded();
953ac7ddfbfSEd Maste     }
954ac7ddfbfSEd Maste 
955ac7ddfbfSEd Maste     CommandOptions m_options;
956ac7ddfbfSEd Maste };
957ac7ddfbfSEd Maste 
958ac7ddfbfSEd Maste OptionDefinition
959ac7ddfbfSEd Maste CommandObjectProcessDetach::CommandOptions::g_option_table[] =
960ac7ddfbfSEd Maste {
9610127ef0fSEd Maste { LLDB_OPT_SET_1, false, "keep-stopped",   's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Whether or not the process should be kept stopped on detach (if possible)." },
9620127ef0fSEd Maste { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
963ac7ddfbfSEd Maste };
964ac7ddfbfSEd Maste 
965ac7ddfbfSEd Maste //-------------------------------------------------------------------------
966ac7ddfbfSEd Maste // CommandObjectProcessConnect
967ac7ddfbfSEd Maste //-------------------------------------------------------------------------
968ac7ddfbfSEd Maste #pragma mark CommandObjectProcessConnect
969ac7ddfbfSEd Maste 
970ac7ddfbfSEd Maste class CommandObjectProcessConnect : public CommandObjectParsed
971ac7ddfbfSEd Maste {
972ac7ddfbfSEd Maste public:
973ac7ddfbfSEd Maste 
974ac7ddfbfSEd Maste     class CommandOptions : public Options
975ac7ddfbfSEd Maste     {
976ac7ddfbfSEd Maste     public:
977ac7ddfbfSEd Maste 
978ac7ddfbfSEd Maste         CommandOptions (CommandInterpreter &interpreter) :
979ac7ddfbfSEd Maste             Options(interpreter)
980ac7ddfbfSEd Maste         {
981ac7ddfbfSEd Maste             // Keep default values of all options in one place: OptionParsingStarting ()
982ac7ddfbfSEd Maste             OptionParsingStarting ();
983ac7ddfbfSEd Maste         }
984ac7ddfbfSEd Maste 
9859f2f44ceSEd Maste         ~CommandOptions () override
986ac7ddfbfSEd Maste         {
987ac7ddfbfSEd Maste         }
988ac7ddfbfSEd Maste 
989ac7ddfbfSEd Maste         Error
9909f2f44ceSEd Maste         SetOptionValue (uint32_t option_idx, const char *option_arg) override
991ac7ddfbfSEd Maste         {
992ac7ddfbfSEd Maste             Error error;
993ac7ddfbfSEd Maste             const int short_option = m_getopt_table[option_idx].val;
994ac7ddfbfSEd Maste 
995ac7ddfbfSEd Maste             switch (short_option)
996ac7ddfbfSEd Maste             {
997ac7ddfbfSEd Maste             case 'p':
998ac7ddfbfSEd Maste                 plugin_name.assign (option_arg);
999ac7ddfbfSEd Maste                 break;
1000ac7ddfbfSEd Maste 
1001ac7ddfbfSEd Maste             default:
1002ac7ddfbfSEd Maste                 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
1003ac7ddfbfSEd Maste                 break;
1004ac7ddfbfSEd Maste             }
1005ac7ddfbfSEd Maste             return error;
1006ac7ddfbfSEd Maste         }
1007ac7ddfbfSEd Maste 
1008ac7ddfbfSEd Maste         void
10099f2f44ceSEd Maste         OptionParsingStarting () override
1010ac7ddfbfSEd Maste         {
1011ac7ddfbfSEd Maste             plugin_name.clear();
1012ac7ddfbfSEd Maste         }
1013ac7ddfbfSEd Maste 
1014ac7ddfbfSEd Maste         const OptionDefinition*
10159f2f44ceSEd Maste         GetDefinitions () override
1016ac7ddfbfSEd Maste         {
1017ac7ddfbfSEd Maste             return g_option_table;
1018ac7ddfbfSEd Maste         }
1019ac7ddfbfSEd Maste 
1020ac7ddfbfSEd Maste         // Options table: Required for subclasses of Options.
1021ac7ddfbfSEd Maste 
1022ac7ddfbfSEd Maste         static OptionDefinition g_option_table[];
1023ac7ddfbfSEd Maste 
1024ac7ddfbfSEd Maste         // Instance variables to hold the values for command options.
1025ac7ddfbfSEd Maste 
1026ac7ddfbfSEd Maste         std::string plugin_name;
1027ac7ddfbfSEd Maste     };
1028ac7ddfbfSEd Maste 
1029ac7ddfbfSEd Maste     CommandObjectProcessConnect (CommandInterpreter &interpreter) :
1030ac7ddfbfSEd Maste         CommandObjectParsed (interpreter,
1031ac7ddfbfSEd Maste                              "process connect",
1032ac7ddfbfSEd Maste                              "Connect to a remote debug service.",
1033ac7ddfbfSEd Maste                              "process connect <remote-url>",
1034ac7ddfbfSEd Maste                              0),
1035ac7ddfbfSEd Maste         m_options (interpreter)
1036ac7ddfbfSEd Maste     {
1037ac7ddfbfSEd Maste     }
1038ac7ddfbfSEd Maste 
10399f2f44ceSEd Maste     ~CommandObjectProcessConnect () override
1040ac7ddfbfSEd Maste     {
1041ac7ddfbfSEd Maste     }
1042ac7ddfbfSEd Maste 
1043ac7ddfbfSEd Maste 
1044ac7ddfbfSEd Maste     Options *
10459f2f44ceSEd Maste     GetOptions () override
1046ac7ddfbfSEd Maste     {
1047ac7ddfbfSEd Maste         return &m_options;
1048ac7ddfbfSEd Maste     }
1049ac7ddfbfSEd Maste 
1050ac7ddfbfSEd Maste protected:
1051ac7ddfbfSEd Maste     bool
10529f2f44ceSEd Maste     DoExecute (Args& command, CommandReturnObject &result) override
1053ac7ddfbfSEd Maste     {
10549f2f44ceSEd Maste         if (command.GetArgumentCount() != 1)
10559f2f44ceSEd Maste         {
10569f2f44ceSEd Maste             result.AppendErrorWithFormat ("'%s' takes exactly one argument:\nUsage: %s\n",
10579f2f44ceSEd Maste                                           m_cmd_name.c_str(),
10589f2f44ceSEd Maste                                           m_cmd_syntax.c_str());
10599f2f44ceSEd Maste             result.SetStatus (eReturnStatusFailed);
10609f2f44ceSEd Maste             return false;
10619f2f44ceSEd Maste         }
1062ac7ddfbfSEd Maste 
10639f2f44ceSEd Maste 
1064ac7ddfbfSEd Maste         Process *process = m_exe_ctx.GetProcessPtr();
10659f2f44ceSEd Maste         if (process && process->IsAlive())
1066ac7ddfbfSEd Maste         {
1067ac7ddfbfSEd Maste             result.AppendErrorWithFormat ("Process %" PRIu64 " is currently being debugged, kill the process before connecting.\n",
1068ac7ddfbfSEd Maste                                           process->GetID());
1069ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
1070ac7ddfbfSEd Maste             return false;
1071ac7ddfbfSEd Maste         }
1072ac7ddfbfSEd Maste 
10739f2f44ceSEd Maste         const char *plugin_name = nullptr;
1074ac7ddfbfSEd Maste         if (!m_options.plugin_name.empty())
1075ac7ddfbfSEd Maste             plugin_name = m_options.plugin_name.c_str();
1076ac7ddfbfSEd Maste 
10779f2f44ceSEd Maste         Error error;
10789f2f44ceSEd Maste         Debugger& debugger = m_interpreter.GetDebugger();
10799f2f44ceSEd Maste         PlatformSP platform_sp = m_interpreter.GetPlatform(true);
10809f2f44ceSEd Maste         ProcessSP process_sp = platform_sp->ConnectProcess(command.GetArgumentAtIndex(0),
10819f2f44ceSEd Maste                                                            plugin_name,
10829f2f44ceSEd Maste                                                            debugger,
10839f2f44ceSEd Maste                                                            debugger.GetSelectedTarget().get(),
10849f2f44ceSEd Maste                                                            error);
10859f2f44ceSEd Maste         if (error.Fail() || process_sp == nullptr)
1086ac7ddfbfSEd Maste         {
10879f2f44ceSEd Maste             result.AppendError(error.AsCString("Error connecting to the process"));
1088ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
1089ac7ddfbfSEd Maste             return false;
1090ac7ddfbfSEd Maste         }
10919f2f44ceSEd Maste         return true;
1092ac7ddfbfSEd Maste     }
1093ac7ddfbfSEd Maste 
1094ac7ddfbfSEd Maste     CommandOptions m_options;
1095ac7ddfbfSEd Maste };
1096ac7ddfbfSEd Maste 
1097ac7ddfbfSEd Maste OptionDefinition
1098ac7ddfbfSEd Maste CommandObjectProcessConnect::CommandOptions::g_option_table[] =
1099ac7ddfbfSEd Maste {
11000127ef0fSEd Maste     { LLDB_OPT_SET_ALL, false, "plugin", 'p', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."},
11010127ef0fSEd Maste     { 0,                false, NULL,      0 , 0,                 NULL, NULL, 0, eArgTypeNone,   NULL }
1102ac7ddfbfSEd Maste };
1103ac7ddfbfSEd Maste 
1104ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1105ac7ddfbfSEd Maste // CommandObjectProcessPlugin
1106ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1107ac7ddfbfSEd Maste #pragma mark CommandObjectProcessPlugin
1108ac7ddfbfSEd Maste 
1109ac7ddfbfSEd Maste class CommandObjectProcessPlugin : public CommandObjectProxy
1110ac7ddfbfSEd Maste {
1111ac7ddfbfSEd Maste public:
1112ac7ddfbfSEd Maste 
1113ac7ddfbfSEd Maste     CommandObjectProcessPlugin (CommandInterpreter &interpreter) :
1114ac7ddfbfSEd Maste         CommandObjectProxy (interpreter,
1115ac7ddfbfSEd Maste                             "process plugin",
1116ac7ddfbfSEd Maste                             "Send a custom command to the current process plug-in.",
1117ac7ddfbfSEd Maste                             "process plugin <args>",
1118ac7ddfbfSEd Maste                             0)
1119ac7ddfbfSEd Maste     {
1120ac7ddfbfSEd Maste     }
1121ac7ddfbfSEd Maste 
11229f2f44ceSEd Maste     ~CommandObjectProcessPlugin () override
1123ac7ddfbfSEd Maste     {
1124ac7ddfbfSEd Maste     }
1125ac7ddfbfSEd Maste 
11269f2f44ceSEd Maste     CommandObject *
11279f2f44ceSEd Maste     GetProxyCommandObject() override
1128ac7ddfbfSEd Maste     {
1129ac7ddfbfSEd Maste         Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
1130ac7ddfbfSEd Maste         if (process)
1131ac7ddfbfSEd Maste             return process->GetPluginCommandObject();
1132ac7ddfbfSEd Maste         return NULL;
1133ac7ddfbfSEd Maste     }
1134ac7ddfbfSEd Maste };
1135ac7ddfbfSEd Maste 
1136ac7ddfbfSEd Maste 
1137ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1138ac7ddfbfSEd Maste // CommandObjectProcessLoad
1139ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1140ac7ddfbfSEd Maste #pragma mark CommandObjectProcessLoad
1141ac7ddfbfSEd Maste 
1142ac7ddfbfSEd Maste class CommandObjectProcessLoad : public CommandObjectParsed
1143ac7ddfbfSEd Maste {
1144ac7ddfbfSEd Maste public:
11459f2f44ceSEd Maste     class CommandOptions : public Options
11469f2f44ceSEd Maste     {
11479f2f44ceSEd Maste     public:
11489f2f44ceSEd Maste         CommandOptions (CommandInterpreter &interpreter) :
11499f2f44ceSEd Maste             Options(interpreter)
11509f2f44ceSEd Maste         {
11519f2f44ceSEd Maste             // Keep default values of all options in one place: OptionParsingStarting ()
11529f2f44ceSEd Maste             OptionParsingStarting ();
11539f2f44ceSEd Maste         }
11549f2f44ceSEd Maste 
11559f2f44ceSEd Maste         ~CommandOptions () override = default;
11569f2f44ceSEd Maste 
11579f2f44ceSEd Maste         Error
11589f2f44ceSEd Maste         SetOptionValue (uint32_t option_idx, const char *option_arg) override
11599f2f44ceSEd Maste         {
11609f2f44ceSEd Maste             Error error;
11619f2f44ceSEd Maste             const int short_option = m_getopt_table[option_idx].val;
11629f2f44ceSEd Maste             switch (short_option)
11639f2f44ceSEd Maste             {
11649f2f44ceSEd Maste             case 'i':
11659f2f44ceSEd Maste                 do_install = true;
11669f2f44ceSEd Maste                 if (option_arg && option_arg[0])
11679f2f44ceSEd Maste                     install_path.SetFile(option_arg, false);
11689f2f44ceSEd Maste                 break;
11699f2f44ceSEd Maste             default:
11709f2f44ceSEd Maste                 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
11719f2f44ceSEd Maste                 break;
11729f2f44ceSEd Maste             }
11739f2f44ceSEd Maste             return error;
11749f2f44ceSEd Maste         }
11759f2f44ceSEd Maste 
11769f2f44ceSEd Maste         void
11779f2f44ceSEd Maste         OptionParsingStarting () override
11789f2f44ceSEd Maste         {
11799f2f44ceSEd Maste             do_install = false;
11809f2f44ceSEd Maste             install_path.Clear();
11819f2f44ceSEd Maste         }
11829f2f44ceSEd Maste 
11839f2f44ceSEd Maste         const OptionDefinition*
11849f2f44ceSEd Maste         GetDefinitions () override
11859f2f44ceSEd Maste         {
11869f2f44ceSEd Maste             return g_option_table;
11879f2f44ceSEd Maste         }
11889f2f44ceSEd Maste 
11899f2f44ceSEd Maste         // Options table: Required for subclasses of Options.
11909f2f44ceSEd Maste         static OptionDefinition g_option_table[];
11919f2f44ceSEd Maste 
11929f2f44ceSEd Maste         // Instance variables to hold the values for command options.
11939f2f44ceSEd Maste         bool do_install;
11949f2f44ceSEd Maste         FileSpec install_path;
11959f2f44ceSEd Maste     };
1196ac7ddfbfSEd Maste 
1197ac7ddfbfSEd Maste     CommandObjectProcessLoad (CommandInterpreter &interpreter) :
1198ac7ddfbfSEd Maste         CommandObjectParsed (interpreter,
1199ac7ddfbfSEd Maste                              "process load",
1200ac7ddfbfSEd Maste                              "Load a shared library into the current process.",
1201ac7ddfbfSEd Maste                              "process load <filename> [<filename> ...]",
12021c3bbb01SEd Maste                              eCommandRequiresProcess       |
12031c3bbb01SEd Maste                              eCommandTryTargetAPILock      |
12041c3bbb01SEd Maste                              eCommandProcessMustBeLaunched |
12059f2f44ceSEd Maste                              eCommandProcessMustBePaused   ),
12069f2f44ceSEd Maste         m_options (interpreter)
1207ac7ddfbfSEd Maste     {
1208ac7ddfbfSEd Maste     }
1209ac7ddfbfSEd Maste 
12109f2f44ceSEd Maste     ~CommandObjectProcessLoad () override = default;
12119f2f44ceSEd Maste 
12129f2f44ceSEd Maste     Options *
12139f2f44ceSEd Maste     GetOptions () override
1214ac7ddfbfSEd Maste     {
12159f2f44ceSEd Maste         return &m_options;
1216ac7ddfbfSEd Maste     }
1217ac7ddfbfSEd Maste 
1218ac7ddfbfSEd Maste protected:
1219ac7ddfbfSEd Maste     bool
12209f2f44ceSEd Maste     DoExecute (Args& command, CommandReturnObject &result) override
1221ac7ddfbfSEd Maste     {
1222ac7ddfbfSEd Maste         Process *process = m_exe_ctx.GetProcessPtr();
1223ac7ddfbfSEd Maste 
1224ac7ddfbfSEd Maste         const size_t argc = command.GetArgumentCount();
1225ac7ddfbfSEd Maste         for (uint32_t i=0; i<argc; ++i)
1226ac7ddfbfSEd Maste         {
1227ac7ddfbfSEd Maste             Error error;
12289f2f44ceSEd Maste             PlatformSP platform = process->GetTarget().GetPlatform();
1229ac7ddfbfSEd Maste             const char *image_path = command.GetArgumentAtIndex(i);
12309f2f44ceSEd Maste             uint32_t image_token = LLDB_INVALID_IMAGE_TOKEN;
12319f2f44ceSEd Maste 
12329f2f44ceSEd Maste             if (!m_options.do_install)
12339f2f44ceSEd Maste             {
1234ac7ddfbfSEd Maste                 FileSpec image_spec (image_path, false);
12359f2f44ceSEd Maste                 platform->ResolveRemotePath(image_spec, image_spec);
12369f2f44ceSEd Maste                 image_token = platform->LoadImage(process, FileSpec(), image_spec, error);
12379f2f44ceSEd Maste             }
12389f2f44ceSEd Maste             else if (m_options.install_path)
12399f2f44ceSEd Maste             {
12409f2f44ceSEd Maste                 FileSpec image_spec (image_path, true);
12419f2f44ceSEd Maste                 platform->ResolveRemotePath(m_options.install_path, m_options.install_path);
12429f2f44ceSEd Maste                 image_token = platform->LoadImage(process, image_spec, m_options.install_path, error);
12439f2f44ceSEd Maste             }
12449f2f44ceSEd Maste             else
12459f2f44ceSEd Maste             {
12469f2f44ceSEd Maste                 FileSpec image_spec (image_path, true);
12479f2f44ceSEd Maste                 image_token = platform->LoadImage(process, image_spec, FileSpec(), error);
12489f2f44ceSEd Maste             }
12499f2f44ceSEd Maste 
1250ac7ddfbfSEd Maste             if (image_token != LLDB_INVALID_IMAGE_TOKEN)
1251ac7ddfbfSEd Maste             {
1252ac7ddfbfSEd Maste                 result.AppendMessageWithFormat ("Loading \"%s\"...ok\nImage %u loaded.\n", image_path, image_token);
1253ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusSuccessFinishResult);
1254ac7ddfbfSEd Maste             }
1255ac7ddfbfSEd Maste             else
1256ac7ddfbfSEd Maste             {
1257ac7ddfbfSEd Maste                 result.AppendErrorWithFormat ("failed to load '%s': %s", image_path, error.AsCString());
1258ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusFailed);
1259ac7ddfbfSEd Maste             }
1260ac7ddfbfSEd Maste         }
1261ac7ddfbfSEd Maste         return result.Succeeded();
1262ac7ddfbfSEd Maste     }
12639f2f44ceSEd Maste 
12649f2f44ceSEd Maste     CommandOptions m_options;
1265ac7ddfbfSEd Maste };
1266ac7ddfbfSEd Maste 
12679f2f44ceSEd Maste OptionDefinition
12689f2f44ceSEd Maste CommandObjectProcessLoad::CommandOptions::g_option_table[] =
12699f2f44ceSEd Maste {
12709f2f44ceSEd Maste     { LLDB_OPT_SET_ALL, false, "install", 'i', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypePath, "Install the shared library to the target. If specified without an argument then the library will installed in the current working directory."},
12719f2f44ceSEd Maste     { 0,                false, nullptr,    0 , 0,                               nullptr, nullptr, 0, eArgTypeNone, nullptr }
12729f2f44ceSEd Maste };
1273ac7ddfbfSEd Maste 
1274ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1275ac7ddfbfSEd Maste // CommandObjectProcessUnload
1276ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1277ac7ddfbfSEd Maste #pragma mark CommandObjectProcessUnload
1278ac7ddfbfSEd Maste 
1279ac7ddfbfSEd Maste class CommandObjectProcessUnload : public CommandObjectParsed
1280ac7ddfbfSEd Maste {
1281ac7ddfbfSEd Maste public:
1282ac7ddfbfSEd Maste 
1283ac7ddfbfSEd Maste     CommandObjectProcessUnload (CommandInterpreter &interpreter) :
1284ac7ddfbfSEd Maste         CommandObjectParsed (interpreter,
1285ac7ddfbfSEd Maste                              "process unload",
1286ac7ddfbfSEd Maste                              "Unload a shared library from the current process using the index returned by a previous call to \"process load\".",
1287ac7ddfbfSEd Maste                              "process unload <index>",
12881c3bbb01SEd Maste                              eCommandRequiresProcess       |
12891c3bbb01SEd Maste                              eCommandTryTargetAPILock      |
12901c3bbb01SEd Maste                              eCommandProcessMustBeLaunched |
12911c3bbb01SEd Maste                              eCommandProcessMustBePaused   )
1292ac7ddfbfSEd Maste     {
1293ac7ddfbfSEd Maste     }
1294ac7ddfbfSEd Maste 
12959f2f44ceSEd Maste     ~CommandObjectProcessUnload () override
1296ac7ddfbfSEd Maste     {
1297ac7ddfbfSEd Maste     }
1298ac7ddfbfSEd Maste 
1299ac7ddfbfSEd Maste protected:
1300ac7ddfbfSEd Maste     bool
13019f2f44ceSEd Maste     DoExecute (Args& command, CommandReturnObject &result) override
1302ac7ddfbfSEd Maste     {
1303ac7ddfbfSEd Maste         Process *process = m_exe_ctx.GetProcessPtr();
1304ac7ddfbfSEd Maste 
1305ac7ddfbfSEd Maste         const size_t argc = command.GetArgumentCount();
1306ac7ddfbfSEd Maste 
1307ac7ddfbfSEd Maste         for (uint32_t i=0; i<argc; ++i)
1308ac7ddfbfSEd Maste         {
1309ac7ddfbfSEd Maste             const char *image_token_cstr = command.GetArgumentAtIndex(i);
13101c3bbb01SEd Maste             uint32_t image_token = StringConvert::ToUInt32(image_token_cstr, LLDB_INVALID_IMAGE_TOKEN, 0);
1311ac7ddfbfSEd Maste             if (image_token == LLDB_INVALID_IMAGE_TOKEN)
1312ac7ddfbfSEd Maste             {
1313ac7ddfbfSEd Maste                 result.AppendErrorWithFormat ("invalid image index argument '%s'", image_token_cstr);
1314ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusFailed);
1315ac7ddfbfSEd Maste                 break;
1316ac7ddfbfSEd Maste             }
1317ac7ddfbfSEd Maste             else
1318ac7ddfbfSEd Maste             {
13199f2f44ceSEd Maste                 Error error (process->GetTarget().GetPlatform()->UnloadImage(process, image_token));
1320ac7ddfbfSEd Maste                 if (error.Success())
1321ac7ddfbfSEd Maste                 {
1322ac7ddfbfSEd Maste                     result.AppendMessageWithFormat ("Unloading shared library with index %u...ok\n", image_token);
1323ac7ddfbfSEd Maste                     result.SetStatus (eReturnStatusSuccessFinishResult);
1324ac7ddfbfSEd Maste                 }
1325ac7ddfbfSEd Maste                 else
1326ac7ddfbfSEd Maste                 {
1327ac7ddfbfSEd Maste                     result.AppendErrorWithFormat ("failed to unload image: %s", error.AsCString());
1328ac7ddfbfSEd Maste                     result.SetStatus (eReturnStatusFailed);
1329ac7ddfbfSEd Maste                     break;
1330ac7ddfbfSEd Maste                 }
1331ac7ddfbfSEd Maste             }
1332ac7ddfbfSEd Maste         }
1333ac7ddfbfSEd Maste         return result.Succeeded();
1334ac7ddfbfSEd Maste     }
1335ac7ddfbfSEd Maste };
1336ac7ddfbfSEd Maste 
1337ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1338ac7ddfbfSEd Maste // CommandObjectProcessSignal
1339ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1340ac7ddfbfSEd Maste #pragma mark CommandObjectProcessSignal
1341ac7ddfbfSEd Maste 
1342ac7ddfbfSEd Maste class CommandObjectProcessSignal : public CommandObjectParsed
1343ac7ddfbfSEd Maste {
1344ac7ddfbfSEd Maste public:
1345ac7ddfbfSEd Maste 
1346ac7ddfbfSEd Maste     CommandObjectProcessSignal (CommandInterpreter &interpreter) :
1347ac7ddfbfSEd Maste         CommandObjectParsed (interpreter,
1348ac7ddfbfSEd Maste                              "process signal",
1349ac7ddfbfSEd Maste                              "Send a UNIX signal to the current process being debugged.",
1350ac7ddfbfSEd Maste                              NULL,
13511c3bbb01SEd Maste                              eCommandRequiresProcess | eCommandTryTargetAPILock)
1352ac7ddfbfSEd Maste     {
1353ac7ddfbfSEd Maste         CommandArgumentEntry arg;
1354ac7ddfbfSEd Maste         CommandArgumentData signal_arg;
1355ac7ddfbfSEd Maste 
1356ac7ddfbfSEd Maste         // Define the first (and only) variant of this arg.
1357ac7ddfbfSEd Maste         signal_arg.arg_type = eArgTypeUnixSignal;
1358ac7ddfbfSEd Maste         signal_arg.arg_repetition = eArgRepeatPlain;
1359ac7ddfbfSEd Maste 
1360ac7ddfbfSEd Maste         // There is only one variant this argument could be; put it into the argument entry.
1361ac7ddfbfSEd Maste         arg.push_back (signal_arg);
1362ac7ddfbfSEd Maste 
1363ac7ddfbfSEd Maste         // Push the data for the first argument into the m_arguments vector.
1364ac7ddfbfSEd Maste         m_arguments.push_back (arg);
1365ac7ddfbfSEd Maste     }
1366ac7ddfbfSEd Maste 
13679f2f44ceSEd Maste     ~CommandObjectProcessSignal () override
1368ac7ddfbfSEd Maste     {
1369ac7ddfbfSEd Maste     }
1370ac7ddfbfSEd Maste 
1371ac7ddfbfSEd Maste protected:
1372ac7ddfbfSEd Maste     bool
13739f2f44ceSEd Maste     DoExecute (Args& command, CommandReturnObject &result) override
1374ac7ddfbfSEd Maste     {
1375ac7ddfbfSEd Maste         Process *process = m_exe_ctx.GetProcessPtr();
1376ac7ddfbfSEd Maste 
1377ac7ddfbfSEd Maste         if (command.GetArgumentCount() == 1)
1378ac7ddfbfSEd Maste         {
1379ac7ddfbfSEd Maste             int signo = LLDB_INVALID_SIGNAL_NUMBER;
1380ac7ddfbfSEd Maste 
1381ac7ddfbfSEd Maste             const char *signal_name = command.GetArgumentAtIndex(0);
1382ac7ddfbfSEd Maste             if (::isxdigit (signal_name[0]))
13831c3bbb01SEd Maste                 signo = StringConvert::ToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0);
1384ac7ddfbfSEd Maste             else
1385b91a7dfcSDimitry Andric                 signo = process->GetUnixSignals()->GetSignalNumberFromName(signal_name);
1386ac7ddfbfSEd Maste 
1387ac7ddfbfSEd Maste             if (signo == LLDB_INVALID_SIGNAL_NUMBER)
1388ac7ddfbfSEd Maste             {
1389ac7ddfbfSEd Maste                 result.AppendErrorWithFormat ("Invalid signal argument '%s'.\n", command.GetArgumentAtIndex(0));
1390ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusFailed);
1391ac7ddfbfSEd Maste             }
1392ac7ddfbfSEd Maste             else
1393ac7ddfbfSEd Maste             {
1394ac7ddfbfSEd Maste                 Error error (process->Signal (signo));
1395ac7ddfbfSEd Maste                 if (error.Success())
1396ac7ddfbfSEd Maste                 {
1397ac7ddfbfSEd Maste                     result.SetStatus (eReturnStatusSuccessFinishResult);
1398ac7ddfbfSEd Maste                 }
1399ac7ddfbfSEd Maste                 else
1400ac7ddfbfSEd Maste                 {
1401ac7ddfbfSEd Maste                     result.AppendErrorWithFormat ("Failed to send signal %i: %s\n", signo, error.AsCString());
1402ac7ddfbfSEd Maste                     result.SetStatus (eReturnStatusFailed);
1403ac7ddfbfSEd Maste                 }
1404ac7ddfbfSEd Maste             }
1405ac7ddfbfSEd Maste         }
1406ac7ddfbfSEd Maste         else
1407ac7ddfbfSEd Maste         {
1408ac7ddfbfSEd Maste             result.AppendErrorWithFormat("'%s' takes exactly one signal number argument:\nUsage: %s\n", m_cmd_name.c_str(),
1409ac7ddfbfSEd Maste                                         m_cmd_syntax.c_str());
1410ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
1411ac7ddfbfSEd Maste         }
1412ac7ddfbfSEd Maste         return result.Succeeded();
1413ac7ddfbfSEd Maste     }
1414ac7ddfbfSEd Maste };
1415ac7ddfbfSEd Maste 
1416ac7ddfbfSEd Maste 
1417ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1418ac7ddfbfSEd Maste // CommandObjectProcessInterrupt
1419ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1420ac7ddfbfSEd Maste #pragma mark CommandObjectProcessInterrupt
1421ac7ddfbfSEd Maste 
1422ac7ddfbfSEd Maste class CommandObjectProcessInterrupt : public CommandObjectParsed
1423ac7ddfbfSEd Maste {
1424ac7ddfbfSEd Maste public:
1425ac7ddfbfSEd Maste 
1426ac7ddfbfSEd Maste 
1427ac7ddfbfSEd Maste     CommandObjectProcessInterrupt (CommandInterpreter &interpreter) :
1428ac7ddfbfSEd Maste         CommandObjectParsed (interpreter,
1429ac7ddfbfSEd Maste                              "process interrupt",
1430ac7ddfbfSEd Maste                              "Interrupt the current process being debugged.",
1431ac7ddfbfSEd Maste                              "process interrupt",
14321c3bbb01SEd Maste                              eCommandRequiresProcess      |
14331c3bbb01SEd Maste                              eCommandTryTargetAPILock     |
14341c3bbb01SEd Maste                              eCommandProcessMustBeLaunched)
1435ac7ddfbfSEd Maste     {
1436ac7ddfbfSEd Maste     }
1437ac7ddfbfSEd Maste 
14389f2f44ceSEd Maste     ~CommandObjectProcessInterrupt () override
1439ac7ddfbfSEd Maste     {
1440ac7ddfbfSEd Maste     }
1441ac7ddfbfSEd Maste 
1442ac7ddfbfSEd Maste protected:
1443ac7ddfbfSEd Maste     bool
14449f2f44ceSEd Maste     DoExecute (Args& command, CommandReturnObject &result) override
1445ac7ddfbfSEd Maste     {
1446ac7ddfbfSEd Maste         Process *process = m_exe_ctx.GetProcessPtr();
1447ac7ddfbfSEd Maste         if (process == NULL)
1448ac7ddfbfSEd Maste         {
1449ac7ddfbfSEd Maste             result.AppendError ("no process to halt");
1450ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
1451ac7ddfbfSEd Maste             return false;
1452ac7ddfbfSEd Maste         }
1453ac7ddfbfSEd Maste 
1454ac7ddfbfSEd Maste         if (command.GetArgumentCount() == 0)
1455ac7ddfbfSEd Maste         {
1456ac7ddfbfSEd Maste             bool clear_thread_plans = true;
1457ac7ddfbfSEd Maste             Error error(process->Halt (clear_thread_plans));
1458ac7ddfbfSEd Maste             if (error.Success())
1459ac7ddfbfSEd Maste             {
1460ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusSuccessFinishResult);
1461ac7ddfbfSEd Maste             }
1462ac7ddfbfSEd Maste             else
1463ac7ddfbfSEd Maste             {
1464ac7ddfbfSEd Maste                 result.AppendErrorWithFormat ("Failed to halt process: %s\n", error.AsCString());
1465ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusFailed);
1466ac7ddfbfSEd Maste             }
1467ac7ddfbfSEd Maste         }
1468ac7ddfbfSEd Maste         else
1469ac7ddfbfSEd Maste         {
1470ac7ddfbfSEd Maste             result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n",
1471ac7ddfbfSEd Maste                                         m_cmd_name.c_str(),
1472ac7ddfbfSEd Maste                                         m_cmd_syntax.c_str());
1473ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
1474ac7ddfbfSEd Maste         }
1475ac7ddfbfSEd Maste         return result.Succeeded();
1476ac7ddfbfSEd Maste     }
1477ac7ddfbfSEd Maste };
1478ac7ddfbfSEd Maste 
1479ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1480ac7ddfbfSEd Maste // CommandObjectProcessKill
1481ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1482ac7ddfbfSEd Maste #pragma mark CommandObjectProcessKill
1483ac7ddfbfSEd Maste 
1484ac7ddfbfSEd Maste class CommandObjectProcessKill : public CommandObjectParsed
1485ac7ddfbfSEd Maste {
1486ac7ddfbfSEd Maste public:
1487ac7ddfbfSEd Maste 
1488ac7ddfbfSEd Maste     CommandObjectProcessKill (CommandInterpreter &interpreter) :
1489ac7ddfbfSEd Maste         CommandObjectParsed (interpreter,
1490ac7ddfbfSEd Maste                              "process kill",
1491ac7ddfbfSEd Maste                              "Terminate the current process being debugged.",
1492ac7ddfbfSEd Maste                              "process kill",
14931c3bbb01SEd Maste                              eCommandRequiresProcess      |
14941c3bbb01SEd Maste                              eCommandTryTargetAPILock     |
14951c3bbb01SEd Maste                              eCommandProcessMustBeLaunched)
1496ac7ddfbfSEd Maste     {
1497ac7ddfbfSEd Maste     }
1498ac7ddfbfSEd Maste 
14999f2f44ceSEd Maste     ~CommandObjectProcessKill () override
1500ac7ddfbfSEd Maste     {
1501ac7ddfbfSEd Maste     }
1502ac7ddfbfSEd Maste 
1503ac7ddfbfSEd Maste protected:
1504ac7ddfbfSEd Maste     bool
15059f2f44ceSEd Maste     DoExecute (Args& command, CommandReturnObject &result) override
1506ac7ddfbfSEd Maste     {
1507ac7ddfbfSEd Maste         Process *process = m_exe_ctx.GetProcessPtr();
1508ac7ddfbfSEd Maste         if (process == NULL)
1509ac7ddfbfSEd Maste         {
1510ac7ddfbfSEd Maste             result.AppendError ("no process to kill");
1511ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
1512ac7ddfbfSEd Maste             return false;
1513ac7ddfbfSEd Maste         }
1514ac7ddfbfSEd Maste 
1515ac7ddfbfSEd Maste         if (command.GetArgumentCount() == 0)
1516ac7ddfbfSEd Maste         {
15171c3bbb01SEd Maste             Error error (process->Destroy(true));
1518ac7ddfbfSEd Maste             if (error.Success())
1519ac7ddfbfSEd Maste             {
1520ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusSuccessFinishResult);
1521ac7ddfbfSEd Maste             }
1522ac7ddfbfSEd Maste             else
1523ac7ddfbfSEd Maste             {
1524ac7ddfbfSEd Maste                 result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString());
1525ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusFailed);
1526ac7ddfbfSEd Maste             }
1527ac7ddfbfSEd Maste         }
1528ac7ddfbfSEd Maste         else
1529ac7ddfbfSEd Maste         {
1530ac7ddfbfSEd Maste             result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n",
1531ac7ddfbfSEd Maste                                         m_cmd_name.c_str(),
1532ac7ddfbfSEd Maste                                         m_cmd_syntax.c_str());
1533ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
1534ac7ddfbfSEd Maste         }
1535ac7ddfbfSEd Maste         return result.Succeeded();
1536ac7ddfbfSEd Maste     }
1537ac7ddfbfSEd Maste };
1538ac7ddfbfSEd Maste 
1539ac7ddfbfSEd Maste //-------------------------------------------------------------------------
15400127ef0fSEd Maste // CommandObjectProcessSaveCore
15410127ef0fSEd Maste //-------------------------------------------------------------------------
15420127ef0fSEd Maste #pragma mark CommandObjectProcessSaveCore
15430127ef0fSEd Maste 
15440127ef0fSEd Maste class CommandObjectProcessSaveCore : public CommandObjectParsed
15450127ef0fSEd Maste {
15460127ef0fSEd Maste public:
15470127ef0fSEd Maste 
15480127ef0fSEd Maste     CommandObjectProcessSaveCore (CommandInterpreter &interpreter) :
15490127ef0fSEd Maste     CommandObjectParsed (interpreter,
15500127ef0fSEd Maste                          "process save-core",
15510127ef0fSEd Maste                          "Save the current process as a core file using an appropriate file type.",
15520127ef0fSEd Maste                          "process save-core FILE",
15531c3bbb01SEd Maste                          eCommandRequiresProcess      |
15541c3bbb01SEd Maste                          eCommandTryTargetAPILock     |
15551c3bbb01SEd Maste                          eCommandProcessMustBeLaunched)
15560127ef0fSEd Maste     {
15570127ef0fSEd Maste     }
15580127ef0fSEd Maste 
15599f2f44ceSEd Maste     ~CommandObjectProcessSaveCore () override
15600127ef0fSEd Maste     {
15610127ef0fSEd Maste     }
15620127ef0fSEd Maste 
15630127ef0fSEd Maste protected:
15640127ef0fSEd Maste     bool
15650127ef0fSEd Maste     DoExecute (Args& command,
15669f2f44ceSEd Maste                CommandReturnObject &result) override
15670127ef0fSEd Maste     {
15680127ef0fSEd Maste         ProcessSP process_sp = m_exe_ctx.GetProcessSP();
15690127ef0fSEd Maste         if (process_sp)
15700127ef0fSEd Maste         {
15710127ef0fSEd Maste             if (command.GetArgumentCount() == 1)
15720127ef0fSEd Maste             {
15730127ef0fSEd Maste                 FileSpec output_file(command.GetArgumentAtIndex(0), false);
15740127ef0fSEd Maste                 Error error = PluginManager::SaveCore(process_sp, output_file);
15750127ef0fSEd Maste                 if (error.Success())
15760127ef0fSEd Maste                 {
15770127ef0fSEd Maste                     result.SetStatus (eReturnStatusSuccessFinishResult);
15780127ef0fSEd Maste                 }
15790127ef0fSEd Maste                 else
15800127ef0fSEd Maste                 {
15810127ef0fSEd Maste                     result.AppendErrorWithFormat ("Failed to save core file for process: %s\n", error.AsCString());
15820127ef0fSEd Maste                     result.SetStatus (eReturnStatusFailed);
15830127ef0fSEd Maste                 }
15840127ef0fSEd Maste             }
15850127ef0fSEd Maste             else
15860127ef0fSEd Maste             {
15870127ef0fSEd Maste                 result.AppendErrorWithFormat ("'%s' takes one arguments:\nUsage: %s\n",
15880127ef0fSEd Maste                                               m_cmd_name.c_str(),
15890127ef0fSEd Maste                                               m_cmd_syntax.c_str());
15900127ef0fSEd Maste                 result.SetStatus (eReturnStatusFailed);
15910127ef0fSEd Maste             }
15920127ef0fSEd Maste         }
15930127ef0fSEd Maste         else
15940127ef0fSEd Maste         {
15950127ef0fSEd Maste             result.AppendError ("invalid process");
15960127ef0fSEd Maste             result.SetStatus (eReturnStatusFailed);
15970127ef0fSEd Maste             return false;
15980127ef0fSEd Maste         }
15990127ef0fSEd Maste 
16000127ef0fSEd Maste         return result.Succeeded();
16010127ef0fSEd Maste     }
16020127ef0fSEd Maste };
16030127ef0fSEd Maste 
16040127ef0fSEd Maste //-------------------------------------------------------------------------
1605ac7ddfbfSEd Maste // CommandObjectProcessStatus
1606ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1607ac7ddfbfSEd Maste #pragma mark CommandObjectProcessStatus
1608ac7ddfbfSEd Maste 
1609ac7ddfbfSEd Maste class CommandObjectProcessStatus : public CommandObjectParsed
1610ac7ddfbfSEd Maste {
1611ac7ddfbfSEd Maste public:
1612ac7ddfbfSEd Maste     CommandObjectProcessStatus (CommandInterpreter &interpreter) :
1613ac7ddfbfSEd Maste         CommandObjectParsed (interpreter,
1614ac7ddfbfSEd Maste                              "process status",
1615ac7ddfbfSEd Maste                              "Show the current status and location of executing process.",
1616ac7ddfbfSEd Maste                              "process status",
16171c3bbb01SEd Maste                              eCommandRequiresProcess | eCommandTryTargetAPILock)
1618ac7ddfbfSEd Maste     {
1619ac7ddfbfSEd Maste     }
1620ac7ddfbfSEd Maste 
16219f2f44ceSEd Maste     ~CommandObjectProcessStatus() override
1622ac7ddfbfSEd Maste     {
1623ac7ddfbfSEd Maste     }
1624ac7ddfbfSEd Maste 
1625ac7ddfbfSEd Maste 
1626ac7ddfbfSEd Maste     bool
16279f2f44ceSEd Maste     DoExecute (Args& command, CommandReturnObject &result) override
1628ac7ddfbfSEd Maste     {
1629ac7ddfbfSEd Maste         Stream &strm = result.GetOutputStream();
1630ac7ddfbfSEd Maste         result.SetStatus (eReturnStatusSuccessFinishNoResult);
16311c3bbb01SEd Maste         // No need to check "process" for validity as eCommandRequiresProcess ensures it is valid
1632ac7ddfbfSEd Maste         Process *process = m_exe_ctx.GetProcessPtr();
1633ac7ddfbfSEd Maste         const bool only_threads_with_stop_reason = true;
1634ac7ddfbfSEd Maste         const uint32_t start_frame = 0;
1635ac7ddfbfSEd Maste         const uint32_t num_frames = 1;
1636ac7ddfbfSEd Maste         const uint32_t num_frames_with_source = 1;
1637ac7ddfbfSEd Maste         process->GetStatus(strm);
1638ac7ddfbfSEd Maste         process->GetThreadStatus (strm,
1639ac7ddfbfSEd Maste                                   only_threads_with_stop_reason,
1640ac7ddfbfSEd Maste                                   start_frame,
1641ac7ddfbfSEd Maste                                   num_frames,
1642ac7ddfbfSEd Maste                                   num_frames_with_source);
1643ac7ddfbfSEd Maste         return result.Succeeded();
1644ac7ddfbfSEd Maste     }
1645ac7ddfbfSEd Maste };
1646ac7ddfbfSEd Maste 
1647ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1648ac7ddfbfSEd Maste // CommandObjectProcessHandle
1649ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1650ac7ddfbfSEd Maste #pragma mark CommandObjectProcessHandle
1651ac7ddfbfSEd Maste 
1652ac7ddfbfSEd Maste class CommandObjectProcessHandle : public CommandObjectParsed
1653ac7ddfbfSEd Maste {
1654ac7ddfbfSEd Maste public:
1655ac7ddfbfSEd Maste 
1656ac7ddfbfSEd Maste     class CommandOptions : public Options
1657ac7ddfbfSEd Maste     {
1658ac7ddfbfSEd Maste     public:
1659ac7ddfbfSEd Maste 
1660ac7ddfbfSEd Maste         CommandOptions (CommandInterpreter &interpreter) :
1661ac7ddfbfSEd Maste             Options (interpreter)
1662ac7ddfbfSEd Maste         {
1663ac7ddfbfSEd Maste             OptionParsingStarting ();
1664ac7ddfbfSEd Maste         }
1665ac7ddfbfSEd Maste 
16669f2f44ceSEd Maste         ~CommandOptions () override
1667ac7ddfbfSEd Maste         {
1668ac7ddfbfSEd Maste         }
1669ac7ddfbfSEd Maste 
1670ac7ddfbfSEd Maste         Error
16719f2f44ceSEd Maste         SetOptionValue (uint32_t option_idx, const char *option_arg) override
1672ac7ddfbfSEd Maste         {
1673ac7ddfbfSEd Maste             Error error;
1674ac7ddfbfSEd Maste             const int short_option = m_getopt_table[option_idx].val;
1675ac7ddfbfSEd Maste 
1676ac7ddfbfSEd Maste             switch (short_option)
1677ac7ddfbfSEd Maste             {
1678ac7ddfbfSEd Maste                 case 's':
1679ac7ddfbfSEd Maste                     stop = option_arg;
1680ac7ddfbfSEd Maste                     break;
1681ac7ddfbfSEd Maste                 case 'n':
1682ac7ddfbfSEd Maste                     notify = option_arg;
1683ac7ddfbfSEd Maste                     break;
1684ac7ddfbfSEd Maste                 case 'p':
1685ac7ddfbfSEd Maste                     pass = option_arg;
1686ac7ddfbfSEd Maste                     break;
1687ac7ddfbfSEd Maste                 default:
1688ac7ddfbfSEd Maste                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
1689ac7ddfbfSEd Maste                     break;
1690ac7ddfbfSEd Maste             }
1691ac7ddfbfSEd Maste             return error;
1692ac7ddfbfSEd Maste         }
1693ac7ddfbfSEd Maste 
1694ac7ddfbfSEd Maste         void
16959f2f44ceSEd Maste         OptionParsingStarting () override
1696ac7ddfbfSEd Maste         {
1697ac7ddfbfSEd Maste             stop.clear();
1698ac7ddfbfSEd Maste             notify.clear();
1699ac7ddfbfSEd Maste             pass.clear();
1700ac7ddfbfSEd Maste         }
1701ac7ddfbfSEd Maste 
1702ac7ddfbfSEd Maste         const OptionDefinition*
17039f2f44ceSEd Maste         GetDefinitions () override
1704ac7ddfbfSEd Maste         {
1705ac7ddfbfSEd Maste             return g_option_table;
1706ac7ddfbfSEd Maste         }
1707ac7ddfbfSEd Maste 
1708ac7ddfbfSEd Maste         // Options table: Required for subclasses of Options.
1709ac7ddfbfSEd Maste 
1710ac7ddfbfSEd Maste         static OptionDefinition g_option_table[];
1711ac7ddfbfSEd Maste 
1712ac7ddfbfSEd Maste         // Instance variables to hold the values for command options.
1713ac7ddfbfSEd Maste 
1714ac7ddfbfSEd Maste         std::string stop;
1715ac7ddfbfSEd Maste         std::string notify;
1716ac7ddfbfSEd Maste         std::string pass;
1717ac7ddfbfSEd Maste     };
1718ac7ddfbfSEd Maste 
1719ac7ddfbfSEd Maste 
1720ac7ddfbfSEd Maste     CommandObjectProcessHandle (CommandInterpreter &interpreter) :
1721ac7ddfbfSEd Maste         CommandObjectParsed (interpreter,
1722ac7ddfbfSEd Maste                              "process handle",
1723ac7ddfbfSEd Maste                              "Show or update what the process and debugger should do with various signals received from the OS.",
1724ac7ddfbfSEd Maste                              NULL),
1725ac7ddfbfSEd Maste         m_options (interpreter)
1726ac7ddfbfSEd Maste     {
1727b91a7dfcSDimitry Andric         SetHelpLong ("\nIf no signals are specified, update them all.  If no update "
1728b91a7dfcSDimitry Andric                      "option is specified, list the current values.");
1729ac7ddfbfSEd Maste         CommandArgumentEntry arg;
1730ac7ddfbfSEd Maste         CommandArgumentData signal_arg;
1731ac7ddfbfSEd Maste 
1732ac7ddfbfSEd Maste         signal_arg.arg_type = eArgTypeUnixSignal;
1733ac7ddfbfSEd Maste         signal_arg.arg_repetition = eArgRepeatStar;
1734ac7ddfbfSEd Maste 
1735ac7ddfbfSEd Maste         arg.push_back (signal_arg);
1736ac7ddfbfSEd Maste 
1737ac7ddfbfSEd Maste         m_arguments.push_back (arg);
1738ac7ddfbfSEd Maste     }
1739ac7ddfbfSEd Maste 
17409f2f44ceSEd Maste     ~CommandObjectProcessHandle () override
1741ac7ddfbfSEd Maste     {
1742ac7ddfbfSEd Maste     }
1743ac7ddfbfSEd Maste 
1744ac7ddfbfSEd Maste     Options *
17459f2f44ceSEd Maste     GetOptions () override
1746ac7ddfbfSEd Maste     {
1747ac7ddfbfSEd Maste         return &m_options;
1748ac7ddfbfSEd Maste     }
1749ac7ddfbfSEd Maste 
1750ac7ddfbfSEd Maste     bool
1751ac7ddfbfSEd Maste     VerifyCommandOptionValue (const std::string &option, int &real_value)
1752ac7ddfbfSEd Maste     {
1753ac7ddfbfSEd Maste         bool okay = true;
1754ac7ddfbfSEd Maste 
1755ac7ddfbfSEd Maste         bool success = false;
1756ac7ddfbfSEd Maste         bool tmp_value = Args::StringToBoolean (option.c_str(), false, &success);
1757ac7ddfbfSEd Maste 
1758ac7ddfbfSEd Maste         if (success && tmp_value)
1759ac7ddfbfSEd Maste             real_value = 1;
1760ac7ddfbfSEd Maste         else if (success && !tmp_value)
1761ac7ddfbfSEd Maste             real_value = 0;
1762ac7ddfbfSEd Maste         else
1763ac7ddfbfSEd Maste         {
1764ac7ddfbfSEd Maste             // If the value isn't 'true' or 'false', it had better be 0 or 1.
17651c3bbb01SEd Maste             real_value = StringConvert::ToUInt32 (option.c_str(), 3);
1766ac7ddfbfSEd Maste             if (real_value != 0 && real_value != 1)
1767ac7ddfbfSEd Maste                 okay = false;
1768ac7ddfbfSEd Maste         }
1769ac7ddfbfSEd Maste 
1770ac7ddfbfSEd Maste         return okay;
1771ac7ddfbfSEd Maste     }
1772ac7ddfbfSEd Maste 
1773ac7ddfbfSEd Maste     void
1774ac7ddfbfSEd Maste     PrintSignalHeader (Stream &str)
1775ac7ddfbfSEd Maste     {
1776ac7ddfbfSEd Maste         str.Printf ("NAME         PASS   STOP   NOTIFY\n");
17771c3bbb01SEd Maste         str.Printf ("===========  =====  =====  ======\n");
1778ac7ddfbfSEd Maste     }
1779ac7ddfbfSEd Maste 
1780ac7ddfbfSEd Maste     void
1781b91a7dfcSDimitry Andric     PrintSignal(Stream &str, int32_t signo, const char *sig_name, const UnixSignalsSP &signals_sp)
1782ac7ddfbfSEd Maste     {
1783ac7ddfbfSEd Maste         bool stop;
1784ac7ddfbfSEd Maste         bool suppress;
1785ac7ddfbfSEd Maste         bool notify;
1786ac7ddfbfSEd Maste 
17871c3bbb01SEd Maste         str.Printf ("%-11s  ", sig_name);
1788b91a7dfcSDimitry Andric         if (signals_sp->GetSignalInfo(signo, suppress, stop, notify))
1789ac7ddfbfSEd Maste         {
1790ac7ddfbfSEd Maste             bool pass = !suppress;
1791ac7ddfbfSEd Maste             str.Printf ("%s  %s  %s",
1792ac7ddfbfSEd Maste                         (pass ? "true " : "false"),
1793ac7ddfbfSEd Maste                         (stop ? "true " : "false"),
1794ac7ddfbfSEd Maste                         (notify ? "true " : "false"));
1795ac7ddfbfSEd Maste         }
1796ac7ddfbfSEd Maste         str.Printf ("\n");
1797ac7ddfbfSEd Maste     }
1798ac7ddfbfSEd Maste 
1799ac7ddfbfSEd Maste     void
1800b91a7dfcSDimitry Andric     PrintSignalInformation(Stream &str, Args &signal_args, int num_valid_signals, const UnixSignalsSP &signals_sp)
1801ac7ddfbfSEd Maste     {
1802ac7ddfbfSEd Maste         PrintSignalHeader (str);
1803ac7ddfbfSEd Maste 
1804ac7ddfbfSEd Maste         if (num_valid_signals > 0)
1805ac7ddfbfSEd Maste         {
1806ac7ddfbfSEd Maste             size_t num_args = signal_args.GetArgumentCount();
1807ac7ddfbfSEd Maste             for (size_t i = 0; i < num_args; ++i)
1808ac7ddfbfSEd Maste             {
1809b91a7dfcSDimitry Andric                 int32_t signo = signals_sp->GetSignalNumberFromName(signal_args.GetArgumentAtIndex(i));
1810ac7ddfbfSEd Maste                 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
1811b91a7dfcSDimitry Andric                     PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals_sp);
1812ac7ddfbfSEd Maste             }
1813ac7ddfbfSEd Maste         }
1814ac7ddfbfSEd Maste         else // Print info for ALL signals
1815ac7ddfbfSEd Maste         {
1816b91a7dfcSDimitry Andric             int32_t signo = signals_sp->GetFirstSignalNumber();
1817ac7ddfbfSEd Maste             while (signo != LLDB_INVALID_SIGNAL_NUMBER)
1818ac7ddfbfSEd Maste             {
1819b91a7dfcSDimitry Andric                 PrintSignal(str, signo, signals_sp->GetSignalAsCString(signo), signals_sp);
1820b91a7dfcSDimitry Andric                 signo = signals_sp->GetNextSignalNumber(signo);
1821ac7ddfbfSEd Maste             }
1822ac7ddfbfSEd Maste         }
1823ac7ddfbfSEd Maste     }
1824ac7ddfbfSEd Maste 
1825ac7ddfbfSEd Maste protected:
1826ac7ddfbfSEd Maste     bool
18279f2f44ceSEd Maste     DoExecute (Args &signal_args, CommandReturnObject &result) override
1828ac7ddfbfSEd Maste     {
1829ac7ddfbfSEd Maste         TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
1830ac7ddfbfSEd Maste 
1831ac7ddfbfSEd Maste         if (!target_sp)
1832ac7ddfbfSEd Maste         {
1833ac7ddfbfSEd Maste             result.AppendError ("No current target;"
1834ac7ddfbfSEd Maste                                 " cannot handle signals until you have a valid target and process.\n");
1835ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
1836ac7ddfbfSEd Maste             return false;
1837ac7ddfbfSEd Maste         }
1838ac7ddfbfSEd Maste 
1839ac7ddfbfSEd Maste         ProcessSP process_sp = target_sp->GetProcessSP();
1840ac7ddfbfSEd Maste 
1841ac7ddfbfSEd Maste         if (!process_sp)
1842ac7ddfbfSEd Maste         {
1843ac7ddfbfSEd Maste             result.AppendError ("No current process; cannot handle signals until you have a valid process.\n");
1844ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
1845ac7ddfbfSEd Maste             return false;
1846ac7ddfbfSEd Maste         }
1847ac7ddfbfSEd Maste 
1848ac7ddfbfSEd Maste         int stop_action = -1;   // -1 means leave the current setting alone
1849ac7ddfbfSEd Maste         int pass_action = -1;   // -1 means leave the current setting alone
1850ac7ddfbfSEd Maste         int notify_action = -1; // -1 means leave the current setting alone
1851ac7ddfbfSEd Maste 
1852ac7ddfbfSEd Maste         if (! m_options.stop.empty()
1853ac7ddfbfSEd Maste             && ! VerifyCommandOptionValue (m_options.stop, stop_action))
1854ac7ddfbfSEd Maste         {
1855ac7ddfbfSEd Maste             result.AppendError ("Invalid argument for command option --stop; must be true or false.\n");
1856ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
1857ac7ddfbfSEd Maste             return false;
1858ac7ddfbfSEd Maste         }
1859ac7ddfbfSEd Maste 
1860ac7ddfbfSEd Maste         if (! m_options.notify.empty()
1861ac7ddfbfSEd Maste             && ! VerifyCommandOptionValue (m_options.notify, notify_action))
1862ac7ddfbfSEd Maste         {
1863ac7ddfbfSEd Maste             result.AppendError ("Invalid argument for command option --notify; must be true or false.\n");
1864ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
1865ac7ddfbfSEd Maste             return false;
1866ac7ddfbfSEd Maste         }
1867ac7ddfbfSEd Maste 
1868ac7ddfbfSEd Maste         if (! m_options.pass.empty()
1869ac7ddfbfSEd Maste             && ! VerifyCommandOptionValue (m_options.pass, pass_action))
1870ac7ddfbfSEd Maste         {
1871ac7ddfbfSEd Maste             result.AppendError ("Invalid argument for command option --pass; must be true or false.\n");
1872ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
1873ac7ddfbfSEd Maste             return false;
1874ac7ddfbfSEd Maste         }
1875ac7ddfbfSEd Maste 
1876ac7ddfbfSEd Maste         size_t num_args = signal_args.GetArgumentCount();
1877b91a7dfcSDimitry Andric         UnixSignalsSP signals_sp = process_sp->GetUnixSignals();
1878ac7ddfbfSEd Maste         int num_signals_set = 0;
1879ac7ddfbfSEd Maste 
1880ac7ddfbfSEd Maste         if (num_args > 0)
1881ac7ddfbfSEd Maste         {
1882ac7ddfbfSEd Maste             for (size_t i = 0; i < num_args; ++i)
1883ac7ddfbfSEd Maste             {
1884b91a7dfcSDimitry Andric                 int32_t signo = signals_sp->GetSignalNumberFromName(signal_args.GetArgumentAtIndex(i));
1885ac7ddfbfSEd Maste                 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
1886ac7ddfbfSEd Maste                 {
1887ac7ddfbfSEd Maste                     // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees
1888ac7ddfbfSEd Maste                     // the value is either 0 or 1.
1889ac7ddfbfSEd Maste                     if (stop_action != -1)
1890b91a7dfcSDimitry Andric                         signals_sp->SetShouldStop(signo, stop_action);
1891ac7ddfbfSEd Maste                     if (pass_action != -1)
1892ac7ddfbfSEd Maste                     {
1893b91a7dfcSDimitry Andric                         bool suppress = !pass_action;
1894b91a7dfcSDimitry Andric                         signals_sp->SetShouldSuppress(signo, suppress);
1895ac7ddfbfSEd Maste                     }
1896ac7ddfbfSEd Maste                     if (notify_action != -1)
1897b91a7dfcSDimitry Andric                         signals_sp->SetShouldNotify(signo, notify_action);
1898ac7ddfbfSEd Maste                     ++num_signals_set;
1899ac7ddfbfSEd Maste                 }
1900ac7ddfbfSEd Maste                 else
1901ac7ddfbfSEd Maste                 {
1902ac7ddfbfSEd Maste                     result.AppendErrorWithFormat ("Invalid signal name '%s'\n", signal_args.GetArgumentAtIndex (i));
1903ac7ddfbfSEd Maste                 }
1904ac7ddfbfSEd Maste             }
1905ac7ddfbfSEd Maste         }
1906ac7ddfbfSEd Maste         else
1907ac7ddfbfSEd Maste         {
1908ac7ddfbfSEd Maste             // No signal specified, if any command options were specified, update ALL signals.
1909ac7ddfbfSEd Maste             if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1))
1910ac7ddfbfSEd Maste             {
1911ac7ddfbfSEd Maste                 if (m_interpreter.Confirm ("Do you really want to update all the signals?", false))
1912ac7ddfbfSEd Maste                 {
1913b91a7dfcSDimitry Andric                     int32_t signo = signals_sp->GetFirstSignalNumber();
1914ac7ddfbfSEd Maste                     while (signo != LLDB_INVALID_SIGNAL_NUMBER)
1915ac7ddfbfSEd Maste                     {
1916ac7ddfbfSEd Maste                         if (notify_action != -1)
1917b91a7dfcSDimitry Andric                             signals_sp->SetShouldNotify(signo, notify_action);
1918ac7ddfbfSEd Maste                         if (stop_action != -1)
1919b91a7dfcSDimitry Andric                             signals_sp->SetShouldStop(signo, stop_action);
1920ac7ddfbfSEd Maste                         if (pass_action != -1)
1921ac7ddfbfSEd Maste                         {
1922b91a7dfcSDimitry Andric                             bool suppress = !pass_action;
1923b91a7dfcSDimitry Andric                             signals_sp->SetShouldSuppress(signo, suppress);
1924ac7ddfbfSEd Maste                         }
1925b91a7dfcSDimitry Andric                         signo = signals_sp->GetNextSignalNumber(signo);
1926ac7ddfbfSEd Maste                     }
1927ac7ddfbfSEd Maste                 }
1928ac7ddfbfSEd Maste             }
1929ac7ddfbfSEd Maste         }
1930ac7ddfbfSEd Maste 
1931b91a7dfcSDimitry Andric         PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals_sp);
1932ac7ddfbfSEd Maste 
1933ac7ddfbfSEd Maste         if (num_signals_set > 0)
1934ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1935ac7ddfbfSEd Maste         else
1936ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
1937ac7ddfbfSEd Maste 
1938ac7ddfbfSEd Maste         return result.Succeeded();
1939ac7ddfbfSEd Maste     }
1940ac7ddfbfSEd Maste 
1941ac7ddfbfSEd Maste     CommandOptions m_options;
1942ac7ddfbfSEd Maste };
1943ac7ddfbfSEd Maste 
1944ac7ddfbfSEd Maste OptionDefinition
1945ac7ddfbfSEd Maste CommandObjectProcessHandle::CommandOptions::g_option_table[] =
1946ac7ddfbfSEd Maste {
19470127ef0fSEd Maste { LLDB_OPT_SET_1, false, "stop",   's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Whether or not the process should be stopped if the signal is received." },
19480127ef0fSEd Maste { LLDB_OPT_SET_1, false, "notify", 'n', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Whether or not the debugger should notify the user if the signal is received." },
19490127ef0fSEd Maste { LLDB_OPT_SET_1, false, "pass",  'p', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." },
19500127ef0fSEd Maste { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
1951ac7ddfbfSEd Maste };
1952ac7ddfbfSEd Maste 
1953ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1954ac7ddfbfSEd Maste // CommandObjectMultiwordProcess
1955ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1956ac7ddfbfSEd Maste 
1957ac7ddfbfSEd Maste CommandObjectMultiwordProcess::CommandObjectMultiwordProcess (CommandInterpreter &interpreter) :
1958ac7ddfbfSEd Maste     CommandObjectMultiword (interpreter,
1959ac7ddfbfSEd Maste                             "process",
1960ac7ddfbfSEd Maste                             "A set of commands for operating on a process.",
1961ac7ddfbfSEd Maste                             "process <subcommand> [<subcommand-options>]")
1962ac7ddfbfSEd Maste {
1963ac7ddfbfSEd Maste     LoadSubCommand ("attach",      CommandObjectSP (new CommandObjectProcessAttach    (interpreter)));
1964ac7ddfbfSEd Maste     LoadSubCommand ("launch",      CommandObjectSP (new CommandObjectProcessLaunch    (interpreter)));
1965ac7ddfbfSEd Maste     LoadSubCommand ("continue",    CommandObjectSP (new CommandObjectProcessContinue  (interpreter)));
1966ac7ddfbfSEd Maste     LoadSubCommand ("connect",     CommandObjectSP (new CommandObjectProcessConnect   (interpreter)));
1967ac7ddfbfSEd Maste     LoadSubCommand ("detach",      CommandObjectSP (new CommandObjectProcessDetach    (interpreter)));
1968ac7ddfbfSEd Maste     LoadSubCommand ("load",        CommandObjectSP (new CommandObjectProcessLoad      (interpreter)));
1969ac7ddfbfSEd Maste     LoadSubCommand ("unload",      CommandObjectSP (new CommandObjectProcessUnload    (interpreter)));
1970ac7ddfbfSEd Maste     LoadSubCommand ("signal",      CommandObjectSP (new CommandObjectProcessSignal    (interpreter)));
1971ac7ddfbfSEd Maste     LoadSubCommand ("handle",      CommandObjectSP (new CommandObjectProcessHandle    (interpreter)));
1972ac7ddfbfSEd Maste     LoadSubCommand ("status",      CommandObjectSP (new CommandObjectProcessStatus    (interpreter)));
1973ac7ddfbfSEd Maste     LoadSubCommand ("interrupt",   CommandObjectSP (new CommandObjectProcessInterrupt (interpreter)));
1974ac7ddfbfSEd Maste     LoadSubCommand ("kill",        CommandObjectSP (new CommandObjectProcessKill      (interpreter)));
1975ac7ddfbfSEd Maste     LoadSubCommand ("plugin",      CommandObjectSP (new CommandObjectProcessPlugin    (interpreter)));
19760127ef0fSEd Maste     LoadSubCommand ("save-core",   CommandObjectSP (new CommandObjectProcessSaveCore  (interpreter)));
1977ac7ddfbfSEd Maste }
1978ac7ddfbfSEd Maste 
1979ac7ddfbfSEd Maste CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess ()
1980ac7ddfbfSEd Maste {
1981ac7ddfbfSEd Maste }
1982ac7ddfbfSEd Maste 
1983