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 // C Includes
11ac7ddfbfSEd Maste // C++ Includes
12ac7ddfbfSEd Maste // Other libraries and framework includes
13ac7ddfbfSEd Maste // Project includes
144bb0738eSEd Maste #include "CommandObjectProcess.h"
15ac7ddfbfSEd Maste #include "lldb/Breakpoint/Breakpoint.h"
16ac7ddfbfSEd Maste #include "lldb/Breakpoint/BreakpointLocation.h"
17ac7ddfbfSEd Maste #include "lldb/Breakpoint/BreakpointSite.h"
18ac7ddfbfSEd Maste #include "lldb/Core/State.h"
19ac7ddfbfSEd Maste #include "lldb/Core/Module.h"
200127ef0fSEd Maste #include "lldb/Core/PluginManager.h"
21ac7ddfbfSEd Maste #include "lldb/Host/Host.h"
221c3bbb01SEd Maste #include "lldb/Host/StringConvert.h"
23ac7ddfbfSEd Maste #include "lldb/Interpreter/Args.h"
24ac7ddfbfSEd Maste #include "lldb/Interpreter/Options.h"
25ac7ddfbfSEd Maste #include "lldb/Interpreter/CommandInterpreter.h"
26ac7ddfbfSEd Maste #include "lldb/Interpreter/CommandReturnObject.h"
27ac7ddfbfSEd Maste #include "lldb/Target/Platform.h"
28ac7ddfbfSEd Maste #include "lldb/Target/Process.h"
29ac7ddfbfSEd Maste #include "lldb/Target/StopInfo.h"
30ac7ddfbfSEd Maste #include "lldb/Target/Target.h"
31ac7ddfbfSEd Maste #include "lldb/Target/Thread.h"
321c3bbb01SEd Maste #include "lldb/Target/UnixSignals.h"
33ac7ddfbfSEd Maste 
34ac7ddfbfSEd Maste using namespace lldb;
35ac7ddfbfSEd Maste using namespace lldb_private;
36ac7ddfbfSEd Maste 
37ac7ddfbfSEd Maste class CommandObjectProcessLaunchOrAttach : public CommandObjectParsed
38ac7ddfbfSEd Maste {
39ac7ddfbfSEd Maste public:
40ac7ddfbfSEd Maste     CommandObjectProcessLaunchOrAttach (CommandInterpreter &interpreter,
41ac7ddfbfSEd Maste                                        const char *name,
42ac7ddfbfSEd Maste                                        const char *help,
43ac7ddfbfSEd Maste                                        const char *syntax,
44ac7ddfbfSEd Maste                                        uint32_t flags,
45ac7ddfbfSEd Maste                                        const char *new_process_action) :
46ac7ddfbfSEd Maste         CommandObjectParsed (interpreter, name, help, syntax, flags),
47ac7ddfbfSEd Maste         m_new_process_action (new_process_action) {}
48ac7ddfbfSEd Maste 
494bb0738eSEd Maste     ~CommandObjectProcessLaunchOrAttach() override = default;
504bb0738eSEd Maste 
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);
844bb0738eSEd Maste                             process = nullptr;
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);
984bb0738eSEd Maste                             process = nullptr;
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     }
1114bb0738eSEd Maste 
112ac7ddfbfSEd Maste     std::string m_new_process_action;
113ac7ddfbfSEd Maste };
1144bb0738eSEd Maste 
115ac7ddfbfSEd Maste //-------------------------------------------------------------------------
116ac7ddfbfSEd Maste // CommandObjectProcessLaunch
117ac7ddfbfSEd Maste //-------------------------------------------------------------------------
118ac7ddfbfSEd Maste #pragma mark CommandObjectProcessLaunch
119ac7ddfbfSEd Maste class CommandObjectProcessLaunch : public CommandObjectProcessLaunchOrAttach
120ac7ddfbfSEd Maste {
121ac7ddfbfSEd Maste public:
122ac7ddfbfSEd Maste     CommandObjectProcessLaunch (CommandInterpreter &interpreter) :
123ac7ddfbfSEd Maste         CommandObjectProcessLaunchOrAttach(interpreter,
124ac7ddfbfSEd Maste                                            "process launch",
125ac7ddfbfSEd Maste                                            "Launch the executable in the debugger.",
1264bb0738eSEd Maste                                            nullptr,
1271c3bbb01SEd Maste                                            eCommandRequiresTarget,
128ac7ddfbfSEd Maste                                            "restart"),
129ac7ddfbfSEd Maste         m_options (interpreter)
130ac7ddfbfSEd Maste     {
131ac7ddfbfSEd Maste         CommandArgumentEntry arg;
132ac7ddfbfSEd Maste         CommandArgumentData run_args_arg;
133ac7ddfbfSEd Maste 
134ac7ddfbfSEd Maste         // Define the first (and only) variant of this arg.
135ac7ddfbfSEd Maste         run_args_arg.arg_type = eArgTypeRunArgs;
136ac7ddfbfSEd Maste         run_args_arg.arg_repetition = eArgRepeatOptional;
137ac7ddfbfSEd Maste 
138ac7ddfbfSEd Maste         // There is only one variant this argument could be; put it into the argument entry.
139ac7ddfbfSEd Maste         arg.push_back (run_args_arg);
140ac7ddfbfSEd Maste 
141ac7ddfbfSEd Maste         // Push the data for the first argument into the m_arguments vector.
142ac7ddfbfSEd Maste         m_arguments.push_back (arg);
143ac7ddfbfSEd Maste     }
144ac7ddfbfSEd Maste 
1454bb0738eSEd Maste     ~CommandObjectProcessLaunch() override = default;
146ac7ddfbfSEd Maste 
1479f2f44ceSEd Maste     int
148ac7ddfbfSEd Maste     HandleArgumentCompletion (Args &input,
149ac7ddfbfSEd Maste                               int &cursor_index,
150ac7ddfbfSEd Maste                               int &cursor_char_position,
151ac7ddfbfSEd Maste                               OptionElementVector &opt_element_vector,
152ac7ddfbfSEd Maste                               int match_start_point,
153ac7ddfbfSEd Maste                               int max_return_elements,
154ac7ddfbfSEd Maste                               bool &word_complete,
1559f2f44ceSEd Maste                               StringList &matches) override
156ac7ddfbfSEd Maste     {
157ac7ddfbfSEd Maste         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
158ac7ddfbfSEd Maste         completion_str.erase (cursor_char_position);
159ac7ddfbfSEd Maste 
160ac7ddfbfSEd Maste         CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
161ac7ddfbfSEd Maste                                                             CommandCompletions::eDiskFileCompletion,
162ac7ddfbfSEd Maste                                                             completion_str.c_str(),
163ac7ddfbfSEd Maste                                                             match_start_point,
164ac7ddfbfSEd Maste                                                             max_return_elements,
1654bb0738eSEd Maste                                                             nullptr,
166ac7ddfbfSEd Maste                                                             word_complete,
167ac7ddfbfSEd Maste                                                             matches);
168ac7ddfbfSEd Maste         return matches.GetSize();
169ac7ddfbfSEd Maste     }
170ac7ddfbfSEd Maste 
171ac7ddfbfSEd Maste     Options *
1729f2f44ceSEd Maste     GetOptions () override
173ac7ddfbfSEd Maste     {
174ac7ddfbfSEd Maste         return &m_options;
175ac7ddfbfSEd Maste     }
176ac7ddfbfSEd Maste 
1779f2f44ceSEd Maste     const char *
1789f2f44ceSEd Maste     GetRepeatCommand (Args &current_command_args, uint32_t index) override
179ac7ddfbfSEd Maste     {
180ac7ddfbfSEd Maste         // No repeat for "process launch"...
181ac7ddfbfSEd Maste         return "";
182ac7ddfbfSEd Maste     }
183ac7ddfbfSEd Maste 
184ac7ddfbfSEd Maste protected:
185ac7ddfbfSEd Maste     bool
1869f2f44ceSEd Maste     DoExecute (Args& launch_args, CommandReturnObject &result) override
187ac7ddfbfSEd Maste     {
188ac7ddfbfSEd Maste         Debugger &debugger = m_interpreter.GetDebugger();
189ac7ddfbfSEd Maste         Target *target = debugger.GetSelectedTarget().get();
1904bb0738eSEd Maste         // If our listener is nullptr, users aren't allows to launch
19112b93ac6SEd Maste         ModuleSP exe_module_sp = target->GetExecutableModule();
192ac7ddfbfSEd Maste 
1934bb0738eSEd Maste         if (exe_module_sp == nullptr)
194ac7ddfbfSEd Maste         {
195ac7ddfbfSEd Maste             result.AppendError ("no file in target, create a debug target using the 'target create' command");
196ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
197ac7ddfbfSEd Maste             return false;
198ac7ddfbfSEd Maste         }
199ac7ddfbfSEd Maste 
200ac7ddfbfSEd Maste         StateType state = eStateInvalid;
201ac7ddfbfSEd Maste 
20212b93ac6SEd Maste         if (!StopProcessIfNecessary(m_exe_ctx.GetProcessPtr(), state, result))
203ac7ddfbfSEd Maste             return false;
204ac7ddfbfSEd Maste 
205ac7ddfbfSEd Maste         const char *target_settings_argv0 = target->GetArg0();
206ac7ddfbfSEd Maste 
2070127ef0fSEd Maste         // Determine whether we will disable ASLR or leave it in the default state (i.e. enabled if the platform supports it).
2080127ef0fSEd Maste         // First check if the process launch options explicitly turn on/off disabling ASLR.  If so, use that setting;
2090127ef0fSEd Maste         // otherwise, use the 'settings target.disable-aslr' setting.
2100127ef0fSEd Maste         bool disable_aslr = false;
2110127ef0fSEd Maste         if (m_options.disable_aslr != eLazyBoolCalculate)
2120127ef0fSEd Maste         {
2130127ef0fSEd Maste             // The user specified an explicit setting on the process launch line.  Use it.
2140127ef0fSEd Maste             disable_aslr = (m_options.disable_aslr == eLazyBoolYes);
2150127ef0fSEd Maste         }
2160127ef0fSEd Maste         else
2170127ef0fSEd Maste         {
2180127ef0fSEd Maste             // The user did not explicitly specify whether to disable ASLR.  Fall back to the target.disable-aslr setting.
2190127ef0fSEd Maste             disable_aslr = target->GetDisableASLR ();
2200127ef0fSEd Maste         }
2210127ef0fSEd Maste 
2220127ef0fSEd Maste         if (disable_aslr)
22312b93ac6SEd Maste             m_options.launch_info.GetFlags().Set (eLaunchFlagDisableASLR);
2240127ef0fSEd Maste         else
2250127ef0fSEd Maste             m_options.launch_info.GetFlags().Clear (eLaunchFlagDisableASLR);
2260127ef0fSEd Maste 
2270127ef0fSEd Maste         if (target->GetDetachOnError())
2280127ef0fSEd Maste             m_options.launch_info.GetFlags().Set (eLaunchFlagDetachOnError);
22912b93ac6SEd Maste 
23012b93ac6SEd Maste         if (target->GetDisableSTDIO())
23112b93ac6SEd Maste             m_options.launch_info.GetFlags().Set (eLaunchFlagDisableSTDIO);
23212b93ac6SEd Maste 
23312b93ac6SEd Maste         Args environment;
23412b93ac6SEd Maste         target->GetEnvironmentAsArgs (environment);
23512b93ac6SEd Maste         if (environment.GetArgumentCount() > 0)
23612b93ac6SEd Maste             m_options.launch_info.GetEnvironmentEntries ().AppendArguments (environment);
237ac7ddfbfSEd Maste 
238ac7ddfbfSEd Maste         if (target_settings_argv0)
239ac7ddfbfSEd Maste         {
240ac7ddfbfSEd Maste             m_options.launch_info.GetArguments().AppendArgument (target_settings_argv0);
24112b93ac6SEd Maste             m_options.launch_info.SetExecutableFile(exe_module_sp->GetPlatformFileSpec(), false);
242ac7ddfbfSEd Maste         }
243ac7ddfbfSEd Maste         else
244ac7ddfbfSEd Maste         {
24512b93ac6SEd Maste             m_options.launch_info.SetExecutableFile(exe_module_sp->GetPlatformFileSpec(), true);
246ac7ddfbfSEd Maste         }
247ac7ddfbfSEd Maste 
248ac7ddfbfSEd Maste         if (launch_args.GetArgumentCount() == 0)
249ac7ddfbfSEd Maste         {
2501c3bbb01SEd Maste             m_options.launch_info.GetArguments().AppendArguments (target->GetProcessLaunchInfo().GetArguments());
251ac7ddfbfSEd Maste         }
252ac7ddfbfSEd Maste         else
253ac7ddfbfSEd Maste         {
254ac7ddfbfSEd Maste             m_options.launch_info.GetArguments().AppendArguments (launch_args);
255ac7ddfbfSEd Maste             // Save the arguments for subsequent runs in the current target.
256ac7ddfbfSEd Maste             target->SetRunArguments (launch_args);
257ac7ddfbfSEd Maste         }
258ac7ddfbfSEd Maste 
2597aa51b79SEd Maste         StreamString stream;
2607aa51b79SEd Maste         Error error = target->Launch(m_options.launch_info, &stream);
261ac7ddfbfSEd Maste 
262ac7ddfbfSEd Maste         if (error.Success())
263ac7ddfbfSEd Maste         {
26412b93ac6SEd Maste             ProcessSP process_sp (target->GetProcessSP());
26512b93ac6SEd Maste             if (process_sp)
266ac7ddfbfSEd Maste             {
2671c3bbb01SEd Maste                 // There is a race condition where this thread will return up the call stack to the main command
2681c3bbb01SEd Maste                 // handler and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has
2691c3bbb01SEd Maste                 // a chance to call PushProcessIOHandler().
2701c3bbb01SEd Maste                 process_sp->SyncIOHandler (0, 2000);
2711c3bbb01SEd Maste 
2727aa51b79SEd Maste                 const char *data = stream.GetData();
2737aa51b79SEd Maste                 if (data && strlen(data) > 0)
2747aa51b79SEd Maste                     result.AppendMessage(stream.GetData());
2751c3bbb01SEd Maste                 const char *archname = exe_module_sp->GetArchitecture().GetArchitectureName();
27612b93ac6SEd Maste                 result.AppendMessageWithFormat ("Process %" PRIu64 " launched: '%s' (%s)\n", process_sp->GetID(), exe_module_sp->GetFileSpec().GetPath().c_str(), archname);
277ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusSuccessFinishResult);
27812b93ac6SEd Maste                 result.SetDidChangeProcessState (true);
279ac7ddfbfSEd Maste             }
280ac7ddfbfSEd Maste             else
281ac7ddfbfSEd Maste             {
28212b93ac6SEd Maste                 result.AppendError("no error returned from Target::Launch, and target has no process");
283ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusFailed);
284ac7ddfbfSEd Maste             }
285ac7ddfbfSEd Maste         }
286ac7ddfbfSEd Maste         else
287ac7ddfbfSEd Maste         {
28812b93ac6SEd Maste             result.AppendError(error.AsCString());
289ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
290ac7ddfbfSEd Maste         }
291ac7ddfbfSEd Maste         return result.Succeeded();
292ac7ddfbfSEd Maste     }
293ac7ddfbfSEd Maste 
294ac7ddfbfSEd Maste protected:
295ac7ddfbfSEd Maste     ProcessLaunchCommandOptions m_options;
296ac7ddfbfSEd Maste };
297ac7ddfbfSEd Maste 
298ac7ddfbfSEd Maste 
299ac7ddfbfSEd Maste //#define SET1 LLDB_OPT_SET_1
300ac7ddfbfSEd Maste //#define SET2 LLDB_OPT_SET_2
301ac7ddfbfSEd Maste //#define SET3 LLDB_OPT_SET_3
302ac7ddfbfSEd Maste //
303ac7ddfbfSEd Maste //OptionDefinition
304ac7ddfbfSEd Maste //CommandObjectProcessLaunch::CommandOptions::g_option_table[] =
305ac7ddfbfSEd Maste //{
3064bb0738eSEd Maste //{ SET1 | SET2 | SET3, false, "stop-at-entry", 's', OptionParser::eNoArgument,       nullptr, 0, eArgTypeNone,    "Stop at the entry point of the program when launching a process."},
3074bb0738eSEd Maste //{ SET1              , false, "stdin",         'i', OptionParser::eRequiredArgument, nullptr, 0, eArgTypeDirectoryName,    "Redirect stdin for the process to <path>."},
3084bb0738eSEd Maste //{ SET1              , false, "stdout",        'o', OptionParser::eRequiredArgument, nullptr, 0, eArgTypeDirectoryName,    "Redirect stdout for the process to <path>."},
3094bb0738eSEd Maste //{ SET1              , false, "stderr",        'e', OptionParser::eRequiredArgument, nullptr, 0, eArgTypeDirectoryName,    "Redirect stderr for the process to <path>."},
3104bb0738eSEd Maste //{ SET1 | SET2 | SET3, false, "plugin",        'p', OptionParser::eRequiredArgument, nullptr, 0, eArgTypePlugin,  "Name of the process plugin you want to use."},
3114bb0738eSEd Maste //{        SET2       , false, "tty",           't', OptionParser::eOptionalArgument, nullptr, 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."},
3124bb0738eSEd Maste //{               SET3, false, "no-stdio",      'n', OptionParser::eNoArgument,       nullptr, 0, eArgTypeNone,    "Do not set up for terminal I/O to go to running process."},
3134bb0738eSEd Maste //{ SET1 | SET2 | SET3, false, "working-dir",   'w', OptionParser::eRequiredArgument, nullptr, 0, eArgTypeDirectoryName,    "Set the current working directory to <path> when running the inferior."},
3144bb0738eSEd Maste //{ 0,                  false, nullptr,             0,  0,                 nullptr, 0, eArgTypeNone,    nullptr }
315ac7ddfbfSEd Maste //};
316ac7ddfbfSEd Maste //
317ac7ddfbfSEd Maste //#undef SET1
318ac7ddfbfSEd Maste //#undef SET2
319ac7ddfbfSEd Maste //#undef SET3
320ac7ddfbfSEd Maste 
321ac7ddfbfSEd Maste //-------------------------------------------------------------------------
322ac7ddfbfSEd Maste // CommandObjectProcessAttach
323ac7ddfbfSEd Maste //-------------------------------------------------------------------------
324ac7ddfbfSEd Maste #pragma mark CommandObjectProcessAttach
325ac7ddfbfSEd Maste class CommandObjectProcessAttach : public CommandObjectProcessLaunchOrAttach
326ac7ddfbfSEd Maste {
327ac7ddfbfSEd Maste public:
328ac7ddfbfSEd Maste     class CommandOptions : public Options
329ac7ddfbfSEd Maste     {
330ac7ddfbfSEd Maste     public:
331ac7ddfbfSEd Maste         CommandOptions (CommandInterpreter &interpreter) :
332ac7ddfbfSEd Maste             Options(interpreter)
333ac7ddfbfSEd Maste         {
334ac7ddfbfSEd Maste             // Keep default values of all options in one place: OptionParsingStarting ()
335ac7ddfbfSEd Maste             OptionParsingStarting ();
336ac7ddfbfSEd Maste         }
337ac7ddfbfSEd Maste 
3384bb0738eSEd Maste         ~CommandOptions() override = default;
339ac7ddfbfSEd Maste 
340ac7ddfbfSEd Maste         Error
3419f2f44ceSEd Maste         SetOptionValue (uint32_t option_idx, const char *option_arg) override
342ac7ddfbfSEd Maste         {
343ac7ddfbfSEd Maste             Error error;
344ac7ddfbfSEd Maste             const int short_option = m_getopt_table[option_idx].val;
345ac7ddfbfSEd Maste             bool success = false;
346ac7ddfbfSEd Maste             switch (short_option)
347ac7ddfbfSEd Maste             {
348ac7ddfbfSEd Maste                 case 'c':
349ac7ddfbfSEd Maste                     attach_info.SetContinueOnceAttached(true);
350ac7ddfbfSEd Maste                     break;
351ac7ddfbfSEd Maste 
352ac7ddfbfSEd Maste                 case 'p':
353ac7ddfbfSEd Maste                     {
3541c3bbb01SEd Maste                         lldb::pid_t pid = StringConvert::ToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success);
355ac7ddfbfSEd Maste                         if (!success || pid == LLDB_INVALID_PROCESS_ID)
356ac7ddfbfSEd Maste                         {
357ac7ddfbfSEd Maste                             error.SetErrorStringWithFormat("invalid process ID '%s'", option_arg);
358ac7ddfbfSEd Maste                         }
359ac7ddfbfSEd Maste                         else
360ac7ddfbfSEd Maste                         {
361ac7ddfbfSEd Maste                             attach_info.SetProcessID (pid);
362ac7ddfbfSEd Maste                         }
363ac7ddfbfSEd Maste                     }
364ac7ddfbfSEd Maste                     break;
365ac7ddfbfSEd Maste 
366ac7ddfbfSEd Maste                 case 'P':
367ac7ddfbfSEd Maste                     attach_info.SetProcessPluginName (option_arg);
368ac7ddfbfSEd Maste                     break;
369ac7ddfbfSEd Maste 
370ac7ddfbfSEd Maste                 case 'n':
371ac7ddfbfSEd Maste                     attach_info.GetExecutableFile().SetFile(option_arg, false);
372ac7ddfbfSEd Maste                     break;
373ac7ddfbfSEd Maste 
374ac7ddfbfSEd Maste                 case 'w':
375ac7ddfbfSEd Maste                     attach_info.SetWaitForLaunch(true);
376ac7ddfbfSEd Maste                     break;
377ac7ddfbfSEd Maste 
378ac7ddfbfSEd Maste                 case 'i':
379ac7ddfbfSEd Maste                     attach_info.SetIgnoreExisting(false);
380ac7ddfbfSEd Maste                     break;
381ac7ddfbfSEd Maste 
382ac7ddfbfSEd Maste                 default:
383ac7ddfbfSEd Maste                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
384ac7ddfbfSEd Maste                     break;
385ac7ddfbfSEd Maste             }
386ac7ddfbfSEd Maste             return error;
387ac7ddfbfSEd Maste         }
388ac7ddfbfSEd Maste 
389ac7ddfbfSEd Maste         void
3909f2f44ceSEd Maste         OptionParsingStarting () override
391ac7ddfbfSEd Maste         {
392ac7ddfbfSEd Maste             attach_info.Clear();
393ac7ddfbfSEd Maste         }
394ac7ddfbfSEd Maste 
395ac7ddfbfSEd Maste         const OptionDefinition*
3969f2f44ceSEd Maste         GetDefinitions () override
397ac7ddfbfSEd Maste         {
398ac7ddfbfSEd Maste             return g_option_table;
399ac7ddfbfSEd Maste         }
400ac7ddfbfSEd Maste 
4019f2f44ceSEd Maste         bool
402ac7ddfbfSEd Maste         HandleOptionArgumentCompletion (Args &input,
403ac7ddfbfSEd Maste                                         int cursor_index,
404ac7ddfbfSEd Maste                                         int char_pos,
405ac7ddfbfSEd Maste                                         OptionElementVector &opt_element_vector,
406ac7ddfbfSEd Maste                                         int opt_element_index,
407ac7ddfbfSEd Maste                                         int match_start_point,
408ac7ddfbfSEd Maste                                         int max_return_elements,
409ac7ddfbfSEd Maste                                         bool &word_complete,
4109f2f44ceSEd Maste                                         StringList &matches) override
411ac7ddfbfSEd Maste         {
412ac7ddfbfSEd Maste             int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
413ac7ddfbfSEd Maste             int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
414ac7ddfbfSEd Maste 
415ac7ddfbfSEd Maste             // We are only completing the name option for now...
416ac7ddfbfSEd Maste 
417ac7ddfbfSEd Maste             const OptionDefinition *opt_defs = GetDefinitions();
418ac7ddfbfSEd Maste             if (opt_defs[opt_defs_index].short_option == 'n')
419ac7ddfbfSEd Maste             {
420ac7ddfbfSEd Maste                 // Are we in the name?
421ac7ddfbfSEd Maste 
422ac7ddfbfSEd Maste                 // Look to see if there is a -P argument provided, and if so use that plugin, otherwise
423ac7ddfbfSEd Maste                 // use the default plugin.
424ac7ddfbfSEd Maste 
4254bb0738eSEd Maste                 const char *partial_name = nullptr;
426ac7ddfbfSEd Maste                 partial_name = input.GetArgumentAtIndex(opt_arg_pos);
427ac7ddfbfSEd Maste 
428ac7ddfbfSEd Maste                 PlatformSP platform_sp (m_interpreter.GetPlatform (true));
429ac7ddfbfSEd Maste                 if (platform_sp)
430ac7ddfbfSEd Maste                 {
431ac7ddfbfSEd Maste                     ProcessInstanceInfoList process_infos;
432ac7ddfbfSEd Maste                     ProcessInstanceInfoMatch match_info;
433ac7ddfbfSEd Maste                     if (partial_name)
434ac7ddfbfSEd Maste                     {
435ac7ddfbfSEd Maste                         match_info.GetProcessInfo().GetExecutableFile().SetFile(partial_name, false);
436ac7ddfbfSEd Maste                         match_info.SetNameMatchType(eNameMatchStartsWith);
437ac7ddfbfSEd Maste                     }
438ac7ddfbfSEd Maste                     platform_sp->FindProcesses (match_info, process_infos);
439ac7ddfbfSEd Maste                     const size_t num_matches = process_infos.GetSize();
440ac7ddfbfSEd Maste                     if (num_matches > 0)
441ac7ddfbfSEd Maste                     {
442ac7ddfbfSEd Maste                         for (size_t i = 0; i < num_matches; ++i)
443ac7ddfbfSEd Maste                         {
444ac7ddfbfSEd Maste                             matches.AppendString (process_infos.GetProcessNameAtIndex(i),
445ac7ddfbfSEd Maste                                                   process_infos.GetProcessNameLengthAtIndex(i));
446ac7ddfbfSEd Maste                         }
447ac7ddfbfSEd Maste                     }
448ac7ddfbfSEd Maste                 }
449ac7ddfbfSEd Maste             }
450ac7ddfbfSEd Maste 
451ac7ddfbfSEd Maste             return false;
452ac7ddfbfSEd Maste         }
453ac7ddfbfSEd Maste 
454ac7ddfbfSEd Maste         // Options table: Required for subclasses of Options.
455ac7ddfbfSEd Maste 
456ac7ddfbfSEd Maste         static OptionDefinition g_option_table[];
457ac7ddfbfSEd Maste 
458ac7ddfbfSEd Maste         // Instance variables to hold the values for command options.
459ac7ddfbfSEd Maste 
460ac7ddfbfSEd Maste         ProcessAttachInfo attach_info;
461ac7ddfbfSEd Maste     };
462ac7ddfbfSEd Maste 
463ac7ddfbfSEd Maste     CommandObjectProcessAttach (CommandInterpreter &interpreter) :
464ac7ddfbfSEd Maste         CommandObjectProcessLaunchOrAttach (interpreter,
465ac7ddfbfSEd Maste                                             "process attach",
466ac7ddfbfSEd Maste                                             "Attach to a process.",
467ac7ddfbfSEd Maste                                             "process attach <cmd-options>",
468ac7ddfbfSEd Maste                                             0,
469ac7ddfbfSEd Maste                                             "attach"),
470ac7ddfbfSEd Maste         m_options (interpreter)
471ac7ddfbfSEd Maste     {
472ac7ddfbfSEd Maste     }
473ac7ddfbfSEd Maste 
4744bb0738eSEd Maste     ~CommandObjectProcessAttach() override = default;
475ac7ddfbfSEd Maste 
476ac7ddfbfSEd Maste     Options *
4779f2f44ceSEd Maste     GetOptions () override
478ac7ddfbfSEd Maste     {
479ac7ddfbfSEd Maste         return &m_options;
480ac7ddfbfSEd Maste     }
481ac7ddfbfSEd Maste 
482ac7ddfbfSEd Maste protected:
483ac7ddfbfSEd Maste     bool
4849f2f44ceSEd Maste     DoExecute (Args& command, CommandReturnObject &result) override
485ac7ddfbfSEd Maste     {
4861c3bbb01SEd Maste         PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
4871c3bbb01SEd Maste 
488ac7ddfbfSEd Maste         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
489ac7ddfbfSEd Maste         // N.B. The attach should be synchronous.  It doesn't help much to get the prompt back between initiating the attach
490ac7ddfbfSEd Maste         // and the target actually stopping.  So even if the interpreter is set to be asynchronous, we wait for the stop
491ac7ddfbfSEd Maste         // ourselves here.
492ac7ddfbfSEd Maste 
493ac7ddfbfSEd Maste         StateType state = eStateInvalid;
494ac7ddfbfSEd Maste         Process *process = m_exe_ctx.GetProcessPtr();
495ac7ddfbfSEd Maste 
496ac7ddfbfSEd Maste         if (!StopProcessIfNecessary (process, state, result))
497ac7ddfbfSEd Maste             return false;
498ac7ddfbfSEd Maste 
4994bb0738eSEd Maste         if (target == nullptr)
500ac7ddfbfSEd Maste         {
501ac7ddfbfSEd Maste             // If there isn't a current target create one.
502ac7ddfbfSEd Maste             TargetSP new_target_sp;
503ac7ddfbfSEd Maste             Error error;
504ac7ddfbfSEd Maste 
505ac7ddfbfSEd Maste             error = m_interpreter.GetDebugger().GetTargetList().CreateTarget(m_interpreter.GetDebugger(),
5064bb0738eSEd Maste                                                                              nullptr,
5074bb0738eSEd Maste                                                                              nullptr,
508ac7ddfbfSEd Maste                                                                              false,
5094bb0738eSEd Maste                                                                              nullptr, // No platform options
510ac7ddfbfSEd Maste                                                                              new_target_sp);
511ac7ddfbfSEd Maste             target = new_target_sp.get();
5124bb0738eSEd Maste             if (target == nullptr || error.Fail())
513ac7ddfbfSEd Maste             {
514ac7ddfbfSEd Maste                 result.AppendError(error.AsCString("Error creating target"));
515ac7ddfbfSEd Maste                 return false;
516ac7ddfbfSEd Maste             }
517ac7ddfbfSEd Maste             m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target);
518ac7ddfbfSEd Maste         }
519ac7ddfbfSEd Maste 
520ac7ddfbfSEd Maste         // Record the old executable module, we want to issue a warning if the process of attaching changed the
521ac7ddfbfSEd Maste         // current executable (like somebody said "file foo" then attached to a PID whose executable was bar.)
522ac7ddfbfSEd Maste 
523ac7ddfbfSEd Maste         ModuleSP old_exec_module_sp = target->GetExecutableModule();
524ac7ddfbfSEd Maste         ArchSpec old_arch_spec = target->GetArchitecture();
525ac7ddfbfSEd Maste 
526ac7ddfbfSEd Maste         if (command.GetArgumentCount())
527ac7ddfbfSEd Maste         {
528ac7ddfbfSEd Maste             result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
529ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
5301c3bbb01SEd Maste             return false;
531ac7ddfbfSEd Maste         }
532ac7ddfbfSEd Maste 
5331c3bbb01SEd Maste         m_interpreter.UpdateExecutionContext(nullptr);
5347aa51b79SEd Maste         StreamString stream;
5351c3bbb01SEd Maste         const auto error = target->Attach(m_options.attach_info, &stream);
5361c3bbb01SEd Maste         if (error.Success())
5371c3bbb01SEd Maste         {
5381c3bbb01SEd Maste             ProcessSP process_sp (target->GetProcessSP());
5391c3bbb01SEd Maste             if (process_sp)
5401c3bbb01SEd Maste             {
5417aa51b79SEd Maste                 if (stream.GetData())
5427aa51b79SEd Maste                     result.AppendMessage(stream.GetData());
543ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
5441c3bbb01SEd Maste                 result.SetDidChangeProcessState (true);
545444ed5c5SDimitry Andric                 result.SetAbnormalStopWasExpected(true);
546ac7ddfbfSEd Maste             }
547ac7ddfbfSEd Maste             else
548ac7ddfbfSEd Maste             {
5491c3bbb01SEd Maste                 result.AppendError("no error returned from Target::Attach, and target has no process");
550ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusFailed);
55112b93ac6SEd Maste             }
55212b93ac6SEd Maste         }
55312b93ac6SEd Maste         else
55412b93ac6SEd Maste         {
55512b93ac6SEd Maste             result.AppendErrorWithFormat ("attach failed: %s\n", error.AsCString());
55612b93ac6SEd Maste             result.SetStatus (eReturnStatusFailed);
557ac7ddfbfSEd Maste         }
558ac7ddfbfSEd Maste 
5591c3bbb01SEd Maste         if (!result.Succeeded())
5601c3bbb01SEd Maste             return false;
5611c3bbb01SEd Maste 
562ac7ddfbfSEd Maste         // Okay, we're done.  Last step is to warn if the executable module has changed:
563ac7ddfbfSEd Maste         char new_path[PATH_MAX];
564ac7ddfbfSEd Maste         ModuleSP new_exec_module_sp (target->GetExecutableModule());
565ac7ddfbfSEd Maste         if (!old_exec_module_sp)
566ac7ddfbfSEd Maste         {
567ac7ddfbfSEd Maste             // We might not have a module if we attached to a raw pid...
568ac7ddfbfSEd Maste             if (new_exec_module_sp)
569ac7ddfbfSEd Maste             {
570ac7ddfbfSEd Maste                 new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX);
571ac7ddfbfSEd Maste                 result.AppendMessageWithFormat("Executable module set to \"%s\".\n", new_path);
572ac7ddfbfSEd Maste             }
573ac7ddfbfSEd Maste         }
574ac7ddfbfSEd Maste         else if (old_exec_module_sp->GetFileSpec() != new_exec_module_sp->GetFileSpec())
575ac7ddfbfSEd Maste         {
576ac7ddfbfSEd Maste             char old_path[PATH_MAX];
577ac7ddfbfSEd Maste 
578ac7ddfbfSEd Maste             old_exec_module_sp->GetFileSpec().GetPath (old_path, PATH_MAX);
579ac7ddfbfSEd Maste             new_exec_module_sp->GetFileSpec().GetPath (new_path, PATH_MAX);
580ac7ddfbfSEd Maste 
581ac7ddfbfSEd Maste             result.AppendWarningWithFormat("Executable module changed from \"%s\" to \"%s\".\n",
582ac7ddfbfSEd Maste                                                 old_path, new_path);
583ac7ddfbfSEd Maste         }
584ac7ddfbfSEd Maste 
585ac7ddfbfSEd Maste         if (!old_arch_spec.IsValid())
586ac7ddfbfSEd Maste         {
587ac7ddfbfSEd Maste             result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().GetTriple().getTriple().c_str());
588ac7ddfbfSEd Maste         }
589ac7ddfbfSEd Maste         else if (!old_arch_spec.IsExactMatch(target->GetArchitecture()))
590ac7ddfbfSEd Maste         {
591ac7ddfbfSEd Maste             result.AppendWarningWithFormat("Architecture changed from %s to %s.\n",
592ac7ddfbfSEd Maste                                            old_arch_spec.GetTriple().getTriple().c_str(),
593ac7ddfbfSEd Maste                                            target->GetArchitecture().GetTriple().getTriple().c_str());
594ac7ddfbfSEd Maste         }
595ac7ddfbfSEd Maste 
596ac7ddfbfSEd Maste         // This supports the use-case scenario of immediately continuing the process once attached.
597ac7ddfbfSEd Maste         if (m_options.attach_info.GetContinueOnceAttached())
598ac7ddfbfSEd Maste             m_interpreter.HandleCommand("process continue", eLazyBoolNo, result);
5991c3bbb01SEd Maste 
600ac7ddfbfSEd Maste         return result.Succeeded();
601ac7ddfbfSEd Maste     }
602ac7ddfbfSEd Maste 
603ac7ddfbfSEd Maste     CommandOptions m_options;
604ac7ddfbfSEd Maste };
605ac7ddfbfSEd Maste 
606ac7ddfbfSEd Maste OptionDefinition
607ac7ddfbfSEd Maste CommandObjectProcessAttach::CommandOptions::g_option_table[] =
608ac7ddfbfSEd Maste {
6094bb0738eSEd Maste { LLDB_OPT_SET_ALL, false, "continue",'c', OptionParser::eNoArgument,         nullptr, nullptr, 0, eArgTypeNone,         "Immediately continue the process once attached."},
6104bb0738eSEd Maste { LLDB_OPT_SET_ALL, false, "plugin",  'P', OptionParser::eRequiredArgument,   nullptr, nullptr, 0, eArgTypePlugin,       "Name of the process plugin you want to use."},
6114bb0738eSEd Maste { LLDB_OPT_SET_1,   false, "pid",     'p', OptionParser::eRequiredArgument,   nullptr, nullptr, 0, eArgTypePid,          "The process ID of an existing process to attach to."},
6124bb0738eSEd Maste { LLDB_OPT_SET_2,   false, "name",    'n', OptionParser::eRequiredArgument,   nullptr, nullptr, 0, eArgTypeProcessName,  "The name of the process to attach to."},
6134bb0738eSEd Maste { LLDB_OPT_SET_2,   false, "include-existing", 'i', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,         "Include existing processes when doing attach -w."},
6144bb0738eSEd Maste { LLDB_OPT_SET_2,   false, "waitfor", 'w', OptionParser::eNoArgument,         nullptr, nullptr, 0, eArgTypeNone,         "Wait for the process with <process-name> to launch."},
6154bb0738eSEd Maste { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
616ac7ddfbfSEd Maste };
617ac7ddfbfSEd Maste 
618ac7ddfbfSEd Maste //-------------------------------------------------------------------------
619ac7ddfbfSEd Maste // CommandObjectProcessContinue
620ac7ddfbfSEd Maste //-------------------------------------------------------------------------
621ac7ddfbfSEd Maste #pragma mark CommandObjectProcessContinue
622ac7ddfbfSEd Maste 
623ac7ddfbfSEd Maste class CommandObjectProcessContinue : public CommandObjectParsed
624ac7ddfbfSEd Maste {
625ac7ddfbfSEd Maste public:
626ac7ddfbfSEd Maste     CommandObjectProcessContinue (CommandInterpreter &interpreter) :
627ac7ddfbfSEd Maste         CommandObjectParsed (interpreter,
628ac7ddfbfSEd Maste                              "process continue",
629ac7ddfbfSEd Maste                              "Continue execution of all threads in the current process.",
630ac7ddfbfSEd Maste                              "process continue",
6311c3bbb01SEd Maste                              eCommandRequiresProcess       |
6321c3bbb01SEd Maste                              eCommandTryTargetAPILock      |
6331c3bbb01SEd Maste                              eCommandProcessMustBeLaunched |
6341c3bbb01SEd Maste                              eCommandProcessMustBePaused   ),
635ac7ddfbfSEd Maste         m_options(interpreter)
636ac7ddfbfSEd Maste     {
637ac7ddfbfSEd Maste     }
638ac7ddfbfSEd Maste 
6394bb0738eSEd Maste     ~CommandObjectProcessContinue() override = default;
640ac7ddfbfSEd Maste 
641ac7ddfbfSEd Maste protected:
642ac7ddfbfSEd Maste     class CommandOptions : public Options
643ac7ddfbfSEd Maste     {
644ac7ddfbfSEd Maste     public:
645ac7ddfbfSEd Maste         CommandOptions (CommandInterpreter &interpreter) :
646ac7ddfbfSEd Maste             Options(interpreter)
647ac7ddfbfSEd Maste         {
648ac7ddfbfSEd Maste             // Keep default values of all options in one place: OptionParsingStarting ()
649ac7ddfbfSEd Maste             OptionParsingStarting ();
650ac7ddfbfSEd Maste         }
651ac7ddfbfSEd Maste 
6524bb0738eSEd Maste         ~CommandOptions() override = default;
653ac7ddfbfSEd Maste 
654ac7ddfbfSEd Maste         Error
6559f2f44ceSEd Maste         SetOptionValue (uint32_t option_idx, const char *option_arg) override
656ac7ddfbfSEd Maste         {
657ac7ddfbfSEd Maste             Error error;
658ac7ddfbfSEd Maste             const int short_option = m_getopt_table[option_idx].val;
659ac7ddfbfSEd Maste             bool success = false;
660ac7ddfbfSEd Maste             switch (short_option)
661ac7ddfbfSEd Maste             {
662ac7ddfbfSEd Maste                 case 'i':
6631c3bbb01SEd Maste                     m_ignore = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
664ac7ddfbfSEd Maste                     if (!success)
665ac7ddfbfSEd Maste                         error.SetErrorStringWithFormat ("invalid value for ignore option: \"%s\", should be a number.", option_arg);
666ac7ddfbfSEd Maste                     break;
667ac7ddfbfSEd Maste 
668ac7ddfbfSEd Maste                 default:
669ac7ddfbfSEd Maste                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
670ac7ddfbfSEd Maste                     break;
671ac7ddfbfSEd Maste             }
672ac7ddfbfSEd Maste             return error;
673ac7ddfbfSEd Maste         }
674ac7ddfbfSEd Maste 
675ac7ddfbfSEd Maste         void
6769f2f44ceSEd Maste         OptionParsingStarting () override
677ac7ddfbfSEd Maste         {
678ac7ddfbfSEd Maste             m_ignore = 0;
679ac7ddfbfSEd Maste         }
680ac7ddfbfSEd Maste 
681ac7ddfbfSEd Maste         const OptionDefinition*
6829f2f44ceSEd Maste         GetDefinitions () override
683ac7ddfbfSEd Maste         {
684ac7ddfbfSEd Maste             return g_option_table;
685ac7ddfbfSEd Maste         }
686ac7ddfbfSEd Maste 
687ac7ddfbfSEd Maste         // Options table: Required for subclasses of Options.
688ac7ddfbfSEd Maste 
689ac7ddfbfSEd Maste         static OptionDefinition g_option_table[];
690ac7ddfbfSEd Maste 
691ac7ddfbfSEd Maste         uint32_t m_ignore;
692ac7ddfbfSEd Maste     };
693ac7ddfbfSEd Maste 
694ac7ddfbfSEd Maste     bool
6959f2f44ceSEd Maste     DoExecute (Args& command, CommandReturnObject &result) override
696ac7ddfbfSEd Maste     {
697ac7ddfbfSEd Maste         Process *process = m_exe_ctx.GetProcessPtr();
698ac7ddfbfSEd Maste         bool synchronous_execution = m_interpreter.GetSynchronous ();
699ac7ddfbfSEd Maste         StateType state = process->GetState();
700ac7ddfbfSEd Maste         if (state == eStateStopped)
701ac7ddfbfSEd Maste         {
702ac7ddfbfSEd Maste             if (command.GetArgumentCount() != 0)
703ac7ddfbfSEd Maste             {
704ac7ddfbfSEd Maste                 result.AppendErrorWithFormat ("The '%s' command does not take any arguments.\n", m_cmd_name.c_str());
705ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusFailed);
706ac7ddfbfSEd Maste                 return false;
707ac7ddfbfSEd Maste             }
708ac7ddfbfSEd Maste 
709ac7ddfbfSEd Maste             if (m_options.m_ignore > 0)
710ac7ddfbfSEd Maste             {
7114bb0738eSEd Maste                 ThreadSP sel_thread_sp(GetDefaultThread()->shared_from_this());
712ac7ddfbfSEd Maste                 if (sel_thread_sp)
713ac7ddfbfSEd Maste                 {
714ac7ddfbfSEd Maste                     StopInfoSP stop_info_sp = sel_thread_sp->GetStopInfo();
715ac7ddfbfSEd Maste                     if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonBreakpoint)
716ac7ddfbfSEd Maste                     {
717ac7ddfbfSEd Maste                         lldb::break_id_t bp_site_id = (lldb::break_id_t)stop_info_sp->GetValue();
718ac7ddfbfSEd Maste                         BreakpointSiteSP bp_site_sp(process->GetBreakpointSiteList().FindByID(bp_site_id));
719ac7ddfbfSEd Maste                         if (bp_site_sp)
720ac7ddfbfSEd Maste                         {
721ac7ddfbfSEd Maste                             const size_t num_owners = bp_site_sp->GetNumberOfOwners();
722ac7ddfbfSEd Maste                             for (size_t i = 0; i < num_owners; i++)
723ac7ddfbfSEd Maste                             {
724ac7ddfbfSEd Maste                                 Breakpoint &bp_ref = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
725ac7ddfbfSEd Maste                                 if (!bp_ref.IsInternal())
726ac7ddfbfSEd Maste                                 {
727ac7ddfbfSEd Maste                                     bp_ref.SetIgnoreCount(m_options.m_ignore);
728ac7ddfbfSEd Maste                                 }
729ac7ddfbfSEd Maste                             }
730ac7ddfbfSEd Maste                         }
731ac7ddfbfSEd Maste                     }
732ac7ddfbfSEd Maste                 }
733ac7ddfbfSEd Maste             }
734ac7ddfbfSEd Maste 
735ac7ddfbfSEd Maste             {  // Scope for thread list mutex:
7364bb0738eSEd Maste                 std::lock_guard<std::recursive_mutex> guard(process->GetThreadList().GetMutex());
737ac7ddfbfSEd Maste                 const uint32_t num_threads = process->GetThreadList().GetSize();
738ac7ddfbfSEd Maste 
739ac7ddfbfSEd Maste                 // Set the actions that the threads should each take when resuming
740ac7ddfbfSEd Maste                 for (uint32_t idx=0; idx<num_threads; ++idx)
741ac7ddfbfSEd Maste                 {
7420127ef0fSEd Maste                     const bool override_suspend = false;
7430127ef0fSEd Maste                     process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState (eStateRunning, override_suspend);
744ac7ddfbfSEd Maste                 }
745ac7ddfbfSEd Maste             }
746ac7ddfbfSEd Maste 
7471c3bbb01SEd Maste             const uint32_t iohandler_id = process->GetIOHandlerID();
7481c3bbb01SEd Maste 
7497aa51b79SEd Maste             StreamString stream;
7507aa51b79SEd Maste             Error error;
7517aa51b79SEd Maste             if (synchronous_execution)
7527aa51b79SEd Maste                 error = process->ResumeSynchronous (&stream);
7537aa51b79SEd Maste             else
7547aa51b79SEd Maste                 error = process->Resume ();
7550127ef0fSEd Maste 
756ac7ddfbfSEd Maste             if (error.Success())
757ac7ddfbfSEd Maste             {
7580127ef0fSEd Maste                 // There is a race condition where this thread will return up the call stack to the main command
7590127ef0fSEd Maste                  // handler and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has
7600127ef0fSEd Maste                  // a chance to call PushProcessIOHandler().
7611c3bbb01SEd Maste                 process->SyncIOHandler(iohandler_id, 2000);
7620127ef0fSEd Maste 
763ac7ddfbfSEd Maste                 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
764ac7ddfbfSEd Maste                 if (synchronous_execution)
765ac7ddfbfSEd Maste                 {
7667aa51b79SEd Maste                     // If any state changed events had anything to say, add that to the result
7677aa51b79SEd Maste                     if (stream.GetData())
7687aa51b79SEd Maste                         result.AppendMessage(stream.GetData());
769ac7ddfbfSEd Maste 
770ac7ddfbfSEd Maste                     result.SetDidChangeProcessState (true);
771ac7ddfbfSEd Maste                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
772ac7ddfbfSEd Maste                 }
773ac7ddfbfSEd Maste                 else
774ac7ddfbfSEd Maste                 {
775ac7ddfbfSEd Maste                     result.SetStatus (eReturnStatusSuccessContinuingNoResult);
776ac7ddfbfSEd Maste                 }
777ac7ddfbfSEd Maste             }
778ac7ddfbfSEd Maste             else
779ac7ddfbfSEd Maste             {
780ac7ddfbfSEd Maste                 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
781ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusFailed);
782ac7ddfbfSEd Maste             }
783ac7ddfbfSEd Maste         }
784ac7ddfbfSEd Maste         else
785ac7ddfbfSEd Maste         {
786ac7ddfbfSEd Maste             result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
787ac7ddfbfSEd Maste                                          StateAsCString(state));
788ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
789ac7ddfbfSEd Maste         }
790ac7ddfbfSEd Maste         return result.Succeeded();
791ac7ddfbfSEd Maste     }
792ac7ddfbfSEd Maste 
793ac7ddfbfSEd Maste     Options *
7949f2f44ceSEd Maste     GetOptions () override
795ac7ddfbfSEd Maste     {
796ac7ddfbfSEd Maste         return &m_options;
797ac7ddfbfSEd Maste     }
798ac7ddfbfSEd Maste 
799ac7ddfbfSEd Maste     CommandOptions m_options;
800ac7ddfbfSEd Maste };
801ac7ddfbfSEd Maste 
802ac7ddfbfSEd Maste OptionDefinition
803ac7ddfbfSEd Maste CommandObjectProcessContinue::CommandOptions::g_option_table[] =
804ac7ddfbfSEd Maste {
8054bb0738eSEd Maste { LLDB_OPT_SET_ALL, false, "ignore-count",'i', OptionParser::eRequiredArgument,         nullptr, nullptr, 0, eArgTypeUnsignedInteger,
806ac7ddfbfSEd Maste                            "Ignore <N> crossings of the breakpoint (if it exists) for the currently selected thread."},
8074bb0738eSEd Maste { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
808ac7ddfbfSEd Maste };
809ac7ddfbfSEd Maste 
810ac7ddfbfSEd Maste //-------------------------------------------------------------------------
811ac7ddfbfSEd Maste // CommandObjectProcessDetach
812ac7ddfbfSEd Maste //-------------------------------------------------------------------------
813ac7ddfbfSEd Maste #pragma mark CommandObjectProcessDetach
814ac7ddfbfSEd Maste 
815ac7ddfbfSEd Maste class CommandObjectProcessDetach : public CommandObjectParsed
816ac7ddfbfSEd Maste {
817ac7ddfbfSEd Maste public:
818ac7ddfbfSEd Maste     class CommandOptions : public Options
819ac7ddfbfSEd Maste     {
820ac7ddfbfSEd Maste     public:
821ac7ddfbfSEd Maste         CommandOptions (CommandInterpreter &interpreter) :
822ac7ddfbfSEd Maste             Options (interpreter)
823ac7ddfbfSEd Maste         {
824ac7ddfbfSEd Maste             OptionParsingStarting ();
825ac7ddfbfSEd Maste         }
826ac7ddfbfSEd Maste 
8274bb0738eSEd Maste         ~CommandOptions() override = default;
828ac7ddfbfSEd Maste 
829ac7ddfbfSEd Maste         Error
8309f2f44ceSEd Maste         SetOptionValue (uint32_t option_idx, const char *option_arg) override
831ac7ddfbfSEd Maste         {
832ac7ddfbfSEd Maste             Error error;
833ac7ddfbfSEd Maste             const int short_option = m_getopt_table[option_idx].val;
834ac7ddfbfSEd Maste 
835ac7ddfbfSEd Maste             switch (short_option)
836ac7ddfbfSEd Maste             {
837ac7ddfbfSEd Maste                 case 's':
838ac7ddfbfSEd Maste                     bool tmp_result;
839ac7ddfbfSEd Maste                     bool success;
840ac7ddfbfSEd Maste                     tmp_result = Args::StringToBoolean(option_arg, false, &success);
841ac7ddfbfSEd Maste                     if (!success)
842ac7ddfbfSEd Maste                         error.SetErrorStringWithFormat("invalid boolean option: \"%s\"", option_arg);
843ac7ddfbfSEd Maste                     else
844ac7ddfbfSEd Maste                     {
845ac7ddfbfSEd Maste                         if (tmp_result)
846ac7ddfbfSEd Maste                             m_keep_stopped = eLazyBoolYes;
847ac7ddfbfSEd Maste                         else
848ac7ddfbfSEd Maste                             m_keep_stopped = eLazyBoolNo;
849ac7ddfbfSEd Maste                     }
850ac7ddfbfSEd Maste                     break;
851ac7ddfbfSEd Maste                 default:
852ac7ddfbfSEd Maste                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
853ac7ddfbfSEd Maste                     break;
854ac7ddfbfSEd Maste             }
855ac7ddfbfSEd Maste             return error;
856ac7ddfbfSEd Maste         }
857ac7ddfbfSEd Maste 
858ac7ddfbfSEd Maste         void
8599f2f44ceSEd Maste         OptionParsingStarting () override
860ac7ddfbfSEd Maste         {
861ac7ddfbfSEd Maste             m_keep_stopped = eLazyBoolCalculate;
862ac7ddfbfSEd Maste         }
863ac7ddfbfSEd Maste 
864ac7ddfbfSEd Maste         const OptionDefinition*
8659f2f44ceSEd Maste         GetDefinitions () override
866ac7ddfbfSEd Maste         {
867ac7ddfbfSEd Maste             return g_option_table;
868ac7ddfbfSEd Maste         }
869ac7ddfbfSEd Maste 
870ac7ddfbfSEd Maste         // Options table: Required for subclasses of Options.
871ac7ddfbfSEd Maste 
872ac7ddfbfSEd Maste         static OptionDefinition g_option_table[];
873ac7ddfbfSEd Maste 
874ac7ddfbfSEd Maste         // Instance variables to hold the values for command options.
875ac7ddfbfSEd Maste         LazyBool m_keep_stopped;
876ac7ddfbfSEd Maste     };
877ac7ddfbfSEd Maste 
8784bb0738eSEd Maste     CommandObjectProcessDetach(CommandInterpreter &interpreter)
8794bb0738eSEd Maste         : CommandObjectParsed(interpreter, "process detach", "Detach from the current target process.",
880ac7ddfbfSEd Maste                               "process detach",
8814bb0738eSEd Maste                               eCommandRequiresProcess | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched),
882ac7ddfbfSEd Maste           m_options(interpreter)
883ac7ddfbfSEd Maste     {
884ac7ddfbfSEd Maste     }
885ac7ddfbfSEd Maste 
8864bb0738eSEd Maste     ~CommandObjectProcessDetach() override = default;
887ac7ddfbfSEd Maste 
888ac7ddfbfSEd Maste     Options *
8899f2f44ceSEd Maste     GetOptions () override
890ac7ddfbfSEd Maste     {
891ac7ddfbfSEd Maste         return &m_options;
892ac7ddfbfSEd Maste     }
893ac7ddfbfSEd Maste 
894ac7ddfbfSEd Maste protected:
895ac7ddfbfSEd Maste     bool
8969f2f44ceSEd Maste     DoExecute (Args& command, CommandReturnObject &result) override
897ac7ddfbfSEd Maste     {
898ac7ddfbfSEd Maste         Process *process = m_exe_ctx.GetProcessPtr();
899ac7ddfbfSEd Maste         // FIXME: This will be a Command Option:
900ac7ddfbfSEd Maste         bool keep_stopped;
901ac7ddfbfSEd Maste         if (m_options.m_keep_stopped == eLazyBoolCalculate)
902ac7ddfbfSEd Maste         {
903ac7ddfbfSEd Maste             // Check the process default:
9044bb0738eSEd Maste             keep_stopped = process->GetDetachKeepsStopped();
905ac7ddfbfSEd Maste         }
906ac7ddfbfSEd Maste         else if (m_options.m_keep_stopped == eLazyBoolYes)
907ac7ddfbfSEd Maste             keep_stopped = true;
908ac7ddfbfSEd Maste         else
909ac7ddfbfSEd Maste             keep_stopped = false;
910ac7ddfbfSEd Maste 
911ac7ddfbfSEd Maste         Error error (process->Detach(keep_stopped));
912ac7ddfbfSEd Maste         if (error.Success())
913ac7ddfbfSEd Maste         {
914ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusSuccessFinishResult);
915ac7ddfbfSEd Maste         }
916ac7ddfbfSEd Maste         else
917ac7ddfbfSEd Maste         {
918ac7ddfbfSEd Maste             result.AppendErrorWithFormat ("Detach failed: %s\n", error.AsCString());
919ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
920ac7ddfbfSEd Maste             return false;
921ac7ddfbfSEd Maste         }
922ac7ddfbfSEd Maste         return result.Succeeded();
923ac7ddfbfSEd Maste     }
924ac7ddfbfSEd Maste 
925ac7ddfbfSEd Maste     CommandOptions m_options;
926ac7ddfbfSEd Maste };
927ac7ddfbfSEd Maste 
928ac7ddfbfSEd Maste OptionDefinition
929ac7ddfbfSEd Maste CommandObjectProcessDetach::CommandOptions::g_option_table[] =
930ac7ddfbfSEd Maste {
9314bb0738eSEd Maste { LLDB_OPT_SET_1, false, "keep-stopped",   's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Whether or not the process should be kept stopped on detach (if possible)." },
9324bb0738eSEd Maste { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
933ac7ddfbfSEd Maste };
934ac7ddfbfSEd Maste 
935ac7ddfbfSEd Maste //-------------------------------------------------------------------------
936ac7ddfbfSEd Maste // CommandObjectProcessConnect
937ac7ddfbfSEd Maste //-------------------------------------------------------------------------
938ac7ddfbfSEd Maste #pragma mark CommandObjectProcessConnect
939ac7ddfbfSEd Maste 
940ac7ddfbfSEd Maste class CommandObjectProcessConnect : public CommandObjectParsed
941ac7ddfbfSEd Maste {
942ac7ddfbfSEd Maste public:
943ac7ddfbfSEd Maste     class CommandOptions : public Options
944ac7ddfbfSEd Maste     {
945ac7ddfbfSEd Maste     public:
946ac7ddfbfSEd Maste         CommandOptions (CommandInterpreter &interpreter) :
947ac7ddfbfSEd Maste             Options(interpreter)
948ac7ddfbfSEd Maste         {
949ac7ddfbfSEd Maste             // Keep default values of all options in one place: OptionParsingStarting ()
950ac7ddfbfSEd Maste             OptionParsingStarting ();
951ac7ddfbfSEd Maste         }
952ac7ddfbfSEd Maste 
9534bb0738eSEd Maste         ~CommandOptions() override = default;
954ac7ddfbfSEd Maste 
955ac7ddfbfSEd Maste         Error
9569f2f44ceSEd Maste         SetOptionValue (uint32_t option_idx, const char *option_arg) override
957ac7ddfbfSEd Maste         {
958ac7ddfbfSEd Maste             Error error;
959ac7ddfbfSEd Maste             const int short_option = m_getopt_table[option_idx].val;
960ac7ddfbfSEd Maste 
961ac7ddfbfSEd Maste             switch (short_option)
962ac7ddfbfSEd Maste             {
963ac7ddfbfSEd Maste             case 'p':
964ac7ddfbfSEd Maste                 plugin_name.assign (option_arg);
965ac7ddfbfSEd Maste                 break;
966ac7ddfbfSEd Maste 
967ac7ddfbfSEd Maste             default:
968ac7ddfbfSEd Maste                 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
969ac7ddfbfSEd Maste                 break;
970ac7ddfbfSEd Maste             }
971ac7ddfbfSEd Maste             return error;
972ac7ddfbfSEd Maste         }
973ac7ddfbfSEd Maste 
974ac7ddfbfSEd Maste         void
9759f2f44ceSEd Maste         OptionParsingStarting () override
976ac7ddfbfSEd Maste         {
977ac7ddfbfSEd Maste             plugin_name.clear();
978ac7ddfbfSEd Maste         }
979ac7ddfbfSEd Maste 
980ac7ddfbfSEd Maste         const OptionDefinition*
9819f2f44ceSEd Maste         GetDefinitions () override
982ac7ddfbfSEd Maste         {
983ac7ddfbfSEd Maste             return g_option_table;
984ac7ddfbfSEd Maste         }
985ac7ddfbfSEd Maste 
986ac7ddfbfSEd Maste         // Options table: Required for subclasses of Options.
987ac7ddfbfSEd Maste 
988ac7ddfbfSEd Maste         static OptionDefinition g_option_table[];
989ac7ddfbfSEd Maste 
990ac7ddfbfSEd Maste         // Instance variables to hold the values for command options.
991ac7ddfbfSEd Maste 
992ac7ddfbfSEd Maste         std::string plugin_name;
993ac7ddfbfSEd Maste     };
994ac7ddfbfSEd Maste 
995ac7ddfbfSEd Maste     CommandObjectProcessConnect (CommandInterpreter &interpreter) :
996ac7ddfbfSEd Maste         CommandObjectParsed (interpreter,
997ac7ddfbfSEd Maste                              "process connect",
998ac7ddfbfSEd Maste                              "Connect to a remote debug service.",
999ac7ddfbfSEd Maste                              "process connect <remote-url>",
1000ac7ddfbfSEd Maste                              0),
1001ac7ddfbfSEd Maste         m_options (interpreter)
1002ac7ddfbfSEd Maste     {
1003ac7ddfbfSEd Maste     }
1004ac7ddfbfSEd Maste 
10054bb0738eSEd Maste     ~CommandObjectProcessConnect() override = default;
1006ac7ddfbfSEd Maste 
1007ac7ddfbfSEd Maste     Options *
10089f2f44ceSEd Maste     GetOptions () override
1009ac7ddfbfSEd Maste     {
1010ac7ddfbfSEd Maste         return &m_options;
1011ac7ddfbfSEd Maste     }
1012ac7ddfbfSEd Maste 
1013ac7ddfbfSEd Maste protected:
1014ac7ddfbfSEd Maste     bool
10159f2f44ceSEd Maste     DoExecute (Args& command, CommandReturnObject &result) override
1016ac7ddfbfSEd Maste     {
10179f2f44ceSEd Maste         if (command.GetArgumentCount() != 1)
10189f2f44ceSEd Maste         {
10199f2f44ceSEd Maste             result.AppendErrorWithFormat ("'%s' takes exactly one argument:\nUsage: %s\n",
10209f2f44ceSEd Maste                                           m_cmd_name.c_str(),
10219f2f44ceSEd Maste                                           m_cmd_syntax.c_str());
10229f2f44ceSEd Maste             result.SetStatus (eReturnStatusFailed);
10239f2f44ceSEd Maste             return false;
10249f2f44ceSEd Maste         }
1025ac7ddfbfSEd Maste 
1026ac7ddfbfSEd Maste         Process *process = m_exe_ctx.GetProcessPtr();
10279f2f44ceSEd Maste         if (process && process->IsAlive())
1028ac7ddfbfSEd Maste         {
1029ac7ddfbfSEd Maste             result.AppendErrorWithFormat ("Process %" PRIu64 " is currently being debugged, kill the process before connecting.\n",
1030ac7ddfbfSEd Maste                                           process->GetID());
1031ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
1032ac7ddfbfSEd Maste             return false;
1033ac7ddfbfSEd Maste         }
1034ac7ddfbfSEd Maste 
10359f2f44ceSEd Maste         const char *plugin_name = nullptr;
1036ac7ddfbfSEd Maste         if (!m_options.plugin_name.empty())
1037ac7ddfbfSEd Maste             plugin_name = m_options.plugin_name.c_str();
1038ac7ddfbfSEd Maste 
10399f2f44ceSEd Maste         Error error;
10409f2f44ceSEd Maste         Debugger& debugger = m_interpreter.GetDebugger();
10419f2f44ceSEd Maste         PlatformSP platform_sp = m_interpreter.GetPlatform(true);
10429f2f44ceSEd Maste         ProcessSP process_sp = platform_sp->ConnectProcess(command.GetArgumentAtIndex(0),
10439f2f44ceSEd Maste                                                            plugin_name,
10449f2f44ceSEd Maste                                                            debugger,
10459f2f44ceSEd Maste                                                            debugger.GetSelectedTarget().get(),
10469f2f44ceSEd Maste                                                            error);
10479f2f44ceSEd Maste         if (error.Fail() || process_sp == nullptr)
1048ac7ddfbfSEd Maste         {
10499f2f44ceSEd Maste             result.AppendError(error.AsCString("Error connecting to the process"));
1050ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
1051ac7ddfbfSEd Maste             return false;
1052ac7ddfbfSEd Maste         }
10539f2f44ceSEd Maste         return true;
1054ac7ddfbfSEd Maste     }
1055ac7ddfbfSEd Maste 
1056ac7ddfbfSEd Maste     CommandOptions m_options;
1057ac7ddfbfSEd Maste };
1058ac7ddfbfSEd Maste 
1059ac7ddfbfSEd Maste OptionDefinition
1060ac7ddfbfSEd Maste CommandObjectProcessConnect::CommandOptions::g_option_table[] =
1061ac7ddfbfSEd Maste {
10624bb0738eSEd Maste     { LLDB_OPT_SET_ALL, false, "plugin", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePlugin, "Name of the process plugin you want to use."},
10634bb0738eSEd Maste     { 0,                false, nullptr,      0 , 0,                 nullptr, nullptr, 0, eArgTypeNone,   nullptr }
1064ac7ddfbfSEd Maste };
1065ac7ddfbfSEd Maste 
1066ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1067ac7ddfbfSEd Maste // CommandObjectProcessPlugin
1068ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1069ac7ddfbfSEd Maste #pragma mark CommandObjectProcessPlugin
1070ac7ddfbfSEd Maste 
1071ac7ddfbfSEd Maste class CommandObjectProcessPlugin : public CommandObjectProxy
1072ac7ddfbfSEd Maste {
1073ac7ddfbfSEd Maste public:
10744bb0738eSEd Maste     CommandObjectProcessPlugin(CommandInterpreter &interpreter)
10754bb0738eSEd Maste         : CommandObjectProxy(interpreter, "process plugin",
10764bb0738eSEd Maste                              "Send a custom command to the current target process plug-in.", "process plugin <args>", 0)
1077ac7ddfbfSEd Maste     {
1078ac7ddfbfSEd Maste     }
1079ac7ddfbfSEd Maste 
10804bb0738eSEd Maste     ~CommandObjectProcessPlugin() override = default;
1081ac7ddfbfSEd Maste 
10829f2f44ceSEd Maste     CommandObject *
10839f2f44ceSEd Maste     GetProxyCommandObject() override
1084ac7ddfbfSEd Maste     {
1085ac7ddfbfSEd Maste         Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
1086ac7ddfbfSEd Maste         if (process)
1087ac7ddfbfSEd Maste             return process->GetPluginCommandObject();
10884bb0738eSEd Maste         return nullptr;
1089ac7ddfbfSEd Maste     }
1090ac7ddfbfSEd Maste };
1091ac7ddfbfSEd Maste 
1092ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1093ac7ddfbfSEd Maste // CommandObjectProcessLoad
1094ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1095ac7ddfbfSEd Maste #pragma mark CommandObjectProcessLoad
1096ac7ddfbfSEd Maste 
1097ac7ddfbfSEd Maste class CommandObjectProcessLoad : public CommandObjectParsed
1098ac7ddfbfSEd Maste {
1099ac7ddfbfSEd Maste public:
11009f2f44ceSEd Maste     class CommandOptions : public Options
11019f2f44ceSEd Maste     {
11029f2f44ceSEd Maste     public:
11039f2f44ceSEd Maste         CommandOptions (CommandInterpreter &interpreter) :
11049f2f44ceSEd Maste             Options(interpreter)
11059f2f44ceSEd Maste         {
11069f2f44ceSEd Maste             // Keep default values of all options in one place: OptionParsingStarting ()
11079f2f44ceSEd Maste             OptionParsingStarting ();
11089f2f44ceSEd Maste         }
11099f2f44ceSEd Maste 
11109f2f44ceSEd Maste         ~CommandOptions() override = default;
11119f2f44ceSEd Maste 
11129f2f44ceSEd Maste         Error
11139f2f44ceSEd Maste         SetOptionValue (uint32_t option_idx, const char *option_arg) override
11149f2f44ceSEd Maste         {
11159f2f44ceSEd Maste             Error error;
11169f2f44ceSEd Maste             const int short_option = m_getopt_table[option_idx].val;
11179f2f44ceSEd Maste             switch (short_option)
11189f2f44ceSEd Maste             {
11199f2f44ceSEd Maste             case 'i':
11209f2f44ceSEd Maste                 do_install = true;
11219f2f44ceSEd Maste                 if (option_arg && option_arg[0])
11229f2f44ceSEd Maste                     install_path.SetFile(option_arg, false);
11239f2f44ceSEd Maste                 break;
11249f2f44ceSEd Maste             default:
11259f2f44ceSEd Maste                 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
11269f2f44ceSEd Maste                 break;
11279f2f44ceSEd Maste             }
11289f2f44ceSEd Maste             return error;
11299f2f44ceSEd Maste         }
11309f2f44ceSEd Maste 
11319f2f44ceSEd Maste         void
11329f2f44ceSEd Maste         OptionParsingStarting () override
11339f2f44ceSEd Maste         {
11349f2f44ceSEd Maste             do_install = false;
11359f2f44ceSEd Maste             install_path.Clear();
11369f2f44ceSEd Maste         }
11379f2f44ceSEd Maste 
11389f2f44ceSEd Maste         const OptionDefinition*
11399f2f44ceSEd Maste         GetDefinitions () override
11409f2f44ceSEd Maste         {
11419f2f44ceSEd Maste             return g_option_table;
11429f2f44ceSEd Maste         }
11439f2f44ceSEd Maste 
11449f2f44ceSEd Maste         // Options table: Required for subclasses of Options.
11459f2f44ceSEd Maste         static OptionDefinition g_option_table[];
11469f2f44ceSEd Maste 
11479f2f44ceSEd Maste         // Instance variables to hold the values for command options.
11489f2f44ceSEd Maste         bool do_install;
11499f2f44ceSEd Maste         FileSpec install_path;
11509f2f44ceSEd Maste     };
1151ac7ddfbfSEd Maste 
1152ac7ddfbfSEd Maste     CommandObjectProcessLoad (CommandInterpreter &interpreter) :
1153ac7ddfbfSEd Maste         CommandObjectParsed (interpreter,
1154ac7ddfbfSEd Maste                              "process load",
1155ac7ddfbfSEd Maste                              "Load a shared library into the current process.",
1156ac7ddfbfSEd Maste                              "process load <filename> [<filename> ...]",
11571c3bbb01SEd Maste                              eCommandRequiresProcess       |
11581c3bbb01SEd Maste                              eCommandTryTargetAPILock      |
11591c3bbb01SEd Maste                              eCommandProcessMustBeLaunched |
11609f2f44ceSEd Maste                              eCommandProcessMustBePaused   ),
11619f2f44ceSEd Maste         m_options (interpreter)
1162ac7ddfbfSEd Maste     {
1163ac7ddfbfSEd Maste     }
1164ac7ddfbfSEd Maste 
11659f2f44ceSEd Maste     ~CommandObjectProcessLoad() override = default;
11669f2f44ceSEd Maste 
11679f2f44ceSEd Maste     Options *
11689f2f44ceSEd Maste     GetOptions () override
1169ac7ddfbfSEd Maste     {
11709f2f44ceSEd Maste         return &m_options;
1171ac7ddfbfSEd Maste     }
1172ac7ddfbfSEd Maste 
1173ac7ddfbfSEd Maste protected:
1174ac7ddfbfSEd Maste     bool
11759f2f44ceSEd Maste     DoExecute (Args& command, CommandReturnObject &result) override
1176ac7ddfbfSEd Maste     {
1177ac7ddfbfSEd Maste         Process *process = m_exe_ctx.GetProcessPtr();
1178ac7ddfbfSEd Maste 
1179ac7ddfbfSEd Maste         const size_t argc = command.GetArgumentCount();
1180ac7ddfbfSEd Maste         for (uint32_t i = 0; i < argc; ++i)
1181ac7ddfbfSEd Maste         {
1182ac7ddfbfSEd Maste             Error error;
11839f2f44ceSEd Maste             PlatformSP platform = process->GetTarget().GetPlatform();
1184ac7ddfbfSEd Maste             const char *image_path = command.GetArgumentAtIndex(i);
11859f2f44ceSEd Maste             uint32_t image_token = LLDB_INVALID_IMAGE_TOKEN;
11869f2f44ceSEd Maste 
11879f2f44ceSEd Maste             if (!m_options.do_install)
11889f2f44ceSEd Maste             {
1189ac7ddfbfSEd Maste                 FileSpec image_spec (image_path, false);
11909f2f44ceSEd Maste                 platform->ResolveRemotePath(image_spec, image_spec);
11919f2f44ceSEd Maste                 image_token = platform->LoadImage(process, FileSpec(), image_spec, error);
11929f2f44ceSEd Maste             }
11939f2f44ceSEd Maste             else if (m_options.install_path)
11949f2f44ceSEd Maste             {
11959f2f44ceSEd Maste                 FileSpec image_spec (image_path, true);
11969f2f44ceSEd Maste                 platform->ResolveRemotePath(m_options.install_path, m_options.install_path);
11979f2f44ceSEd Maste                 image_token = platform->LoadImage(process, image_spec, m_options.install_path, error);
11989f2f44ceSEd Maste             }
11999f2f44ceSEd Maste             else
12009f2f44ceSEd Maste             {
12019f2f44ceSEd Maste                 FileSpec image_spec (image_path, true);
12029f2f44ceSEd Maste                 image_token = platform->LoadImage(process, image_spec, FileSpec(), error);
12039f2f44ceSEd Maste             }
12049f2f44ceSEd Maste 
1205ac7ddfbfSEd Maste             if (image_token != LLDB_INVALID_IMAGE_TOKEN)
1206ac7ddfbfSEd Maste             {
1207ac7ddfbfSEd Maste                 result.AppendMessageWithFormat ("Loading \"%s\"...ok\nImage %u loaded.\n", image_path, image_token);
1208ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusSuccessFinishResult);
1209ac7ddfbfSEd Maste             }
1210ac7ddfbfSEd Maste             else
1211ac7ddfbfSEd Maste             {
1212ac7ddfbfSEd Maste                 result.AppendErrorWithFormat ("failed to load '%s': %s", image_path, error.AsCString());
1213ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusFailed);
1214ac7ddfbfSEd Maste             }
1215ac7ddfbfSEd Maste         }
1216ac7ddfbfSEd Maste         return result.Succeeded();
1217ac7ddfbfSEd Maste     }
12189f2f44ceSEd Maste 
12199f2f44ceSEd Maste     CommandOptions m_options;
1220ac7ddfbfSEd Maste };
1221ac7ddfbfSEd Maste 
12229f2f44ceSEd Maste OptionDefinition
12239f2f44ceSEd Maste CommandObjectProcessLoad::CommandOptions::g_option_table[] =
12249f2f44ceSEd Maste {
12259f2f44ceSEd 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."},
12269f2f44ceSEd Maste     { 0,                false, nullptr,    0 , 0,                               nullptr, nullptr, 0, eArgTypeNone, nullptr }
12279f2f44ceSEd Maste };
1228ac7ddfbfSEd Maste 
1229ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1230ac7ddfbfSEd Maste // CommandObjectProcessUnload
1231ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1232ac7ddfbfSEd Maste #pragma mark CommandObjectProcessUnload
1233ac7ddfbfSEd Maste 
1234ac7ddfbfSEd Maste class CommandObjectProcessUnload : public CommandObjectParsed
1235ac7ddfbfSEd Maste {
1236ac7ddfbfSEd Maste public:
1237ac7ddfbfSEd Maste 
1238ac7ddfbfSEd Maste     CommandObjectProcessUnload (CommandInterpreter &interpreter) :
1239ac7ddfbfSEd Maste         CommandObjectParsed (interpreter,
1240ac7ddfbfSEd Maste                              "process unload",
1241ac7ddfbfSEd Maste                              "Unload a shared library from the current process using the index returned by a previous call to \"process load\".",
1242ac7ddfbfSEd Maste                              "process unload <index>",
12431c3bbb01SEd Maste                              eCommandRequiresProcess       |
12441c3bbb01SEd Maste                              eCommandTryTargetAPILock      |
12451c3bbb01SEd Maste                              eCommandProcessMustBeLaunched |
12461c3bbb01SEd Maste                              eCommandProcessMustBePaused   )
1247ac7ddfbfSEd Maste     {
1248ac7ddfbfSEd Maste     }
1249ac7ddfbfSEd Maste 
12504bb0738eSEd Maste     ~CommandObjectProcessUnload() override = default;
1251ac7ddfbfSEd Maste 
1252ac7ddfbfSEd Maste protected:
1253ac7ddfbfSEd Maste     bool
12549f2f44ceSEd Maste     DoExecute (Args& command, CommandReturnObject &result) override
1255ac7ddfbfSEd Maste     {
1256ac7ddfbfSEd Maste         Process *process = m_exe_ctx.GetProcessPtr();
1257ac7ddfbfSEd Maste 
1258ac7ddfbfSEd Maste         const size_t argc = command.GetArgumentCount();
1259ac7ddfbfSEd Maste 
1260ac7ddfbfSEd Maste         for (uint32_t i = 0; i < argc; ++i)
1261ac7ddfbfSEd Maste         {
1262ac7ddfbfSEd Maste             const char *image_token_cstr = command.GetArgumentAtIndex(i);
12631c3bbb01SEd Maste             uint32_t image_token = StringConvert::ToUInt32(image_token_cstr, LLDB_INVALID_IMAGE_TOKEN, 0);
1264ac7ddfbfSEd Maste             if (image_token == LLDB_INVALID_IMAGE_TOKEN)
1265ac7ddfbfSEd Maste             {
1266ac7ddfbfSEd Maste                 result.AppendErrorWithFormat ("invalid image index argument '%s'", image_token_cstr);
1267ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusFailed);
1268ac7ddfbfSEd Maste                 break;
1269ac7ddfbfSEd Maste             }
1270ac7ddfbfSEd Maste             else
1271ac7ddfbfSEd Maste             {
12729f2f44ceSEd Maste                 Error error (process->GetTarget().GetPlatform()->UnloadImage(process, image_token));
1273ac7ddfbfSEd Maste                 if (error.Success())
1274ac7ddfbfSEd Maste                 {
1275ac7ddfbfSEd Maste                     result.AppendMessageWithFormat ("Unloading shared library with index %u...ok\n", image_token);
1276ac7ddfbfSEd Maste                     result.SetStatus (eReturnStatusSuccessFinishResult);
1277ac7ddfbfSEd Maste                 }
1278ac7ddfbfSEd Maste                 else
1279ac7ddfbfSEd Maste                 {
1280ac7ddfbfSEd Maste                     result.AppendErrorWithFormat ("failed to unload image: %s", error.AsCString());
1281ac7ddfbfSEd Maste                     result.SetStatus (eReturnStatusFailed);
1282ac7ddfbfSEd Maste                     break;
1283ac7ddfbfSEd Maste                 }
1284ac7ddfbfSEd Maste             }
1285ac7ddfbfSEd Maste         }
1286ac7ddfbfSEd Maste         return result.Succeeded();
1287ac7ddfbfSEd Maste     }
1288ac7ddfbfSEd Maste };
1289ac7ddfbfSEd Maste 
1290ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1291ac7ddfbfSEd Maste // CommandObjectProcessSignal
1292ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1293ac7ddfbfSEd Maste #pragma mark CommandObjectProcessSignal
1294ac7ddfbfSEd Maste 
1295ac7ddfbfSEd Maste class CommandObjectProcessSignal : public CommandObjectParsed
1296ac7ddfbfSEd Maste {
1297ac7ddfbfSEd Maste public:
12984bb0738eSEd Maste     CommandObjectProcessSignal(CommandInterpreter &interpreter)
12994bb0738eSEd Maste         : CommandObjectParsed(interpreter, "process signal", "Send a UNIX signal to the current target process.",
13004bb0738eSEd Maste                               nullptr, eCommandRequiresProcess | eCommandTryTargetAPILock)
1301ac7ddfbfSEd Maste     {
1302ac7ddfbfSEd Maste         CommandArgumentEntry arg;
1303ac7ddfbfSEd Maste         CommandArgumentData signal_arg;
1304ac7ddfbfSEd Maste 
1305ac7ddfbfSEd Maste         // Define the first (and only) variant of this arg.
1306ac7ddfbfSEd Maste         signal_arg.arg_type = eArgTypeUnixSignal;
1307ac7ddfbfSEd Maste         signal_arg.arg_repetition = eArgRepeatPlain;
1308ac7ddfbfSEd Maste 
1309ac7ddfbfSEd Maste         // There is only one variant this argument could be; put it into the argument entry.
1310ac7ddfbfSEd Maste         arg.push_back (signal_arg);
1311ac7ddfbfSEd Maste 
1312ac7ddfbfSEd Maste         // Push the data for the first argument into the m_arguments vector.
1313ac7ddfbfSEd Maste         m_arguments.push_back (arg);
1314ac7ddfbfSEd Maste     }
1315ac7ddfbfSEd Maste 
13164bb0738eSEd Maste     ~CommandObjectProcessSignal() override = default;
1317ac7ddfbfSEd Maste 
1318ac7ddfbfSEd Maste protected:
1319ac7ddfbfSEd Maste     bool
13209f2f44ceSEd Maste     DoExecute (Args& command, CommandReturnObject &result) override
1321ac7ddfbfSEd Maste     {
1322ac7ddfbfSEd Maste         Process *process = m_exe_ctx.GetProcessPtr();
1323ac7ddfbfSEd Maste 
1324ac7ddfbfSEd Maste         if (command.GetArgumentCount() == 1)
1325ac7ddfbfSEd Maste         {
1326ac7ddfbfSEd Maste             int signo = LLDB_INVALID_SIGNAL_NUMBER;
1327ac7ddfbfSEd Maste 
1328ac7ddfbfSEd Maste             const char *signal_name = command.GetArgumentAtIndex(0);
1329ac7ddfbfSEd Maste             if (::isxdigit (signal_name[0]))
13301c3bbb01SEd Maste                 signo = StringConvert::ToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0);
1331ac7ddfbfSEd Maste             else
1332b91a7dfcSDimitry Andric                 signo = process->GetUnixSignals()->GetSignalNumberFromName(signal_name);
1333ac7ddfbfSEd Maste 
1334ac7ddfbfSEd Maste             if (signo == LLDB_INVALID_SIGNAL_NUMBER)
1335ac7ddfbfSEd Maste             {
1336ac7ddfbfSEd Maste                 result.AppendErrorWithFormat ("Invalid signal argument '%s'.\n", command.GetArgumentAtIndex(0));
1337ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusFailed);
1338ac7ddfbfSEd Maste             }
1339ac7ddfbfSEd Maste             else
1340ac7ddfbfSEd Maste             {
1341ac7ddfbfSEd Maste                 Error error (process->Signal (signo));
1342ac7ddfbfSEd Maste                 if (error.Success())
1343ac7ddfbfSEd Maste                 {
1344ac7ddfbfSEd Maste                     result.SetStatus (eReturnStatusSuccessFinishResult);
1345ac7ddfbfSEd Maste                 }
1346ac7ddfbfSEd Maste                 else
1347ac7ddfbfSEd Maste                 {
1348ac7ddfbfSEd Maste                     result.AppendErrorWithFormat ("Failed to send signal %i: %s\n", signo, error.AsCString());
1349ac7ddfbfSEd Maste                     result.SetStatus (eReturnStatusFailed);
1350ac7ddfbfSEd Maste                 }
1351ac7ddfbfSEd Maste             }
1352ac7ddfbfSEd Maste         }
1353ac7ddfbfSEd Maste         else
1354ac7ddfbfSEd Maste         {
1355ac7ddfbfSEd Maste             result.AppendErrorWithFormat("'%s' takes exactly one signal number argument:\nUsage: %s\n", m_cmd_name.c_str(),
1356ac7ddfbfSEd Maste                                         m_cmd_syntax.c_str());
1357ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
1358ac7ddfbfSEd Maste         }
1359ac7ddfbfSEd Maste         return result.Succeeded();
1360ac7ddfbfSEd Maste     }
1361ac7ddfbfSEd Maste };
1362ac7ddfbfSEd Maste 
1363ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1364ac7ddfbfSEd Maste // CommandObjectProcessInterrupt
1365ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1366ac7ddfbfSEd Maste #pragma mark CommandObjectProcessInterrupt
1367ac7ddfbfSEd Maste 
1368ac7ddfbfSEd Maste class CommandObjectProcessInterrupt : public CommandObjectParsed
1369ac7ddfbfSEd Maste {
1370ac7ddfbfSEd Maste public:
13714bb0738eSEd Maste     CommandObjectProcessInterrupt(CommandInterpreter &interpreter)
13724bb0738eSEd Maste         : CommandObjectParsed(interpreter, "process interrupt", "Interrupt the current target process.",
1373ac7ddfbfSEd Maste                               "process interrupt",
13744bb0738eSEd Maste                               eCommandRequiresProcess | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched)
1375ac7ddfbfSEd Maste     {
1376ac7ddfbfSEd Maste     }
1377ac7ddfbfSEd Maste 
13784bb0738eSEd Maste     ~CommandObjectProcessInterrupt() override = default;
1379ac7ddfbfSEd Maste 
1380ac7ddfbfSEd Maste protected:
1381ac7ddfbfSEd Maste     bool
13829f2f44ceSEd Maste     DoExecute (Args& command, CommandReturnObject &result) override
1383ac7ddfbfSEd Maste     {
1384ac7ddfbfSEd Maste         Process *process = m_exe_ctx.GetProcessPtr();
13854bb0738eSEd Maste         if (process == nullptr)
1386ac7ddfbfSEd Maste         {
1387ac7ddfbfSEd Maste             result.AppendError ("no process to halt");
1388ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
1389ac7ddfbfSEd Maste             return false;
1390ac7ddfbfSEd Maste         }
1391ac7ddfbfSEd Maste 
1392ac7ddfbfSEd Maste         if (command.GetArgumentCount() == 0)
1393ac7ddfbfSEd Maste         {
1394ac7ddfbfSEd Maste             bool clear_thread_plans = true;
1395ac7ddfbfSEd Maste             Error error(process->Halt (clear_thread_plans));
1396ac7ddfbfSEd Maste             if (error.Success())
1397ac7ddfbfSEd Maste             {
1398ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusSuccessFinishResult);
1399ac7ddfbfSEd Maste             }
1400ac7ddfbfSEd Maste             else
1401ac7ddfbfSEd Maste             {
1402ac7ddfbfSEd Maste                 result.AppendErrorWithFormat ("Failed to halt process: %s\n", error.AsCString());
1403ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusFailed);
1404ac7ddfbfSEd Maste             }
1405ac7ddfbfSEd Maste         }
1406ac7ddfbfSEd Maste         else
1407ac7ddfbfSEd Maste         {
1408ac7ddfbfSEd Maste             result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n",
1409ac7ddfbfSEd Maste                                         m_cmd_name.c_str(),
1410ac7ddfbfSEd Maste                                         m_cmd_syntax.c_str());
1411ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
1412ac7ddfbfSEd Maste         }
1413ac7ddfbfSEd Maste         return result.Succeeded();
1414ac7ddfbfSEd Maste     }
1415ac7ddfbfSEd Maste };
1416ac7ddfbfSEd Maste 
1417ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1418ac7ddfbfSEd Maste // CommandObjectProcessKill
1419ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1420ac7ddfbfSEd Maste #pragma mark CommandObjectProcessKill
1421ac7ddfbfSEd Maste 
1422ac7ddfbfSEd Maste class CommandObjectProcessKill : public CommandObjectParsed
1423ac7ddfbfSEd Maste {
1424ac7ddfbfSEd Maste public:
14254bb0738eSEd Maste     CommandObjectProcessKill(CommandInterpreter &interpreter)
14264bb0738eSEd Maste         : CommandObjectParsed(interpreter, "process kill", "Terminate the current target process.", "process kill",
14274bb0738eSEd Maste                               eCommandRequiresProcess | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched)
1428ac7ddfbfSEd Maste     {
1429ac7ddfbfSEd Maste     }
1430ac7ddfbfSEd Maste 
14314bb0738eSEd Maste     ~CommandObjectProcessKill() override = default;
1432ac7ddfbfSEd Maste 
1433ac7ddfbfSEd Maste protected:
1434ac7ddfbfSEd Maste     bool
14359f2f44ceSEd Maste     DoExecute (Args& command, CommandReturnObject &result) override
1436ac7ddfbfSEd Maste     {
1437ac7ddfbfSEd Maste         Process *process = m_exe_ctx.GetProcessPtr();
14384bb0738eSEd Maste         if (process == nullptr)
1439ac7ddfbfSEd Maste         {
1440ac7ddfbfSEd Maste             result.AppendError ("no process to kill");
1441ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
1442ac7ddfbfSEd Maste             return false;
1443ac7ddfbfSEd Maste         }
1444ac7ddfbfSEd Maste 
1445ac7ddfbfSEd Maste         if (command.GetArgumentCount() == 0)
1446ac7ddfbfSEd Maste         {
14471c3bbb01SEd Maste             Error error (process->Destroy(true));
1448ac7ddfbfSEd Maste             if (error.Success())
1449ac7ddfbfSEd Maste             {
1450ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusSuccessFinishResult);
1451ac7ddfbfSEd Maste             }
1452ac7ddfbfSEd Maste             else
1453ac7ddfbfSEd Maste             {
1454ac7ddfbfSEd Maste                 result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString());
1455ac7ddfbfSEd Maste                 result.SetStatus (eReturnStatusFailed);
1456ac7ddfbfSEd Maste             }
1457ac7ddfbfSEd Maste         }
1458ac7ddfbfSEd Maste         else
1459ac7ddfbfSEd Maste         {
1460ac7ddfbfSEd Maste             result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n",
1461ac7ddfbfSEd Maste                                         m_cmd_name.c_str(),
1462ac7ddfbfSEd Maste                                         m_cmd_syntax.c_str());
1463ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
1464ac7ddfbfSEd Maste         }
1465ac7ddfbfSEd Maste         return result.Succeeded();
1466ac7ddfbfSEd Maste     }
1467ac7ddfbfSEd Maste };
1468ac7ddfbfSEd Maste 
1469ac7ddfbfSEd Maste //-------------------------------------------------------------------------
14700127ef0fSEd Maste // CommandObjectProcessSaveCore
14710127ef0fSEd Maste //-------------------------------------------------------------------------
14720127ef0fSEd Maste #pragma mark CommandObjectProcessSaveCore
14730127ef0fSEd Maste 
14740127ef0fSEd Maste class CommandObjectProcessSaveCore : public CommandObjectParsed
14750127ef0fSEd Maste {
14760127ef0fSEd Maste public:
14770127ef0fSEd Maste     CommandObjectProcessSaveCore (CommandInterpreter &interpreter) :
14780127ef0fSEd Maste     CommandObjectParsed (interpreter,
14790127ef0fSEd Maste                          "process save-core",
14800127ef0fSEd Maste                          "Save the current process as a core file using an appropriate file type.",
14810127ef0fSEd Maste                          "process save-core FILE",
14821c3bbb01SEd Maste                          eCommandRequiresProcess      |
14831c3bbb01SEd Maste                          eCommandTryTargetAPILock     |
14841c3bbb01SEd Maste                          eCommandProcessMustBeLaunched)
14850127ef0fSEd Maste     {
14860127ef0fSEd Maste     }
14870127ef0fSEd Maste 
14884bb0738eSEd Maste     ~CommandObjectProcessSaveCore() override = default;
14890127ef0fSEd Maste 
14900127ef0fSEd Maste protected:
14910127ef0fSEd Maste     bool
14920127ef0fSEd Maste     DoExecute (Args& command,
14939f2f44ceSEd Maste                CommandReturnObject &result) override
14940127ef0fSEd Maste     {
14950127ef0fSEd Maste         ProcessSP process_sp = m_exe_ctx.GetProcessSP();
14960127ef0fSEd Maste         if (process_sp)
14970127ef0fSEd Maste         {
14980127ef0fSEd Maste             if (command.GetArgumentCount() == 1)
14990127ef0fSEd Maste             {
15000127ef0fSEd Maste                 FileSpec output_file(command.GetArgumentAtIndex(0), false);
15010127ef0fSEd Maste                 Error error = PluginManager::SaveCore(process_sp, output_file);
15020127ef0fSEd Maste                 if (error.Success())
15030127ef0fSEd Maste                 {
15040127ef0fSEd Maste                     result.SetStatus (eReturnStatusSuccessFinishResult);
15050127ef0fSEd Maste                 }
15060127ef0fSEd Maste                 else
15070127ef0fSEd Maste                 {
15080127ef0fSEd Maste                     result.AppendErrorWithFormat ("Failed to save core file for process: %s\n", error.AsCString());
15090127ef0fSEd Maste                     result.SetStatus (eReturnStatusFailed);
15100127ef0fSEd Maste                 }
15110127ef0fSEd Maste             }
15120127ef0fSEd Maste             else
15130127ef0fSEd Maste             {
15140127ef0fSEd Maste                 result.AppendErrorWithFormat ("'%s' takes one arguments:\nUsage: %s\n",
15150127ef0fSEd Maste                                               m_cmd_name.c_str(),
15160127ef0fSEd Maste                                               m_cmd_syntax.c_str());
15170127ef0fSEd Maste                 result.SetStatus (eReturnStatusFailed);
15180127ef0fSEd Maste             }
15190127ef0fSEd Maste         }
15200127ef0fSEd Maste         else
15210127ef0fSEd Maste         {
15220127ef0fSEd Maste             result.AppendError ("invalid process");
15230127ef0fSEd Maste             result.SetStatus (eReturnStatusFailed);
15240127ef0fSEd Maste             return false;
15250127ef0fSEd Maste         }
15260127ef0fSEd Maste 
15270127ef0fSEd Maste         return result.Succeeded();
15280127ef0fSEd Maste     }
15290127ef0fSEd Maste };
15300127ef0fSEd Maste 
15310127ef0fSEd Maste //-------------------------------------------------------------------------
1532ac7ddfbfSEd Maste // CommandObjectProcessStatus
1533ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1534ac7ddfbfSEd Maste #pragma mark CommandObjectProcessStatus
1535ac7ddfbfSEd Maste 
1536ac7ddfbfSEd Maste class CommandObjectProcessStatus : public CommandObjectParsed
1537ac7ddfbfSEd Maste {
1538ac7ddfbfSEd Maste public:
15394bb0738eSEd Maste     CommandObjectProcessStatus(CommandInterpreter &interpreter)
15404bb0738eSEd Maste         : CommandObjectParsed(interpreter, "process status",
15414bb0738eSEd Maste                               "Show status and stop location for the current target process.", "process status",
15421c3bbb01SEd Maste                               eCommandRequiresProcess | eCommandTryTargetAPILock)
1543ac7ddfbfSEd Maste     {
1544ac7ddfbfSEd Maste     }
1545ac7ddfbfSEd Maste 
15464bb0738eSEd Maste     ~CommandObjectProcessStatus() override = default;
1547ac7ddfbfSEd Maste 
1548ac7ddfbfSEd Maste     bool
15499f2f44ceSEd Maste     DoExecute (Args& command, CommandReturnObject &result) override
1550ac7ddfbfSEd Maste     {
1551ac7ddfbfSEd Maste         Stream &strm = result.GetOutputStream();
1552ac7ddfbfSEd Maste         result.SetStatus (eReturnStatusSuccessFinishNoResult);
15531c3bbb01SEd Maste         // No need to check "process" for validity as eCommandRequiresProcess ensures it is valid
1554ac7ddfbfSEd Maste         Process *process = m_exe_ctx.GetProcessPtr();
1555ac7ddfbfSEd Maste         const bool only_threads_with_stop_reason = true;
1556ac7ddfbfSEd Maste         const uint32_t start_frame = 0;
1557ac7ddfbfSEd Maste         const uint32_t num_frames = 1;
1558ac7ddfbfSEd Maste         const uint32_t num_frames_with_source = 1;
1559ac7ddfbfSEd Maste         process->GetStatus(strm);
1560ac7ddfbfSEd Maste         process->GetThreadStatus (strm,
1561ac7ddfbfSEd Maste                                   only_threads_with_stop_reason,
1562ac7ddfbfSEd Maste                                   start_frame,
1563ac7ddfbfSEd Maste                                   num_frames,
1564ac7ddfbfSEd Maste                                   num_frames_with_source);
1565ac7ddfbfSEd Maste         return result.Succeeded();
1566ac7ddfbfSEd Maste     }
1567ac7ddfbfSEd Maste };
1568ac7ddfbfSEd Maste 
1569ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1570ac7ddfbfSEd Maste // CommandObjectProcessHandle
1571ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1572ac7ddfbfSEd Maste #pragma mark CommandObjectProcessHandle
1573ac7ddfbfSEd Maste 
1574ac7ddfbfSEd Maste class CommandObjectProcessHandle : public CommandObjectParsed
1575ac7ddfbfSEd Maste {
1576ac7ddfbfSEd Maste public:
1577ac7ddfbfSEd Maste     class CommandOptions : public Options
1578ac7ddfbfSEd Maste     {
1579ac7ddfbfSEd Maste     public:
1580ac7ddfbfSEd Maste         CommandOptions (CommandInterpreter &interpreter) :
1581ac7ddfbfSEd Maste             Options (interpreter)
1582ac7ddfbfSEd Maste         {
1583ac7ddfbfSEd Maste             OptionParsingStarting ();
1584ac7ddfbfSEd Maste         }
1585ac7ddfbfSEd Maste 
15864bb0738eSEd Maste         ~CommandOptions() override = default;
1587ac7ddfbfSEd Maste 
1588ac7ddfbfSEd Maste         Error
15899f2f44ceSEd Maste         SetOptionValue (uint32_t option_idx, const char *option_arg) override
1590ac7ddfbfSEd Maste         {
1591ac7ddfbfSEd Maste             Error error;
1592ac7ddfbfSEd Maste             const int short_option = m_getopt_table[option_idx].val;
1593ac7ddfbfSEd Maste 
1594ac7ddfbfSEd Maste             switch (short_option)
1595ac7ddfbfSEd Maste             {
1596ac7ddfbfSEd Maste                 case 's':
1597ac7ddfbfSEd Maste                     stop = option_arg;
1598ac7ddfbfSEd Maste                     break;
1599ac7ddfbfSEd Maste                 case 'n':
1600ac7ddfbfSEd Maste                     notify = option_arg;
1601ac7ddfbfSEd Maste                     break;
1602ac7ddfbfSEd Maste                 case 'p':
1603ac7ddfbfSEd Maste                     pass = option_arg;
1604ac7ddfbfSEd Maste                     break;
1605ac7ddfbfSEd Maste                 default:
1606ac7ddfbfSEd Maste                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
1607ac7ddfbfSEd Maste                     break;
1608ac7ddfbfSEd Maste             }
1609ac7ddfbfSEd Maste             return error;
1610ac7ddfbfSEd Maste         }
1611ac7ddfbfSEd Maste 
1612ac7ddfbfSEd Maste         void
16139f2f44ceSEd Maste         OptionParsingStarting () override
1614ac7ddfbfSEd Maste         {
1615ac7ddfbfSEd Maste             stop.clear();
1616ac7ddfbfSEd Maste             notify.clear();
1617ac7ddfbfSEd Maste             pass.clear();
1618ac7ddfbfSEd Maste         }
1619ac7ddfbfSEd Maste 
1620ac7ddfbfSEd Maste         const OptionDefinition*
16219f2f44ceSEd Maste         GetDefinitions () override
1622ac7ddfbfSEd Maste         {
1623ac7ddfbfSEd Maste             return g_option_table;
1624ac7ddfbfSEd Maste         }
1625ac7ddfbfSEd Maste 
1626ac7ddfbfSEd Maste         // Options table: Required for subclasses of Options.
1627ac7ddfbfSEd Maste 
1628ac7ddfbfSEd Maste         static OptionDefinition g_option_table[];
1629ac7ddfbfSEd Maste 
1630ac7ddfbfSEd Maste         // Instance variables to hold the values for command options.
1631ac7ddfbfSEd Maste 
1632ac7ddfbfSEd Maste         std::string stop;
1633ac7ddfbfSEd Maste         std::string notify;
1634ac7ddfbfSEd Maste         std::string pass;
1635ac7ddfbfSEd Maste     };
1636ac7ddfbfSEd Maste 
16374bb0738eSEd Maste     CommandObjectProcessHandle(CommandInterpreter &interpreter)
16384bb0738eSEd Maste         : CommandObjectParsed(
16394bb0738eSEd Maste               interpreter, "process handle",
16404bb0738eSEd Maste               "Manage LLDB handling of OS signals for the current target process.  Defaults to showing current policy.",
16414bb0738eSEd Maste               nullptr),
1642ac7ddfbfSEd Maste           m_options(interpreter)
1643ac7ddfbfSEd Maste     {
1644b91a7dfcSDimitry Andric         SetHelpLong ("\nIf no signals are specified, update them all.  If no update "
1645b91a7dfcSDimitry Andric                      "option is specified, list the current values.");
1646ac7ddfbfSEd Maste         CommandArgumentEntry arg;
1647ac7ddfbfSEd Maste         CommandArgumentData signal_arg;
1648ac7ddfbfSEd Maste 
1649ac7ddfbfSEd Maste         signal_arg.arg_type = eArgTypeUnixSignal;
1650ac7ddfbfSEd Maste         signal_arg.arg_repetition = eArgRepeatStar;
1651ac7ddfbfSEd Maste 
1652ac7ddfbfSEd Maste         arg.push_back (signal_arg);
1653ac7ddfbfSEd Maste 
1654ac7ddfbfSEd Maste         m_arguments.push_back (arg);
1655ac7ddfbfSEd Maste     }
1656ac7ddfbfSEd Maste 
16574bb0738eSEd Maste     ~CommandObjectProcessHandle() override = default;
1658ac7ddfbfSEd Maste 
1659ac7ddfbfSEd Maste     Options *
16609f2f44ceSEd Maste     GetOptions () override
1661ac7ddfbfSEd Maste     {
1662ac7ddfbfSEd Maste         return &m_options;
1663ac7ddfbfSEd Maste     }
1664ac7ddfbfSEd Maste 
1665ac7ddfbfSEd Maste     bool
1666ac7ddfbfSEd Maste     VerifyCommandOptionValue (const std::string &option, int &real_value)
1667ac7ddfbfSEd Maste     {
1668ac7ddfbfSEd Maste         bool okay = true;
1669ac7ddfbfSEd Maste         bool success = false;
1670ac7ddfbfSEd Maste         bool tmp_value = Args::StringToBoolean (option.c_str(), false, &success);
1671ac7ddfbfSEd Maste 
1672ac7ddfbfSEd Maste         if (success && tmp_value)
1673ac7ddfbfSEd Maste             real_value = 1;
1674ac7ddfbfSEd Maste         else if (success && !tmp_value)
1675ac7ddfbfSEd Maste             real_value = 0;
1676ac7ddfbfSEd Maste         else
1677ac7ddfbfSEd Maste         {
1678ac7ddfbfSEd Maste             // If the value isn't 'true' or 'false', it had better be 0 or 1.
16791c3bbb01SEd Maste             real_value = StringConvert::ToUInt32 (option.c_str(), 3);
1680ac7ddfbfSEd Maste             if (real_value != 0 && real_value != 1)
1681ac7ddfbfSEd Maste                 okay = false;
1682ac7ddfbfSEd Maste         }
1683ac7ddfbfSEd Maste 
1684ac7ddfbfSEd Maste         return okay;
1685ac7ddfbfSEd Maste     }
1686ac7ddfbfSEd Maste 
1687ac7ddfbfSEd Maste     void
1688ac7ddfbfSEd Maste     PrintSignalHeader (Stream &str)
1689ac7ddfbfSEd Maste     {
1690ac7ddfbfSEd Maste         str.Printf ("NAME         PASS   STOP   NOTIFY\n");
16911c3bbb01SEd Maste         str.Printf ("===========  =====  =====  ======\n");
1692ac7ddfbfSEd Maste     }
1693ac7ddfbfSEd Maste 
1694ac7ddfbfSEd Maste     void
1695b91a7dfcSDimitry Andric     PrintSignal(Stream &str, int32_t signo, const char *sig_name, const UnixSignalsSP &signals_sp)
1696ac7ddfbfSEd Maste     {
1697ac7ddfbfSEd Maste         bool stop;
1698ac7ddfbfSEd Maste         bool suppress;
1699ac7ddfbfSEd Maste         bool notify;
1700ac7ddfbfSEd Maste 
17011c3bbb01SEd Maste         str.Printf ("%-11s  ", sig_name);
1702b91a7dfcSDimitry Andric         if (signals_sp->GetSignalInfo(signo, suppress, stop, notify))
1703ac7ddfbfSEd Maste         {
1704ac7ddfbfSEd Maste             bool pass = !suppress;
1705ac7ddfbfSEd Maste             str.Printf ("%s  %s  %s",
1706ac7ddfbfSEd Maste                         (pass ? "true " : "false"),
1707ac7ddfbfSEd Maste                         (stop ? "true " : "false"),
1708ac7ddfbfSEd Maste                         (notify ? "true " : "false"));
1709ac7ddfbfSEd Maste         }
1710ac7ddfbfSEd Maste         str.Printf ("\n");
1711ac7ddfbfSEd Maste     }
1712ac7ddfbfSEd Maste 
1713ac7ddfbfSEd Maste     void
1714b91a7dfcSDimitry Andric     PrintSignalInformation(Stream &str, Args &signal_args, int num_valid_signals, const UnixSignalsSP &signals_sp)
1715ac7ddfbfSEd Maste     {
1716ac7ddfbfSEd Maste         PrintSignalHeader (str);
1717ac7ddfbfSEd Maste 
1718ac7ddfbfSEd Maste         if (num_valid_signals > 0)
1719ac7ddfbfSEd Maste         {
1720ac7ddfbfSEd Maste             size_t num_args = signal_args.GetArgumentCount();
1721ac7ddfbfSEd Maste             for (size_t i = 0; i < num_args; ++i)
1722ac7ddfbfSEd Maste             {
1723b91a7dfcSDimitry Andric                 int32_t signo = signals_sp->GetSignalNumberFromName(signal_args.GetArgumentAtIndex(i));
1724ac7ddfbfSEd Maste                 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
1725b91a7dfcSDimitry Andric                     PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals_sp);
1726ac7ddfbfSEd Maste             }
1727ac7ddfbfSEd Maste         }
1728ac7ddfbfSEd Maste         else // Print info for ALL signals
1729ac7ddfbfSEd Maste         {
1730b91a7dfcSDimitry Andric             int32_t signo = signals_sp->GetFirstSignalNumber();
1731ac7ddfbfSEd Maste             while (signo != LLDB_INVALID_SIGNAL_NUMBER)
1732ac7ddfbfSEd Maste             {
1733b91a7dfcSDimitry Andric                 PrintSignal(str, signo, signals_sp->GetSignalAsCString(signo), signals_sp);
1734b91a7dfcSDimitry Andric                 signo = signals_sp->GetNextSignalNumber(signo);
1735ac7ddfbfSEd Maste             }
1736ac7ddfbfSEd Maste         }
1737ac7ddfbfSEd Maste     }
1738ac7ddfbfSEd Maste 
1739ac7ddfbfSEd Maste protected:
1740ac7ddfbfSEd Maste     bool
17419f2f44ceSEd Maste     DoExecute (Args &signal_args, CommandReturnObject &result) override
1742ac7ddfbfSEd Maste     {
1743ac7ddfbfSEd Maste         TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
1744ac7ddfbfSEd Maste 
1745ac7ddfbfSEd Maste         if (!target_sp)
1746ac7ddfbfSEd Maste         {
1747ac7ddfbfSEd Maste             result.AppendError ("No current target;"
1748ac7ddfbfSEd Maste                                 " cannot handle signals until you have a valid target and process.\n");
1749ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
1750ac7ddfbfSEd Maste             return false;
1751ac7ddfbfSEd Maste         }
1752ac7ddfbfSEd Maste 
1753ac7ddfbfSEd Maste         ProcessSP process_sp = target_sp->GetProcessSP();
1754ac7ddfbfSEd Maste 
1755ac7ddfbfSEd Maste         if (!process_sp)
1756ac7ddfbfSEd Maste         {
1757ac7ddfbfSEd Maste             result.AppendError ("No current process; cannot handle signals until you have a valid process.\n");
1758ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
1759ac7ddfbfSEd Maste             return false;
1760ac7ddfbfSEd Maste         }
1761ac7ddfbfSEd Maste 
1762ac7ddfbfSEd Maste         int stop_action = -1;   // -1 means leave the current setting alone
1763ac7ddfbfSEd Maste         int pass_action = -1;   // -1 means leave the current setting alone
1764ac7ddfbfSEd Maste         int notify_action = -1; // -1 means leave the current setting alone
1765ac7ddfbfSEd Maste 
1766ac7ddfbfSEd Maste         if (! m_options.stop.empty()
1767ac7ddfbfSEd Maste             && ! VerifyCommandOptionValue (m_options.stop, stop_action))
1768ac7ddfbfSEd Maste         {
1769ac7ddfbfSEd Maste             result.AppendError ("Invalid argument for command option --stop; must be true or false.\n");
1770ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
1771ac7ddfbfSEd Maste             return false;
1772ac7ddfbfSEd Maste         }
1773ac7ddfbfSEd Maste 
1774ac7ddfbfSEd Maste         if (! m_options.notify.empty()
1775ac7ddfbfSEd Maste             && ! VerifyCommandOptionValue (m_options.notify, notify_action))
1776ac7ddfbfSEd Maste         {
1777ac7ddfbfSEd Maste             result.AppendError ("Invalid argument for command option --notify; must be true or false.\n");
1778ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
1779ac7ddfbfSEd Maste             return false;
1780ac7ddfbfSEd Maste         }
1781ac7ddfbfSEd Maste 
1782ac7ddfbfSEd Maste         if (! m_options.pass.empty()
1783ac7ddfbfSEd Maste             && ! VerifyCommandOptionValue (m_options.pass, pass_action))
1784ac7ddfbfSEd Maste         {
1785ac7ddfbfSEd Maste             result.AppendError ("Invalid argument for command option --pass; must be true or false.\n");
1786ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
1787ac7ddfbfSEd Maste             return false;
1788ac7ddfbfSEd Maste         }
1789ac7ddfbfSEd Maste 
1790ac7ddfbfSEd Maste         size_t num_args = signal_args.GetArgumentCount();
1791b91a7dfcSDimitry Andric         UnixSignalsSP signals_sp = process_sp->GetUnixSignals();
1792ac7ddfbfSEd Maste         int num_signals_set = 0;
1793ac7ddfbfSEd Maste 
1794ac7ddfbfSEd Maste         if (num_args > 0)
1795ac7ddfbfSEd Maste         {
1796ac7ddfbfSEd Maste             for (size_t i = 0; i < num_args; ++i)
1797ac7ddfbfSEd Maste             {
1798b91a7dfcSDimitry Andric                 int32_t signo = signals_sp->GetSignalNumberFromName(signal_args.GetArgumentAtIndex(i));
1799ac7ddfbfSEd Maste                 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
1800ac7ddfbfSEd Maste                 {
1801ac7ddfbfSEd Maste                     // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees
1802ac7ddfbfSEd Maste                     // the value is either 0 or 1.
1803ac7ddfbfSEd Maste                     if (stop_action != -1)
1804b91a7dfcSDimitry Andric                         signals_sp->SetShouldStop(signo, stop_action);
1805ac7ddfbfSEd Maste                     if (pass_action != -1)
1806ac7ddfbfSEd Maste                     {
1807b91a7dfcSDimitry Andric                         bool suppress = !pass_action;
1808b91a7dfcSDimitry Andric                         signals_sp->SetShouldSuppress(signo, suppress);
1809ac7ddfbfSEd Maste                     }
1810ac7ddfbfSEd Maste                     if (notify_action != -1)
1811b91a7dfcSDimitry Andric                         signals_sp->SetShouldNotify(signo, notify_action);
1812ac7ddfbfSEd Maste                     ++num_signals_set;
1813ac7ddfbfSEd Maste                 }
1814ac7ddfbfSEd Maste                 else
1815ac7ddfbfSEd Maste                 {
1816ac7ddfbfSEd Maste                     result.AppendErrorWithFormat ("Invalid signal name '%s'\n", signal_args.GetArgumentAtIndex (i));
1817ac7ddfbfSEd Maste                 }
1818ac7ddfbfSEd Maste             }
1819ac7ddfbfSEd Maste         }
1820ac7ddfbfSEd Maste         else
1821ac7ddfbfSEd Maste         {
1822ac7ddfbfSEd Maste             // No signal specified, if any command options were specified, update ALL signals.
1823ac7ddfbfSEd Maste             if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1))
1824ac7ddfbfSEd Maste             {
1825ac7ddfbfSEd Maste                 if (m_interpreter.Confirm ("Do you really want to update all the signals?", false))
1826ac7ddfbfSEd Maste                 {
1827b91a7dfcSDimitry Andric                     int32_t signo = signals_sp->GetFirstSignalNumber();
1828ac7ddfbfSEd Maste                     while (signo != LLDB_INVALID_SIGNAL_NUMBER)
1829ac7ddfbfSEd Maste                     {
1830ac7ddfbfSEd Maste                         if (notify_action != -1)
1831b91a7dfcSDimitry Andric                             signals_sp->SetShouldNotify(signo, notify_action);
1832ac7ddfbfSEd Maste                         if (stop_action != -1)
1833b91a7dfcSDimitry Andric                             signals_sp->SetShouldStop(signo, stop_action);
1834ac7ddfbfSEd Maste                         if (pass_action != -1)
1835ac7ddfbfSEd Maste                         {
1836b91a7dfcSDimitry Andric                             bool suppress = !pass_action;
1837b91a7dfcSDimitry Andric                             signals_sp->SetShouldSuppress(signo, suppress);
1838ac7ddfbfSEd Maste                         }
1839b91a7dfcSDimitry Andric                         signo = signals_sp->GetNextSignalNumber(signo);
1840ac7ddfbfSEd Maste                     }
1841ac7ddfbfSEd Maste                 }
1842ac7ddfbfSEd Maste             }
1843ac7ddfbfSEd Maste         }
1844ac7ddfbfSEd Maste 
1845b91a7dfcSDimitry Andric         PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals_sp);
1846ac7ddfbfSEd Maste 
1847ac7ddfbfSEd Maste         if (num_signals_set > 0)
1848ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1849ac7ddfbfSEd Maste         else
1850ac7ddfbfSEd Maste             result.SetStatus (eReturnStatusFailed);
1851ac7ddfbfSEd Maste 
1852ac7ddfbfSEd Maste         return result.Succeeded();
1853ac7ddfbfSEd Maste     }
1854ac7ddfbfSEd Maste 
1855ac7ddfbfSEd Maste     CommandOptions m_options;
1856ac7ddfbfSEd Maste };
1857ac7ddfbfSEd Maste 
1858ac7ddfbfSEd Maste OptionDefinition
1859ac7ddfbfSEd Maste CommandObjectProcessHandle::CommandOptions::g_option_table[] =
1860ac7ddfbfSEd Maste {
18614bb0738eSEd Maste { LLDB_OPT_SET_1, false, "stop",   's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Whether or not the process should be stopped if the signal is received." },
18624bb0738eSEd Maste { LLDB_OPT_SET_1, false, "notify", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Whether or not the debugger should notify the user if the signal is received." },
18634bb0738eSEd Maste { LLDB_OPT_SET_1, false, "pass",  'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." },
18644bb0738eSEd Maste { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
1865ac7ddfbfSEd Maste };
1866ac7ddfbfSEd Maste 
1867ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1868ac7ddfbfSEd Maste // CommandObjectMultiwordProcess
1869ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1870ac7ddfbfSEd Maste 
18714bb0738eSEd Maste CommandObjectMultiwordProcess::CommandObjectMultiwordProcess(CommandInterpreter &interpreter)
18724bb0738eSEd Maste     : CommandObjectMultiword(interpreter, "process", "Commands for interacting with processes on the current platform.",
1873ac7ddfbfSEd Maste                              "process <subcommand> [<subcommand-options>]")
1874ac7ddfbfSEd Maste {
1875ac7ddfbfSEd Maste     LoadSubCommand ("attach",      CommandObjectSP (new CommandObjectProcessAttach    (interpreter)));
1876ac7ddfbfSEd Maste     LoadSubCommand ("launch",      CommandObjectSP (new CommandObjectProcessLaunch    (interpreter)));
1877ac7ddfbfSEd Maste     LoadSubCommand ("continue",    CommandObjectSP (new CommandObjectProcessContinue  (interpreter)));
1878ac7ddfbfSEd Maste     LoadSubCommand ("connect",     CommandObjectSP (new CommandObjectProcessConnect   (interpreter)));
1879ac7ddfbfSEd Maste     LoadSubCommand ("detach",      CommandObjectSP (new CommandObjectProcessDetach    (interpreter)));
1880ac7ddfbfSEd Maste     LoadSubCommand ("load",        CommandObjectSP (new CommandObjectProcessLoad      (interpreter)));
1881ac7ddfbfSEd Maste     LoadSubCommand ("unload",      CommandObjectSP (new CommandObjectProcessUnload    (interpreter)));
1882ac7ddfbfSEd Maste     LoadSubCommand ("signal",      CommandObjectSP (new CommandObjectProcessSignal    (interpreter)));
1883ac7ddfbfSEd Maste     LoadSubCommand ("handle",      CommandObjectSP (new CommandObjectProcessHandle    (interpreter)));
1884ac7ddfbfSEd Maste     LoadSubCommand ("status",      CommandObjectSP (new CommandObjectProcessStatus    (interpreter)));
1885ac7ddfbfSEd Maste     LoadSubCommand ("interrupt",   CommandObjectSP (new CommandObjectProcessInterrupt (interpreter)));
1886ac7ddfbfSEd Maste     LoadSubCommand ("kill",        CommandObjectSP (new CommandObjectProcessKill      (interpreter)));
1887ac7ddfbfSEd Maste     LoadSubCommand ("plugin",      CommandObjectSP (new CommandObjectProcessPlugin    (interpreter)));
18880127ef0fSEd Maste     LoadSubCommand ("save-core",   CommandObjectSP (new CommandObjectProcessSaveCore  (interpreter)));
1889ac7ddfbfSEd Maste }
1890ac7ddfbfSEd Maste 
18914bb0738eSEd Maste CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess() = default;
1892