130fdc8d8SChris Lattner //===-- CommandObjectProcess.cpp --------------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
1030fdc8d8SChris Lattner // C Includes
1130fdc8d8SChris Lattner // C++ Includes
1230fdc8d8SChris Lattner // Other libraries and framework includes
1330fdc8d8SChris Lattner // Project includes
1449bcfd80SEugene Zelenko #include "CommandObjectProcess.h"
150e41084aSJim Ingham #include "lldb/Breakpoint/Breakpoint.h"
160e41084aSJim Ingham #include "lldb/Breakpoint/BreakpointLocation.h"
170e41084aSJim Ingham #include "lldb/Breakpoint/BreakpointSite.h"
1830fdc8d8SChris Lattner #include "lldb/Core/State.h"
191f746071SGreg Clayton #include "lldb/Core/Module.h"
20a2715cf1SGreg Clayton #include "lldb/Core/PluginManager.h"
217260f620SGreg Clayton #include "lldb/Host/Host.h"
225275aaa0SVince Harron #include "lldb/Host/StringConvert.h"
230e41084aSJim Ingham #include "lldb/Interpreter/Args.h"
240e41084aSJim Ingham #include "lldb/Interpreter/Options.h"
2530fdc8d8SChris Lattner #include "lldb/Interpreter/CommandInterpreter.h"
2630fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h"
27e996fd30SGreg Clayton #include "lldb/Target/Platform.h"
2830fdc8d8SChris Lattner #include "lldb/Target/Process.h"
290e41084aSJim Ingham #include "lldb/Target/StopInfo.h"
3030fdc8d8SChris Lattner #include "lldb/Target/Target.h"
3130fdc8d8SChris Lattner #include "lldb/Target/Thread.h"
3293749ab3SZachary Turner #include "lldb/Target/UnixSignals.h"
3330fdc8d8SChris Lattner 
3430fdc8d8SChris Lattner using namespace lldb;
3530fdc8d8SChris Lattner using namespace lldb_private;
3630fdc8d8SChris Lattner 
37dcb1d856SJim Ingham class CommandObjectProcessLaunchOrAttach : public CommandObjectParsed
38dcb1d856SJim Ingham {
39dcb1d856SJim Ingham public:
40dcb1d856SJim Ingham     CommandObjectProcessLaunchOrAttach (CommandInterpreter &interpreter,
41dcb1d856SJim Ingham                                        const char *name,
42dcb1d856SJim Ingham                                        const char *help,
43dcb1d856SJim Ingham                                        const char *syntax,
44dcb1d856SJim Ingham                                        uint32_t flags,
45dcb1d856SJim Ingham                                        const char *new_process_action) :
46dcb1d856SJim Ingham         CommandObjectParsed (interpreter, name, help, syntax, flags),
47dcb1d856SJim Ingham         m_new_process_action (new_process_action) {}
48dcb1d856SJim Ingham 
4949bcfd80SEugene Zelenko     ~CommandObjectProcessLaunchOrAttach() override = default;
5049bcfd80SEugene Zelenko 
51dcb1d856SJim Ingham protected:
52dcb1d856SJim Ingham     bool
53b09c5384SGreg Clayton     StopProcessIfNecessary (Process *process, StateType &state, CommandReturnObject &result)
54dcb1d856SJim Ingham     {
55dcb1d856SJim Ingham         state = eStateInvalid;
56dcb1d856SJim Ingham         if (process)
57dcb1d856SJim Ingham         {
58dcb1d856SJim Ingham             state = process->GetState();
59dcb1d856SJim Ingham 
60dcb1d856SJim Ingham             if (process->IsAlive() && state != eStateConnected)
61dcb1d856SJim Ingham             {
62dcb1d856SJim Ingham                 char message[1024];
63dcb1d856SJim Ingham                 if (process->GetState() == eStateAttaching)
64dcb1d856SJim Ingham                     ::snprintf (message, sizeof(message), "There is a pending attach, abort it and %s?", m_new_process_action.c_str());
65dcb1d856SJim Ingham                 else if (process->GetShouldDetach())
66dcb1d856SJim Ingham                     ::snprintf (message, sizeof(message), "There is a running process, detach from it and %s?", m_new_process_action.c_str());
67dcb1d856SJim Ingham                 else
68dcb1d856SJim Ingham                     ::snprintf (message, sizeof(message), "There is a running process, kill it and %s?", m_new_process_action.c_str());
69dcb1d856SJim Ingham 
70dcb1d856SJim Ingham                 if (!m_interpreter.Confirm (message, true))
71dcb1d856SJim Ingham                 {
72dcb1d856SJim Ingham                     result.SetStatus (eReturnStatusFailed);
73dcb1d856SJim Ingham                     return false;
74dcb1d856SJim Ingham                 }
75dcb1d856SJim Ingham                 else
76dcb1d856SJim Ingham                 {
77dcb1d856SJim Ingham                     if (process->GetShouldDetach())
78dcb1d856SJim Ingham                     {
79acff8950SJim Ingham                         bool keep_stopped = false;
80acff8950SJim Ingham                         Error detach_error (process->Detach(keep_stopped));
81dcb1d856SJim Ingham                         if (detach_error.Success())
82dcb1d856SJim Ingham                         {
83dcb1d856SJim Ingham                             result.SetStatus (eReturnStatusSuccessFinishResult);
8449bcfd80SEugene Zelenko                             process = nullptr;
85dcb1d856SJim Ingham                         }
86dcb1d856SJim Ingham                         else
87dcb1d856SJim Ingham                         {
88dcb1d856SJim Ingham                             result.AppendErrorWithFormat ("Failed to detach from process: %s\n", detach_error.AsCString());
89dcb1d856SJim Ingham                             result.SetStatus (eReturnStatusFailed);
90dcb1d856SJim Ingham                         }
91dcb1d856SJim Ingham                     }
92dcb1d856SJim Ingham                     else
93dcb1d856SJim Ingham                     {
94ede3193bSJason Molenda                         Error destroy_error (process->Destroy(false));
95dcb1d856SJim Ingham                         if (destroy_error.Success())
96dcb1d856SJim Ingham                         {
97dcb1d856SJim Ingham                             result.SetStatus (eReturnStatusSuccessFinishResult);
9849bcfd80SEugene Zelenko                             process = nullptr;
99dcb1d856SJim Ingham                         }
100dcb1d856SJim Ingham                         else
101dcb1d856SJim Ingham                         {
102dcb1d856SJim Ingham                             result.AppendErrorWithFormat ("Failed to kill process: %s\n", destroy_error.AsCString());
103dcb1d856SJim Ingham                             result.SetStatus (eReturnStatusFailed);
104dcb1d856SJim Ingham                         }
105dcb1d856SJim Ingham                     }
106dcb1d856SJim Ingham                 }
107dcb1d856SJim Ingham             }
108dcb1d856SJim Ingham         }
109dcb1d856SJim Ingham         return result.Succeeded();
110dcb1d856SJim Ingham     }
11149bcfd80SEugene Zelenko 
112dcb1d856SJim Ingham     std::string m_new_process_action;
113dcb1d856SJim Ingham };
11449bcfd80SEugene Zelenko 
11530fdc8d8SChris Lattner //-------------------------------------------------------------------------
11630fdc8d8SChris Lattner // CommandObjectProcessLaunch
11730fdc8d8SChris Lattner //-------------------------------------------------------------------------
1184bddaeb5SJim Ingham #pragma mark CommandObjectProcessLaunch
119dcb1d856SJim Ingham class CommandObjectProcessLaunch : public CommandObjectProcessLaunchOrAttach
12030fdc8d8SChris Lattner {
12130fdc8d8SChris Lattner public:
122a7015092SGreg Clayton     CommandObjectProcessLaunch (CommandInterpreter &interpreter) :
123dcb1d856SJim Ingham         CommandObjectProcessLaunchOrAttach(interpreter,
124a7015092SGreg Clayton                                            "process launch",
125e3d26315SCaroline Tice                                            "Launch the executable in the debugger.",
12649bcfd80SEugene Zelenko                                            nullptr,
127e87764f2SEnrico Granata                                            eCommandRequiresTarget,
128dcb1d856SJim Ingham                                            "restart"),
129eb0103f2SGreg Clayton         m_options (interpreter)
13030fdc8d8SChris Lattner     {
131405fe67fSCaroline Tice         CommandArgumentEntry arg;
132405fe67fSCaroline Tice         CommandArgumentData run_args_arg;
133405fe67fSCaroline Tice 
134405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
135405fe67fSCaroline Tice         run_args_arg.arg_type = eArgTypeRunArgs;
136405fe67fSCaroline Tice         run_args_arg.arg_repetition = eArgRepeatOptional;
137405fe67fSCaroline Tice 
138405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
139405fe67fSCaroline Tice         arg.push_back (run_args_arg);
140405fe67fSCaroline Tice 
141405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
142405fe67fSCaroline Tice         m_arguments.push_back (arg);
14330fdc8d8SChris Lattner     }
14430fdc8d8SChris Lattner 
14549bcfd80SEugene Zelenko     ~CommandObjectProcessLaunch() override = default;
14630fdc8d8SChris Lattner 
14713d21e9aSBruce Mitchener     int
148e9ce62b6SJim Ingham     HandleArgumentCompletion (Args &input,
149e9ce62b6SJim Ingham                               int &cursor_index,
150e9ce62b6SJim Ingham                               int &cursor_char_position,
151e9ce62b6SJim Ingham                               OptionElementVector &opt_element_vector,
152e9ce62b6SJim Ingham                               int match_start_point,
153e9ce62b6SJim Ingham                               int max_return_elements,
154e9ce62b6SJim Ingham                               bool &word_complete,
15513d21e9aSBruce Mitchener                               StringList &matches) override
156e9ce62b6SJim Ingham     {
157e9ce62b6SJim Ingham         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
158e9ce62b6SJim Ingham         completion_str.erase (cursor_char_position);
159e9ce62b6SJim Ingham 
160e9ce62b6SJim Ingham         CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
161e9ce62b6SJim Ingham                                                             CommandCompletions::eDiskFileCompletion,
162e9ce62b6SJim Ingham                                                             completion_str.c_str(),
163e9ce62b6SJim Ingham                                                             match_start_point,
164e9ce62b6SJim Ingham                                                             max_return_elements,
16549bcfd80SEugene Zelenko                                                             nullptr,
166e9ce62b6SJim Ingham                                                             word_complete,
167e9ce62b6SJim Ingham                                                             matches);
168e9ce62b6SJim Ingham         return matches.GetSize();
169e9ce62b6SJim Ingham     }
170e9ce62b6SJim Ingham 
17130fdc8d8SChris Lattner     Options *
17213d21e9aSBruce Mitchener     GetOptions () override
17330fdc8d8SChris Lattner     {
17430fdc8d8SChris Lattner         return &m_options;
17530fdc8d8SChris Lattner     }
17630fdc8d8SChris Lattner 
17713d21e9aSBruce Mitchener     const char *
17813d21e9aSBruce Mitchener     GetRepeatCommand (Args &current_command_args, uint32_t index) override
1795a988416SJim Ingham     {
1805a988416SJim Ingham         // No repeat for "process launch"...
1815a988416SJim Ingham         return "";
1825a988416SJim Ingham     }
1835a988416SJim Ingham 
1845a988416SJim Ingham protected:
18530fdc8d8SChris Lattner     bool
18613d21e9aSBruce Mitchener     DoExecute (Args& launch_args, CommandReturnObject &result) override
18730fdc8d8SChris Lattner     {
1881d885966SGreg Clayton         Debugger &debugger = m_interpreter.GetDebugger();
1891d885966SGreg Clayton         Target *target = debugger.GetSelectedTarget().get();
19049bcfd80SEugene Zelenko         // If our listener is nullptr, users aren't allows to launch
191b09c5384SGreg Clayton         ModuleSP exe_module_sp = target->GetExecutableModule();
19271337622SGreg Clayton 
19349bcfd80SEugene Zelenko         if (exe_module_sp == nullptr)
19471337622SGreg Clayton         {
195effe5c95SGreg Clayton             result.AppendError ("no file in target, create a debug target using the 'target create' command");
19671337622SGreg Clayton             result.SetStatus (eReturnStatusFailed);
19771337622SGreg Clayton             return false;
19871337622SGreg Clayton         }
19971337622SGreg Clayton 
20071337622SGreg Clayton         StateType state = eStateInvalid;
20171337622SGreg Clayton 
202b09c5384SGreg Clayton         if (!StopProcessIfNecessary(m_exe_ctx.GetProcessPtr(), state, result))
20330fdc8d8SChris Lattner             return false;
20430fdc8d8SChris Lattner 
20545392553SGreg Clayton         const char *target_settings_argv0 = target->GetArg0();
20645392553SGreg Clayton 
2075163792bSTodd Fiala         // Determine whether we will disable ASLR or leave it in the default state (i.e. enabled if the platform supports it).
2085163792bSTodd Fiala         // First check if the process launch options explicitly turn on/off disabling ASLR.  If so, use that setting;
2095163792bSTodd Fiala         // otherwise, use the 'settings target.disable-aslr' setting.
2105163792bSTodd Fiala         bool disable_aslr = false;
2115163792bSTodd Fiala         if (m_options.disable_aslr != eLazyBoolCalculate)
2125163792bSTodd Fiala         {
2135163792bSTodd Fiala             // The user specified an explicit setting on the process launch line.  Use it.
2145163792bSTodd Fiala             disable_aslr = (m_options.disable_aslr == eLazyBoolYes);
2155163792bSTodd Fiala         }
2165163792bSTodd Fiala         else
2175163792bSTodd Fiala         {
2185163792bSTodd Fiala             // The user did not explicitly specify whether to disable ASLR.  Fall back to the target.disable-aslr setting.
2195163792bSTodd Fiala             disable_aslr = target->GetDisableASLR ();
2205163792bSTodd Fiala         }
2215163792bSTodd Fiala 
2225163792bSTodd Fiala         if (disable_aslr)
223b09c5384SGreg Clayton             m_options.launch_info.GetFlags().Set (eLaunchFlagDisableASLR);
2245163792bSTodd Fiala         else
2255163792bSTodd Fiala             m_options.launch_info.GetFlags().Clear (eLaunchFlagDisableASLR);
226b09c5384SGreg Clayton 
227106d0286SJim Ingham         if (target->GetDetachOnError())
228106d0286SJim Ingham             m_options.launch_info.GetFlags().Set (eLaunchFlagDetachOnError);
229106d0286SJim Ingham 
230b09c5384SGreg Clayton         if (target->GetDisableSTDIO())
231b09c5384SGreg Clayton             m_options.launch_info.GetFlags().Set (eLaunchFlagDisableSTDIO);
232b09c5384SGreg Clayton 
233b09c5384SGreg Clayton         Args environment;
234b09c5384SGreg Clayton         target->GetEnvironmentAsArgs (environment);
235b09c5384SGreg Clayton         if (environment.GetArgumentCount() > 0)
236b09c5384SGreg Clayton             m_options.launch_info.GetEnvironmentEntries ().AppendArguments (environment);
23745392553SGreg Clayton 
23845392553SGreg Clayton         if (target_settings_argv0)
23945392553SGreg Clayton         {
24045392553SGreg Clayton             m_options.launch_info.GetArguments().AppendArgument (target_settings_argv0);
241b09c5384SGreg Clayton             m_options.launch_info.SetExecutableFile(exe_module_sp->GetPlatformFileSpec(), false);
24245392553SGreg Clayton         }
24345392553SGreg Clayton         else
24445392553SGreg Clayton         {
245b09c5384SGreg Clayton             m_options.launch_info.SetExecutableFile(exe_module_sp->GetPlatformFileSpec(), true);
24645392553SGreg Clayton         }
24745392553SGreg Clayton 
248144f3a9cSGreg Clayton         if (launch_args.GetArgumentCount() == 0)
249144f3a9cSGreg Clayton         {
250cc39d3f4SIlia K             m_options.launch_info.GetArguments().AppendArguments (target->GetProcessLaunchInfo().GetArguments());
251144f3a9cSGreg Clayton         }
252144f3a9cSGreg Clayton         else
25330fdc8d8SChris Lattner         {
25445392553SGreg Clayton             m_options.launch_info.GetArguments().AppendArguments (launch_args);
255162b597cSGreg Clayton             // Save the arguments for subsequent runs in the current target.
256162b597cSGreg Clayton             target->SetRunArguments (launch_args);
257982c9762SGreg Clayton         }
2581d885966SGreg Clayton 
259dc6224e0SGreg Clayton         StreamString stream;
2608012cadbSGreg Clayton         Error error = target->Launch(m_options.launch_info, &stream);
26130fdc8d8SChris Lattner 
26230fdc8d8SChris Lattner         if (error.Success())
26330fdc8d8SChris Lattner         {
264b09c5384SGreg Clayton             ProcessSP process_sp (target->GetProcessSP());
265b09c5384SGreg Clayton             if (process_sp)
26630fdc8d8SChris Lattner             {
2678f0db3e1SIlia K                 // There is a race condition where this thread will return up the call stack to the main command
2688f0db3e1SIlia K                 // handler and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has
2698f0db3e1SIlia K                 // a chance to call PushProcessIOHandler().
2704446487dSPavel Labath                 process_sp->SyncIOHandler (0, 2000);
2718f0db3e1SIlia K 
272f2ef94e7SStephane Sezer                 const char *data = stream.GetData();
273f2ef94e7SStephane Sezer                 if (data && strlen(data) > 0)
274dc6224e0SGreg Clayton                     result.AppendMessage(stream.GetData());
2758f0db3e1SIlia K                 const char *archname = exe_module_sp->GetArchitecture().GetArchitectureName();
276b09c5384SGreg Clayton                 result.AppendMessageWithFormat ("Process %" PRIu64 " launched: '%s' (%s)\n", process_sp->GetID(), exe_module_sp->GetFileSpec().GetPath().c_str(), archname);
27705faeb71SGreg Clayton                 result.SetStatus (eReturnStatusSuccessFinishResult);
278b09c5384SGreg Clayton                 result.SetDidChangeProcessState (true);
27905faeb71SGreg Clayton             }
28005faeb71SGreg Clayton             else
28105faeb71SGreg Clayton             {
282b09c5384SGreg Clayton                 result.AppendError("no error returned from Target::Launch, and target has no process");
283514487e8SGreg Clayton                 result.SetStatus (eReturnStatusFailed);
28430fdc8d8SChris Lattner             }
28530fdc8d8SChris Lattner         }
286514487e8SGreg Clayton         else
287514487e8SGreg Clayton         {
288b09c5384SGreg Clayton             result.AppendError(error.AsCString());
289514487e8SGreg Clayton             result.SetStatus (eReturnStatusFailed);
290514487e8SGreg Clayton         }
29130fdc8d8SChris Lattner         return result.Succeeded();
29230fdc8d8SChris Lattner     }
29330fdc8d8SChris Lattner 
29430fdc8d8SChris Lattner protected:
295982c9762SGreg Clayton     ProcessLaunchCommandOptions m_options;
29630fdc8d8SChris Lattner };
29730fdc8d8SChris Lattner 
29830fdc8d8SChris Lattner 
299982c9762SGreg Clayton //#define SET1 LLDB_OPT_SET_1
300982c9762SGreg Clayton //#define SET2 LLDB_OPT_SET_2
301982c9762SGreg Clayton //#define SET3 LLDB_OPT_SET_3
302982c9762SGreg Clayton //
303982c9762SGreg Clayton //OptionDefinition
304982c9762SGreg Clayton //CommandObjectProcessLaunch::CommandOptions::g_option_table[] =
305982c9762SGreg Clayton //{
30649bcfd80SEugene Zelenko //{ 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."},
30749bcfd80SEugene Zelenko //{ SET1              , false, "stdin",         'i', OptionParser::eRequiredArgument, nullptr, 0, eArgTypeDirectoryName,    "Redirect stdin for the process to <path>."},
30849bcfd80SEugene Zelenko //{ SET1              , false, "stdout",        'o', OptionParser::eRequiredArgument, nullptr, 0, eArgTypeDirectoryName,    "Redirect stdout for the process to <path>."},
30949bcfd80SEugene Zelenko //{ SET1              , false, "stderr",        'e', OptionParser::eRequiredArgument, nullptr, 0, eArgTypeDirectoryName,    "Redirect stderr for the process to <path>."},
31049bcfd80SEugene Zelenko //{ SET1 | SET2 | SET3, false, "plugin",        'p', OptionParser::eRequiredArgument, nullptr, 0, eArgTypePlugin,  "Name of the process plugin you want to use."},
31149bcfd80SEugene Zelenko //{        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."},
31249bcfd80SEugene Zelenko //{               SET3, false, "no-stdio",      'n', OptionParser::eNoArgument,       nullptr, 0, eArgTypeNone,    "Do not set up for terminal I/O to go to running process."},
31349bcfd80SEugene Zelenko //{ SET1 | SET2 | SET3, false, "working-dir",   'w', OptionParser::eRequiredArgument, nullptr, 0, eArgTypeDirectoryName,    "Set the current working directory to <path> when running the inferior."},
31449bcfd80SEugene Zelenko //{ 0,                  false, nullptr,             0,  0,                 nullptr, 0, eArgTypeNone,    nullptr }
315982c9762SGreg Clayton //};
316982c9762SGreg Clayton //
317982c9762SGreg Clayton //#undef SET1
318982c9762SGreg Clayton //#undef SET2
319982c9762SGreg Clayton //#undef SET3
32030fdc8d8SChris Lattner 
32130fdc8d8SChris Lattner //-------------------------------------------------------------------------
32230fdc8d8SChris Lattner // CommandObjectProcessAttach
32330fdc8d8SChris Lattner //-------------------------------------------------------------------------
324bb9caf73SJim Ingham #pragma mark CommandObjectProcessAttach
325dcb1d856SJim Ingham class CommandObjectProcessAttach : public CommandObjectProcessLaunchOrAttach
32630fdc8d8SChris Lattner {
32730fdc8d8SChris Lattner public:
32830fdc8d8SChris Lattner     class CommandOptions : public Options
32930fdc8d8SChris Lattner     {
33030fdc8d8SChris Lattner     public:
331eb0103f2SGreg Clayton         CommandOptions (CommandInterpreter &interpreter) :
332eb0103f2SGreg Clayton             Options(interpreter)
33330fdc8d8SChris Lattner         {
334f6b8b581SGreg Clayton             // Keep default values of all options in one place: OptionParsingStarting ()
335f6b8b581SGreg Clayton             OptionParsingStarting ();
33630fdc8d8SChris Lattner         }
33730fdc8d8SChris Lattner 
33849bcfd80SEugene Zelenko         ~CommandOptions() override = default;
33930fdc8d8SChris Lattner 
34030fdc8d8SChris Lattner         Error
34113d21e9aSBruce Mitchener         SetOptionValue (uint32_t option_idx, const char *option_arg) override
34230fdc8d8SChris Lattner         {
34330fdc8d8SChris Lattner             Error error;
3443bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
34530fdc8d8SChris Lattner             bool success = false;
34630fdc8d8SChris Lattner             switch (short_option)
34730fdc8d8SChris Lattner             {
348a95ce623SJohnny Chen                 case 'c':
349a95ce623SJohnny Chen                     attach_info.SetContinueOnceAttached(true);
350a95ce623SJohnny Chen                     break;
351a95ce623SJohnny Chen 
35230fdc8d8SChris Lattner                 case 'p':
353144f3a9cSGreg Clayton                     {
3545275aaa0SVince Harron                         lldb::pid_t pid = StringConvert::ToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success);
35530fdc8d8SChris Lattner                         if (!success || pid == LLDB_INVALID_PROCESS_ID)
35630fdc8d8SChris Lattner                         {
35786edbf41SGreg Clayton                             error.SetErrorStringWithFormat("invalid process ID '%s'", option_arg);
35830fdc8d8SChris Lattner                         }
359144f3a9cSGreg Clayton                         else
360144f3a9cSGreg Clayton                         {
361144f3a9cSGreg Clayton                             attach_info.SetProcessID (pid);
362144f3a9cSGreg Clayton                         }
363144f3a9cSGreg Clayton                     }
36430fdc8d8SChris Lattner                     break;
36530fdc8d8SChris Lattner 
36630fdc8d8SChris Lattner                 case 'P':
367144f3a9cSGreg Clayton                     attach_info.SetProcessPluginName (option_arg);
36830fdc8d8SChris Lattner                     break;
36930fdc8d8SChris Lattner 
37030fdc8d8SChris Lattner                 case 'n':
371144f3a9cSGreg Clayton                     attach_info.GetExecutableFile().SetFile(option_arg, false);
37230fdc8d8SChris Lattner                     break;
37330fdc8d8SChris Lattner 
37430fdc8d8SChris Lattner                 case 'w':
375144f3a9cSGreg Clayton                     attach_info.SetWaitForLaunch(true);
37630fdc8d8SChris Lattner                     break;
37730fdc8d8SChris Lattner 
378cd16df91SJim Ingham                 case 'i':
379cd16df91SJim Ingham                     attach_info.SetIgnoreExisting(false);
380cd16df91SJim Ingham                     break;
381cd16df91SJim Ingham 
38230fdc8d8SChris Lattner                 default:
38386edbf41SGreg Clayton                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
38430fdc8d8SChris Lattner                     break;
38530fdc8d8SChris Lattner             }
38630fdc8d8SChris Lattner             return error;
38730fdc8d8SChris Lattner         }
38830fdc8d8SChris Lattner 
38930fdc8d8SChris Lattner         void
39013d21e9aSBruce Mitchener         OptionParsingStarting () override
39130fdc8d8SChris Lattner         {
392144f3a9cSGreg Clayton             attach_info.Clear();
39330fdc8d8SChris Lattner         }
39430fdc8d8SChris Lattner 
395e0d378b3SGreg Clayton         const OptionDefinition*
39613d21e9aSBruce Mitchener         GetDefinitions () override
39730fdc8d8SChris Lattner         {
39830fdc8d8SChris Lattner             return g_option_table;
39930fdc8d8SChris Lattner         }
40030fdc8d8SChris Lattner 
40113d21e9aSBruce Mitchener         bool
402eb0103f2SGreg Clayton         HandleOptionArgumentCompletion (Args &input,
4035aee162fSJim Ingham                                         int cursor_index,
4045aee162fSJim Ingham                                         int char_pos,
4055aee162fSJim Ingham                                         OptionElementVector &opt_element_vector,
4065aee162fSJim Ingham                                         int opt_element_index,
4075aee162fSJim Ingham                                         int match_start_point,
4085aee162fSJim Ingham                                         int max_return_elements,
4095aee162fSJim Ingham                                         bool &word_complete,
41013d21e9aSBruce Mitchener                                         StringList &matches) override
4115aee162fSJim Ingham         {
4125aee162fSJim Ingham             int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
4135aee162fSJim Ingham             int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
4145aee162fSJim Ingham 
4155aee162fSJim Ingham             // We are only completing the name option for now...
4165aee162fSJim Ingham 
417e0d378b3SGreg Clayton             const OptionDefinition *opt_defs = GetDefinitions();
4185aee162fSJim Ingham             if (opt_defs[opt_defs_index].short_option == 'n')
4195aee162fSJim Ingham             {
4205aee162fSJim Ingham                 // Are we in the name?
4215aee162fSJim Ingham 
4225aee162fSJim Ingham                 // Look to see if there is a -P argument provided, and if so use that plugin, otherwise
4235aee162fSJim Ingham                 // use the default plugin.
4245aee162fSJim Ingham 
42549bcfd80SEugene Zelenko                 const char *partial_name = nullptr;
4265aee162fSJim Ingham                 partial_name = input.GetArgumentAtIndex(opt_arg_pos);
4275aee162fSJim Ingham 
4288b82f087SGreg Clayton                 PlatformSP platform_sp (m_interpreter.GetPlatform (true));
429e996fd30SGreg Clayton                 if (platform_sp)
4305aee162fSJim Ingham                 {
4318b82f087SGreg Clayton                     ProcessInstanceInfoList process_infos;
4328b82f087SGreg Clayton                     ProcessInstanceInfoMatch match_info;
43332e0a750SGreg Clayton                     if (partial_name)
43432e0a750SGreg Clayton                     {
435144f3a9cSGreg Clayton                         match_info.GetProcessInfo().GetExecutableFile().SetFile(partial_name, false);
43632e0a750SGreg Clayton                         match_info.SetNameMatchType(eNameMatchStartsWith);
43732e0a750SGreg Clayton                     }
43832e0a750SGreg Clayton                     platform_sp->FindProcesses (match_info, process_infos);
439c7bece56SGreg Clayton                     const size_t num_matches = process_infos.GetSize();
440e996fd30SGreg Clayton                     if (num_matches > 0)
441e996fd30SGreg Clayton                     {
442c7bece56SGreg Clayton                         for (size_t i = 0; i < num_matches; ++i)
443e996fd30SGreg Clayton                         {
444e996fd30SGreg Clayton                             matches.AppendString (process_infos.GetProcessNameAtIndex(i),
445e996fd30SGreg Clayton                                                   process_infos.GetProcessNameLengthAtIndex(i));
4465aee162fSJim Ingham                         }
4475aee162fSJim Ingham                     }
4485aee162fSJim Ingham                 }
4495aee162fSJim Ingham             }
4505aee162fSJim Ingham 
4515aee162fSJim Ingham             return false;
4525aee162fSJim Ingham         }
4535aee162fSJim Ingham 
45430fdc8d8SChris Lattner         // Options table: Required for subclasses of Options.
45530fdc8d8SChris Lattner 
456e0d378b3SGreg Clayton         static OptionDefinition g_option_table[];
45730fdc8d8SChris Lattner 
45830fdc8d8SChris Lattner         // Instance variables to hold the values for command options.
45930fdc8d8SChris Lattner 
460144f3a9cSGreg Clayton         ProcessAttachInfo attach_info;
46130fdc8d8SChris Lattner     };
46230fdc8d8SChris Lattner 
463a7015092SGreg Clayton     CommandObjectProcessAttach (CommandInterpreter &interpreter) :
464dcb1d856SJim Ingham         CommandObjectProcessLaunchOrAttach (interpreter,
465a7015092SGreg Clayton                                             "process attach",
466e3d26315SCaroline Tice                                             "Attach to a process.",
467dcb1d856SJim Ingham                                             "process attach <cmd-options>",
468dcb1d856SJim Ingham                                             0,
469dcb1d856SJim Ingham                                             "attach"),
470eb0103f2SGreg Clayton         m_options (interpreter)
4715aee162fSJim Ingham     {
4725aee162fSJim Ingham     }
4735aee162fSJim Ingham 
47449bcfd80SEugene Zelenko     ~CommandObjectProcessAttach() override = default;
4755aee162fSJim Ingham 
4765a988416SJim Ingham     Options *
47713d21e9aSBruce Mitchener     GetOptions () override
4785a988416SJim Ingham     {
4795a988416SJim Ingham         return &m_options;
4805a988416SJim Ingham     }
4815a988416SJim Ingham 
4825a988416SJim Ingham protected:
4835aee162fSJim Ingham     bool
48413d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
4855aee162fSJim Ingham     {
486926af0cdSOleksiy Vyalov         PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
487926af0cdSOleksiy Vyalov 
488a7015092SGreg Clayton         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
48931412642SJim Ingham         // N.B. The attach should be synchronous.  It doesn't help much to get the prompt back between initiating the attach
49031412642SJim Ingham         // and the target actually stopping.  So even if the interpreter is set to be asynchronous, we wait for the stop
49131412642SJim Ingham         // ourselves here.
4925aee162fSJim Ingham 
49371337622SGreg Clayton         StateType state = eStateInvalid;
494dcb1d856SJim Ingham         Process *process = m_exe_ctx.GetProcessPtr();
495dcb1d856SJim Ingham 
496dcb1d856SJim Ingham         if (!StopProcessIfNecessary (process, state, result))
4975aee162fSJim Ingham             return false;
4985aee162fSJim Ingham 
49949bcfd80SEugene Zelenko         if (target == nullptr)
5005aee162fSJim Ingham         {
5015aee162fSJim Ingham             // If there isn't a current target create one.
5025aee162fSJim Ingham             TargetSP new_target_sp;
5035aee162fSJim Ingham             Error error;
5045aee162fSJim Ingham 
505a7015092SGreg Clayton             error = m_interpreter.GetDebugger().GetTargetList().CreateTarget(m_interpreter.GetDebugger(),
50649bcfd80SEugene Zelenko                                                                              nullptr,
50749bcfd80SEugene Zelenko                                                                              nullptr,
5085aee162fSJim Ingham                                                                              false,
50949bcfd80SEugene Zelenko                                                                              nullptr, // No platform options
5105aee162fSJim Ingham                                                                              new_target_sp);
5115aee162fSJim Ingham             target = new_target_sp.get();
51249bcfd80SEugene Zelenko             if (target == nullptr || error.Fail())
5135aee162fSJim Ingham             {
514b766a73dSGreg Clayton                 result.AppendError(error.AsCString("Error creating target"));
5155aee162fSJim Ingham                 return false;
5165aee162fSJim Ingham             }
517a7015092SGreg Clayton             m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target);
5185aee162fSJim Ingham         }
5195aee162fSJim Ingham 
5205aee162fSJim Ingham         // Record the old executable module, we want to issue a warning if the process of attaching changed the
5215aee162fSJim Ingham         // current executable (like somebody said "file foo" then attached to a PID whose executable was bar.)
5225aee162fSJim Ingham 
5235aee162fSJim Ingham         ModuleSP old_exec_module_sp = target->GetExecutableModule();
5245aee162fSJim Ingham         ArchSpec old_arch_spec = target->GetArchitecture();
5255aee162fSJim Ingham 
5265aee162fSJim Ingham         if (command.GetArgumentCount())
5275aee162fSJim Ingham         {
528fd54b368SJason Molenda             result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
5295aee162fSJim Ingham             result.SetStatus (eReturnStatusFailed);
530926af0cdSOleksiy Vyalov             return false;
53171337622SGreg Clayton         }
5325aee162fSJim Ingham 
533926af0cdSOleksiy Vyalov         m_interpreter.UpdateExecutionContext(nullptr);
53437386143SOleksiy Vyalov         StreamString stream;
53537386143SOleksiy Vyalov         const auto error = target->Attach(m_options.attach_info, &stream);
536144f3a9cSGreg Clayton         if (error.Success())
5373a0b9cdfSJim Ingham         {
53837386143SOleksiy Vyalov             ProcessSP process_sp (target->GetProcessSP());
53937386143SOleksiy Vyalov             if (process_sp)
540926af0cdSOleksiy Vyalov             {
541dc6224e0SGreg Clayton                 if (stream.GetData())
542dc6224e0SGreg Clayton                     result.AppendMessage(stream.GetData());
543bb3a283bSJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
54437386143SOleksiy Vyalov                 result.SetDidChangeProcessState (true);
545962260c8SJim Ingham                 result.SetAbnormalStopWasExpected(true);
546bb3a283bSJim Ingham             }
547aa739093SJohnny Chen             else
548aa739093SJohnny Chen             {
54937386143SOleksiy Vyalov                 result.AppendError("no error returned from Target::Attach, and target has no process");
550aa739093SJohnny Chen                 result.SetStatus (eReturnStatusFailed);
55144d93782SGreg Clayton             }
55244d93782SGreg Clayton         }
55344d93782SGreg Clayton         else
55444d93782SGreg Clayton         {
55544d93782SGreg Clayton             result.AppendErrorWithFormat ("attach failed: %s\n", error.AsCString());
55644d93782SGreg Clayton             result.SetStatus (eReturnStatusFailed);
557aa739093SJohnny Chen         }
5585aee162fSJim Ingham 
559926af0cdSOleksiy Vyalov         if (!result.Succeeded())
560926af0cdSOleksiy Vyalov             return false;
561926af0cdSOleksiy Vyalov 
5625aee162fSJim Ingham         // Okay, we're done.  Last step is to warn if the executable module has changed:
563513c26ceSGreg Clayton         char new_path[PATH_MAX];
564aa149cbdSGreg Clayton         ModuleSP new_exec_module_sp (target->GetExecutableModule());
5655aee162fSJim Ingham         if (!old_exec_module_sp)
5665aee162fSJim Ingham         {
567513c26ceSGreg Clayton             // We might not have a module if we attached to a raw pid...
568aa149cbdSGreg Clayton             if (new_exec_module_sp)
569513c26ceSGreg Clayton             {
570aa149cbdSGreg Clayton                 new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX);
571513c26ceSGreg Clayton                 result.AppendMessageWithFormat("Executable module set to \"%s\".\n", new_path);
572513c26ceSGreg Clayton             }
5735aee162fSJim Ingham         }
574aa149cbdSGreg Clayton         else if (old_exec_module_sp->GetFileSpec() != new_exec_module_sp->GetFileSpec())
5755aee162fSJim Ingham         {
576513c26ceSGreg Clayton             char old_path[PATH_MAX];
5775aee162fSJim Ingham 
5785aee162fSJim Ingham             old_exec_module_sp->GetFileSpec().GetPath (old_path, PATH_MAX);
579aa149cbdSGreg Clayton             new_exec_module_sp->GetFileSpec().GetPath (new_path, PATH_MAX);
5805aee162fSJim Ingham 
5815aee162fSJim Ingham             result.AppendWarningWithFormat("Executable module changed from \"%s\" to \"%s\".\n",
5825aee162fSJim Ingham                                                 old_path, new_path);
5835aee162fSJim Ingham         }
5845aee162fSJim Ingham 
5855aee162fSJim Ingham         if (!old_arch_spec.IsValid())
5865aee162fSJim Ingham         {
587c1b1f1eaSGreg Clayton             result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().GetTriple().getTriple().c_str());
5885aee162fSJim Ingham         }
589bf4b7be6SSean Callanan         else if (!old_arch_spec.IsExactMatch(target->GetArchitecture()))
5905aee162fSJim Ingham         {
5915aee162fSJim Ingham             result.AppendWarningWithFormat("Architecture changed from %s to %s.\n",
592c1b1f1eaSGreg Clayton                                            old_arch_spec.GetTriple().getTriple().c_str(),
593c1b1f1eaSGreg Clayton                                            target->GetArchitecture().GetTriple().getTriple().c_str());
5945aee162fSJim Ingham         }
595a95ce623SJohnny Chen 
596a95ce623SJohnny Chen         // This supports the use-case scenario of immediately continuing the process once attached.
597a95ce623SJohnny Chen         if (m_options.attach_info.GetContinueOnceAttached())
5985bcaf583SSean Callanan             m_interpreter.HandleCommand("process continue", eLazyBoolNo, result);
599926af0cdSOleksiy Vyalov 
6005aee162fSJim Ingham         return result.Succeeded();
6015aee162fSJim Ingham     }
6025aee162fSJim Ingham 
60330fdc8d8SChris Lattner     CommandOptions m_options;
60430fdc8d8SChris Lattner };
60530fdc8d8SChris Lattner 
606e0d378b3SGreg Clayton OptionDefinition
60730fdc8d8SChris Lattner CommandObjectProcessAttach::CommandOptions::g_option_table[] =
60830fdc8d8SChris Lattner {
60949bcfd80SEugene Zelenko { LLDB_OPT_SET_ALL, false, "continue",'c', OptionParser::eNoArgument,         nullptr, nullptr, 0, eArgTypeNone,         "Immediately continue the process once attached."},
61049bcfd80SEugene Zelenko { LLDB_OPT_SET_ALL, false, "plugin",  'P', OptionParser::eRequiredArgument,   nullptr, nullptr, 0, eArgTypePlugin,       "Name of the process plugin you want to use."},
61149bcfd80SEugene Zelenko { LLDB_OPT_SET_1,   false, "pid",     'p', OptionParser::eRequiredArgument,   nullptr, nullptr, 0, eArgTypePid,          "The process ID of an existing process to attach to."},
61249bcfd80SEugene Zelenko { LLDB_OPT_SET_2,   false, "name",    'n', OptionParser::eRequiredArgument,   nullptr, nullptr, 0, eArgTypeProcessName,  "The name of the process to attach to."},
61349bcfd80SEugene Zelenko { LLDB_OPT_SET_2,   false, "include-existing", 'i', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,         "Include existing processes when doing attach -w."},
61449bcfd80SEugene Zelenko { LLDB_OPT_SET_2,   false, "waitfor", 'w', OptionParser::eNoArgument,         nullptr, nullptr, 0, eArgTypeNone,         "Wait for the process with <process-name> to launch."},
61549bcfd80SEugene Zelenko { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
61630fdc8d8SChris Lattner };
61730fdc8d8SChris Lattner 
61830fdc8d8SChris Lattner //-------------------------------------------------------------------------
61930fdc8d8SChris Lattner // CommandObjectProcessContinue
62030fdc8d8SChris Lattner //-------------------------------------------------------------------------
621bb9caf73SJim Ingham #pragma mark CommandObjectProcessContinue
62230fdc8d8SChris Lattner 
6235a988416SJim Ingham class CommandObjectProcessContinue : public CommandObjectParsed
62430fdc8d8SChris Lattner {
62530fdc8d8SChris Lattner public:
626a7015092SGreg Clayton     CommandObjectProcessContinue (CommandInterpreter &interpreter) :
6275a988416SJim Ingham         CommandObjectParsed (interpreter,
628a7015092SGreg Clayton                              "process continue",
629e3d26315SCaroline Tice                              "Continue execution of all threads in the current process.",
63030fdc8d8SChris Lattner                              "process continue",
631e87764f2SEnrico Granata                              eCommandRequiresProcess       |
632e87764f2SEnrico Granata                              eCommandTryTargetAPILock      |
633e87764f2SEnrico Granata                              eCommandProcessMustBeLaunched |
634e87764f2SEnrico Granata                              eCommandProcessMustBePaused   ),
6350e41084aSJim Ingham         m_options(interpreter)
63630fdc8d8SChris Lattner     {
63730fdc8d8SChris Lattner     }
63830fdc8d8SChris Lattner 
63949bcfd80SEugene Zelenko     ~CommandObjectProcessContinue() override = default;
64030fdc8d8SChris Lattner 
6415a988416SJim Ingham protected:
6420e41084aSJim Ingham     class CommandOptions : public Options
6430e41084aSJim Ingham     {
6440e41084aSJim Ingham     public:
6450e41084aSJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
6460e41084aSJim Ingham             Options(interpreter)
6470e41084aSJim Ingham         {
6480e41084aSJim Ingham             // Keep default values of all options in one place: OptionParsingStarting ()
6490e41084aSJim Ingham             OptionParsingStarting ();
6500e41084aSJim Ingham         }
6510e41084aSJim Ingham 
65249bcfd80SEugene Zelenko         ~CommandOptions() override = default;
6530e41084aSJim Ingham 
6540e41084aSJim Ingham         Error
65513d21e9aSBruce Mitchener         SetOptionValue (uint32_t option_idx, const char *option_arg) override
6560e41084aSJim Ingham         {
6570e41084aSJim Ingham             Error error;
6583bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
6590e41084aSJim Ingham             bool success = false;
6600e41084aSJim Ingham             switch (short_option)
6610e41084aSJim Ingham             {
6620e41084aSJim Ingham                 case 'i':
6635275aaa0SVince Harron                     m_ignore = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
6640e41084aSJim Ingham                     if (!success)
6650e41084aSJim Ingham                         error.SetErrorStringWithFormat ("invalid value for ignore option: \"%s\", should be a number.", option_arg);
6660e41084aSJim Ingham                     break;
6670e41084aSJim Ingham 
6680e41084aSJim Ingham                 default:
6690e41084aSJim Ingham                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
6700e41084aSJim Ingham                     break;
6710e41084aSJim Ingham             }
6720e41084aSJim Ingham             return error;
6730e41084aSJim Ingham         }
6740e41084aSJim Ingham 
6750e41084aSJim Ingham         void
67613d21e9aSBruce Mitchener         OptionParsingStarting () override
6770e41084aSJim Ingham         {
6780e41084aSJim Ingham             m_ignore = 0;
6790e41084aSJim Ingham         }
6800e41084aSJim Ingham 
6810e41084aSJim Ingham         const OptionDefinition*
68213d21e9aSBruce Mitchener         GetDefinitions () override
6830e41084aSJim Ingham         {
6840e41084aSJim Ingham             return g_option_table;
6850e41084aSJim Ingham         }
6860e41084aSJim Ingham 
6870e41084aSJim Ingham         // Options table: Required for subclasses of Options.
6880e41084aSJim Ingham 
6890e41084aSJim Ingham         static OptionDefinition g_option_table[];
6900e41084aSJim Ingham 
6910e41084aSJim Ingham         uint32_t m_ignore;
6920e41084aSJim Ingham     };
6930e41084aSJim Ingham 
69430fdc8d8SChris Lattner     bool
69513d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
69630fdc8d8SChris Lattner     {
697f9fc609fSGreg Clayton         Process *process = m_exe_ctx.GetProcessPtr();
698a7015092SGreg Clayton         bool synchronous_execution = m_interpreter.GetSynchronous ();
69930fdc8d8SChris Lattner         StateType state = process->GetState();
70030fdc8d8SChris Lattner         if (state == eStateStopped)
70130fdc8d8SChris Lattner         {
70230fdc8d8SChris Lattner             if (command.GetArgumentCount() != 0)
70330fdc8d8SChris Lattner             {
70430fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("The '%s' command does not take any arguments.\n", m_cmd_name.c_str());
70530fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
70630fdc8d8SChris Lattner                 return false;
70730fdc8d8SChris Lattner             }
70830fdc8d8SChris Lattner 
7090e41084aSJim Ingham             if (m_options.m_ignore > 0)
7100e41084aSJim Ingham             {
7118d94ba0fSJim Ingham                 ThreadSP sel_thread_sp(GetDefaultThread()->shared_from_this());
7120e41084aSJim Ingham                 if (sel_thread_sp)
7130e41084aSJim Ingham                 {
7140e41084aSJim Ingham                     StopInfoSP stop_info_sp = sel_thread_sp->GetStopInfo();
7150e41084aSJim Ingham                     if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonBreakpoint)
7160e41084aSJim Ingham                     {
717c7bece56SGreg Clayton                         lldb::break_id_t bp_site_id = (lldb::break_id_t)stop_info_sp->GetValue();
7180e41084aSJim Ingham                         BreakpointSiteSP bp_site_sp(process->GetBreakpointSiteList().FindByID(bp_site_id));
7190e41084aSJim Ingham                         if (bp_site_sp)
7200e41084aSJim Ingham                         {
721c7bece56SGreg Clayton                             const size_t num_owners = bp_site_sp->GetNumberOfOwners();
722c7bece56SGreg Clayton                             for (size_t i = 0; i < num_owners; i++)
7230e41084aSJim Ingham                             {
7240e41084aSJim Ingham                                 Breakpoint &bp_ref = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
7250e41084aSJim Ingham                                 if (!bp_ref.IsInternal())
7260e41084aSJim Ingham                                 {
7270e41084aSJim Ingham                                     bp_ref.SetIgnoreCount(m_options.m_ignore);
7280e41084aSJim Ingham                                 }
7290e41084aSJim Ingham                             }
7300e41084aSJim Ingham                         }
7310e41084aSJim Ingham                     }
7320e41084aSJim Ingham                 }
7330e41084aSJim Ingham             }
7340e41084aSJim Ingham 
73541f2b940SJim Ingham             {  // Scope for thread list mutex:
736bb19a13cSSaleem Abdulrasool                 std::lock_guard<std::recursive_mutex> guard(process->GetThreadList().GetMutex());
73730fdc8d8SChris Lattner                 const uint32_t num_threads = process->GetThreadList().GetSize();
73830fdc8d8SChris Lattner 
73930fdc8d8SChris Lattner                 // Set the actions that the threads should each take when resuming
74030fdc8d8SChris Lattner                 for (uint32_t idx=0; idx<num_threads; ++idx)
74130fdc8d8SChris Lattner                 {
7426c9ed91cSJim Ingham                     const bool override_suspend = false;
7436c9ed91cSJim Ingham                     process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState (eStateRunning, override_suspend);
74430fdc8d8SChris Lattner                 }
74541f2b940SJim Ingham             }
74630fdc8d8SChris Lattner 
7474446487dSPavel Labath             const uint32_t iohandler_id = process->GetIOHandlerID();
7484446487dSPavel Labath 
749dc6224e0SGreg Clayton             StreamString stream;
750dc6224e0SGreg Clayton             Error error;
751dc6224e0SGreg Clayton             if (synchronous_execution)
752dc6224e0SGreg Clayton                 error = process->ResumeSynchronous (&stream);
753dc6224e0SGreg Clayton             else
754dc6224e0SGreg Clayton                 error = process->Resume ();
755a3b89e27STodd Fiala 
75630fdc8d8SChris Lattner             if (error.Success())
75730fdc8d8SChris Lattner             {
758a3b89e27STodd Fiala                 // There is a race condition where this thread will return up the call stack to the main command
759a3b89e27STodd Fiala                  // handler and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has
760a3b89e27STodd Fiala                  // a chance to call PushProcessIOHandler().
7614446487dSPavel Labath                 process->SyncIOHandler(iohandler_id, 2000);
762a3b89e27STodd Fiala 
763d01b2953SDaniel Malea                 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
76430fdc8d8SChris Lattner                 if (synchronous_execution)
76530fdc8d8SChris Lattner                 {
766dc6224e0SGreg Clayton                     // If any state changed events had anything to say, add that to the result
767dc6224e0SGreg Clayton                     if (stream.GetData())
768dc6224e0SGreg Clayton                         result.AppendMessage(stream.GetData());
76930fdc8d8SChris Lattner 
77030fdc8d8SChris Lattner                     result.SetDidChangeProcessState (true);
77130fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
77230fdc8d8SChris Lattner                 }
77330fdc8d8SChris Lattner                 else
77430fdc8d8SChris Lattner                 {
77530fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusSuccessContinuingNoResult);
77630fdc8d8SChris Lattner                 }
77730fdc8d8SChris Lattner             }
77830fdc8d8SChris Lattner             else
77930fdc8d8SChris Lattner             {
78030fdc8d8SChris Lattner                 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
78130fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
78230fdc8d8SChris Lattner             }
78330fdc8d8SChris Lattner         }
78430fdc8d8SChris Lattner         else
78530fdc8d8SChris Lattner         {
78630fdc8d8SChris Lattner             result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
78730fdc8d8SChris Lattner                                          StateAsCString(state));
78830fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
78930fdc8d8SChris Lattner         }
79030fdc8d8SChris Lattner         return result.Succeeded();
79130fdc8d8SChris Lattner     }
7920e41084aSJim Ingham 
7930e41084aSJim Ingham     Options *
79413d21e9aSBruce Mitchener     GetOptions () override
7950e41084aSJim Ingham     {
7960e41084aSJim Ingham         return &m_options;
7970e41084aSJim Ingham     }
7980e41084aSJim Ingham 
7990e41084aSJim Ingham     CommandOptions m_options;
8000e41084aSJim Ingham };
8010e41084aSJim Ingham 
8020e41084aSJim Ingham OptionDefinition
8030e41084aSJim Ingham CommandObjectProcessContinue::CommandOptions::g_option_table[] =
8040e41084aSJim Ingham {
80549bcfd80SEugene Zelenko { LLDB_OPT_SET_ALL, false, "ignore-count",'i', OptionParser::eRequiredArgument,         nullptr, nullptr, 0, eArgTypeUnsignedInteger,
8060e41084aSJim Ingham                            "Ignore <N> crossings of the breakpoint (if it exists) for the currently selected thread."},
80749bcfd80SEugene Zelenko { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
80830fdc8d8SChris Lattner };
80930fdc8d8SChris Lattner 
81030fdc8d8SChris Lattner //-------------------------------------------------------------------------
81130fdc8d8SChris Lattner // CommandObjectProcessDetach
81230fdc8d8SChris Lattner //-------------------------------------------------------------------------
813bb9caf73SJim Ingham #pragma mark CommandObjectProcessDetach
81430fdc8d8SChris Lattner 
8155a988416SJim Ingham class CommandObjectProcessDetach : public CommandObjectParsed
81630fdc8d8SChris Lattner {
81730fdc8d8SChris Lattner public:
818acff8950SJim Ingham     class CommandOptions : public Options
819acff8950SJim Ingham     {
820acff8950SJim Ingham     public:
821acff8950SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
822acff8950SJim Ingham             Options (interpreter)
823acff8950SJim Ingham         {
824acff8950SJim Ingham             OptionParsingStarting ();
825acff8950SJim Ingham         }
826acff8950SJim Ingham 
82749bcfd80SEugene Zelenko         ~CommandOptions() override = default;
828acff8950SJim Ingham 
829acff8950SJim Ingham         Error
83013d21e9aSBruce Mitchener         SetOptionValue (uint32_t option_idx, const char *option_arg) override
831acff8950SJim Ingham         {
832acff8950SJim Ingham             Error error;
833acff8950SJim Ingham             const int short_option = m_getopt_table[option_idx].val;
834acff8950SJim Ingham 
835acff8950SJim Ingham             switch (short_option)
836acff8950SJim Ingham             {
837acff8950SJim Ingham                 case 's':
838acff8950SJim Ingham                     bool tmp_result;
839acff8950SJim Ingham                     bool success;
840acff8950SJim Ingham                     tmp_result = Args::StringToBoolean(option_arg, false, &success);
841acff8950SJim Ingham                     if (!success)
842acff8950SJim Ingham                         error.SetErrorStringWithFormat("invalid boolean option: \"%s\"", option_arg);
843acff8950SJim Ingham                     else
844acff8950SJim Ingham                     {
845acff8950SJim Ingham                         if (tmp_result)
846acff8950SJim Ingham                             m_keep_stopped = eLazyBoolYes;
847acff8950SJim Ingham                         else
848acff8950SJim Ingham                             m_keep_stopped = eLazyBoolNo;
849acff8950SJim Ingham                     }
850acff8950SJim Ingham                     break;
851acff8950SJim Ingham                 default:
852acff8950SJim Ingham                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
853acff8950SJim Ingham                     break;
854acff8950SJim Ingham             }
855acff8950SJim Ingham             return error;
856acff8950SJim Ingham         }
857acff8950SJim Ingham 
858acff8950SJim Ingham         void
85913d21e9aSBruce Mitchener         OptionParsingStarting () override
860acff8950SJim Ingham         {
861acff8950SJim Ingham             m_keep_stopped = eLazyBoolCalculate;
862acff8950SJim Ingham         }
863acff8950SJim Ingham 
864acff8950SJim Ingham         const OptionDefinition*
86513d21e9aSBruce Mitchener         GetDefinitions () override
866acff8950SJim Ingham         {
867acff8950SJim Ingham             return g_option_table;
868acff8950SJim Ingham         }
869acff8950SJim Ingham 
870acff8950SJim Ingham         // Options table: Required for subclasses of Options.
871acff8950SJim Ingham 
872acff8950SJim Ingham         static OptionDefinition g_option_table[];
873acff8950SJim Ingham 
874acff8950SJim Ingham         // Instance variables to hold the values for command options.
875acff8950SJim Ingham         LazyBool m_keep_stopped;
876acff8950SJim Ingham     };
87730fdc8d8SChris Lattner 
878*7428a18cSKate Stone     CommandObjectProcessDetach(CommandInterpreter &interpreter)
879*7428a18cSKate Stone         : CommandObjectParsed(interpreter, "process detach", "Detach from the current target process.",
880a7015092SGreg Clayton                               "process detach",
881*7428a18cSKate Stone                               eCommandRequiresProcess | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched),
882acff8950SJim Ingham           m_options(interpreter)
88330fdc8d8SChris Lattner     {
88430fdc8d8SChris Lattner     }
88530fdc8d8SChris Lattner 
88649bcfd80SEugene Zelenko     ~CommandObjectProcessDetach() override = default;
88730fdc8d8SChris Lattner 
888acff8950SJim Ingham     Options *
88913d21e9aSBruce Mitchener     GetOptions () override
890acff8950SJim Ingham     {
891acff8950SJim Ingham         return &m_options;
892acff8950SJim Ingham     }
893acff8950SJim Ingham 
8945a988416SJim Ingham protected:
89530fdc8d8SChris Lattner     bool
89613d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
89730fdc8d8SChris Lattner     {
898f9fc609fSGreg Clayton         Process *process = m_exe_ctx.GetProcessPtr();
899acff8950SJim Ingham         // FIXME: This will be a Command Option:
900acff8950SJim Ingham         bool keep_stopped;
901acff8950SJim Ingham         if (m_options.m_keep_stopped == eLazyBoolCalculate)
902acff8950SJim Ingham         {
903acff8950SJim Ingham             // Check the process default:
90449bcfd80SEugene Zelenko             keep_stopped = process->GetDetachKeepsStopped();
905acff8950SJim Ingham         }
906acff8950SJim Ingham         else if (m_options.m_keep_stopped == eLazyBoolYes)
907acff8950SJim Ingham             keep_stopped = true;
908acff8950SJim Ingham         else
909acff8950SJim Ingham             keep_stopped = false;
910acff8950SJim Ingham 
911acff8950SJim Ingham         Error error (process->Detach(keep_stopped));
91230fdc8d8SChris Lattner         if (error.Success())
91330fdc8d8SChris Lattner         {
91430fdc8d8SChris Lattner             result.SetStatus (eReturnStatusSuccessFinishResult);
91530fdc8d8SChris Lattner         }
91630fdc8d8SChris Lattner         else
91730fdc8d8SChris Lattner         {
91830fdc8d8SChris Lattner             result.AppendErrorWithFormat ("Detach failed: %s\n", error.AsCString());
91930fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
92030fdc8d8SChris Lattner             return false;
92130fdc8d8SChris Lattner         }
92230fdc8d8SChris Lattner         return result.Succeeded();
92330fdc8d8SChris Lattner     }
924acff8950SJim Ingham 
925acff8950SJim Ingham     CommandOptions m_options;
926acff8950SJim Ingham };
927acff8950SJim Ingham 
928acff8950SJim Ingham OptionDefinition
929acff8950SJim Ingham CommandObjectProcessDetach::CommandOptions::g_option_table[] =
930acff8950SJim Ingham {
93149bcfd80SEugene Zelenko { 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)." },
93249bcfd80SEugene Zelenko { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
93330fdc8d8SChris Lattner };
93430fdc8d8SChris Lattner 
93530fdc8d8SChris Lattner //-------------------------------------------------------------------------
936b766a73dSGreg Clayton // CommandObjectProcessConnect
937b766a73dSGreg Clayton //-------------------------------------------------------------------------
938b766a73dSGreg Clayton #pragma mark CommandObjectProcessConnect
939b766a73dSGreg Clayton 
9405a988416SJim Ingham class CommandObjectProcessConnect : public CommandObjectParsed
941b766a73dSGreg Clayton {
942b766a73dSGreg Clayton public:
943b766a73dSGreg Clayton     class CommandOptions : public Options
944b766a73dSGreg Clayton     {
945b766a73dSGreg Clayton     public:
946eb0103f2SGreg Clayton         CommandOptions (CommandInterpreter &interpreter) :
947eb0103f2SGreg Clayton             Options(interpreter)
948b766a73dSGreg Clayton         {
949f6b8b581SGreg Clayton             // Keep default values of all options in one place: OptionParsingStarting ()
950f6b8b581SGreg Clayton             OptionParsingStarting ();
951b766a73dSGreg Clayton         }
952b766a73dSGreg Clayton 
95349bcfd80SEugene Zelenko         ~CommandOptions() override = default;
954b766a73dSGreg Clayton 
955b766a73dSGreg Clayton         Error
95613d21e9aSBruce Mitchener         SetOptionValue (uint32_t option_idx, const char *option_arg) override
957b766a73dSGreg Clayton         {
958b766a73dSGreg Clayton             Error error;
9593bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
960b766a73dSGreg Clayton 
961b766a73dSGreg Clayton             switch (short_option)
962b766a73dSGreg Clayton             {
963b766a73dSGreg Clayton             case 'p':
964b766a73dSGreg Clayton                 plugin_name.assign (option_arg);
965b766a73dSGreg Clayton                 break;
966b766a73dSGreg Clayton 
967b766a73dSGreg Clayton             default:
96886edbf41SGreg Clayton                 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
969b766a73dSGreg Clayton                 break;
970b766a73dSGreg Clayton             }
971b766a73dSGreg Clayton             return error;
972b766a73dSGreg Clayton         }
973b766a73dSGreg Clayton 
974b766a73dSGreg Clayton         void
97513d21e9aSBruce Mitchener         OptionParsingStarting () override
976b766a73dSGreg Clayton         {
977b766a73dSGreg Clayton             plugin_name.clear();
978b766a73dSGreg Clayton         }
979b766a73dSGreg Clayton 
980e0d378b3SGreg Clayton         const OptionDefinition*
98113d21e9aSBruce Mitchener         GetDefinitions () override
982b766a73dSGreg Clayton         {
983b766a73dSGreg Clayton             return g_option_table;
984b766a73dSGreg Clayton         }
985b766a73dSGreg Clayton 
986b766a73dSGreg Clayton         // Options table: Required for subclasses of Options.
987b766a73dSGreg Clayton 
988e0d378b3SGreg Clayton         static OptionDefinition g_option_table[];
989b766a73dSGreg Clayton 
990b766a73dSGreg Clayton         // Instance variables to hold the values for command options.
991b766a73dSGreg Clayton 
992b766a73dSGreg Clayton         std::string plugin_name;
993b766a73dSGreg Clayton     };
994b766a73dSGreg Clayton 
995b766a73dSGreg Clayton     CommandObjectProcessConnect (CommandInterpreter &interpreter) :
9965a988416SJim Ingham         CommandObjectParsed (interpreter,
997b766a73dSGreg Clayton                              "process connect",
998b766a73dSGreg Clayton                              "Connect to a remote debug service.",
999b766a73dSGreg Clayton                              "process connect <remote-url>",
1000eb0103f2SGreg Clayton                              0),
1001eb0103f2SGreg Clayton         m_options (interpreter)
1002b766a73dSGreg Clayton     {
1003b766a73dSGreg Clayton     }
1004b766a73dSGreg Clayton 
100549bcfd80SEugene Zelenko     ~CommandObjectProcessConnect() override = default;
1006b766a73dSGreg Clayton 
10075a988416SJim Ingham     Options *
100813d21e9aSBruce Mitchener     GetOptions () override
10095a988416SJim Ingham     {
10105a988416SJim Ingham         return &m_options;
10115a988416SJim Ingham     }
10125a988416SJim Ingham 
10135a988416SJim Ingham protected:
1014b766a73dSGreg Clayton     bool
101513d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
1016b766a73dSGreg Clayton     {
1017ccd6cffbSTamas Berghammer         if (command.GetArgumentCount() != 1)
1018b766a73dSGreg Clayton         {
1019ccd6cffbSTamas Berghammer             result.AppendErrorWithFormat ("'%s' takes exactly one argument:\nUsage: %s\n",
1020ccd6cffbSTamas Berghammer                                           m_cmd_name.c_str(),
1021ccd6cffbSTamas Berghammer                                           m_cmd_syntax.c_str());
1022ccd6cffbSTamas Berghammer             result.SetStatus (eReturnStatusFailed);
1023ccd6cffbSTamas Berghammer             return false;
1024ccd6cffbSTamas Berghammer         }
1025ccd6cffbSTamas Berghammer 
1026ccd6cffbSTamas Berghammer         Process *process = m_exe_ctx.GetProcessPtr();
1027ccd6cffbSTamas Berghammer         if (process && process->IsAlive())
1028b766a73dSGreg Clayton         {
1029d01b2953SDaniel Malea             result.AppendErrorWithFormat ("Process %" PRIu64 " is currently being debugged, kill the process before connecting.\n",
1030b766a73dSGreg Clayton                                           process->GetID());
1031b766a73dSGreg Clayton             result.SetStatus (eReturnStatusFailed);
1032b766a73dSGreg Clayton             return false;
1033b766a73dSGreg Clayton         }
1034b766a73dSGreg Clayton 
1035ccd6cffbSTamas Berghammer         const char *plugin_name = nullptr;
1036b766a73dSGreg Clayton         if (!m_options.plugin_name.empty())
1037b766a73dSGreg Clayton             plugin_name = m_options.plugin_name.c_str();
1038b766a73dSGreg Clayton 
1039ccd6cffbSTamas Berghammer         Error error;
1040ccd6cffbSTamas Berghammer         Debugger& debugger = m_interpreter.GetDebugger();
1041ccd6cffbSTamas Berghammer         PlatformSP platform_sp = m_interpreter.GetPlatform(true);
1042ccd6cffbSTamas Berghammer         ProcessSP process_sp = platform_sp->ConnectProcess(command.GetArgumentAtIndex(0),
1043ccd6cffbSTamas Berghammer                                                            plugin_name,
1044ccd6cffbSTamas Berghammer                                                            debugger,
1045ccd6cffbSTamas Berghammer                                                            debugger.GetSelectedTarget().get(),
1046ccd6cffbSTamas Berghammer                                                            error);
1047ccd6cffbSTamas Berghammer         if (error.Fail() || process_sp == nullptr)
1048b766a73dSGreg Clayton         {
1049ccd6cffbSTamas Berghammer             result.AppendError(error.AsCString("Error connecting to the process"));
1050b766a73dSGreg Clayton             result.SetStatus (eReturnStatusFailed);
1051b766a73dSGreg Clayton             return false;
1052b766a73dSGreg Clayton         }
1053ccd6cffbSTamas Berghammer         return true;
1054b766a73dSGreg Clayton     }
1055b766a73dSGreg Clayton 
1056b766a73dSGreg Clayton     CommandOptions m_options;
1057b766a73dSGreg Clayton };
1058b766a73dSGreg Clayton 
1059e0d378b3SGreg Clayton OptionDefinition
1060b766a73dSGreg Clayton CommandObjectProcessConnect::CommandOptions::g_option_table[] =
1061b766a73dSGreg Clayton {
106249bcfd80SEugene Zelenko     { LLDB_OPT_SET_ALL, false, "plugin", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePlugin, "Name of the process plugin you want to use."},
106349bcfd80SEugene Zelenko     { 0,                false, nullptr,      0 , 0,                 nullptr, nullptr, 0, eArgTypeNone,   nullptr }
1064b766a73dSGreg Clayton };
1065b766a73dSGreg Clayton 
1066b766a73dSGreg Clayton //-------------------------------------------------------------------------
1067998255bfSGreg Clayton // CommandObjectProcessPlugin
1068998255bfSGreg Clayton //-------------------------------------------------------------------------
1069998255bfSGreg Clayton #pragma mark CommandObjectProcessPlugin
1070998255bfSGreg Clayton 
1071998255bfSGreg Clayton class CommandObjectProcessPlugin : public CommandObjectProxy
1072998255bfSGreg Clayton {
1073998255bfSGreg Clayton public:
1074*7428a18cSKate Stone     CommandObjectProcessPlugin(CommandInterpreter &interpreter)
1075*7428a18cSKate Stone         : CommandObjectProxy(interpreter, "process plugin",
1076*7428a18cSKate Stone                              "Send a custom command to the current target process plug-in.", "process plugin <args>", 0)
1077998255bfSGreg Clayton     {
1078998255bfSGreg Clayton     }
1079998255bfSGreg Clayton 
108049bcfd80SEugene Zelenko     ~CommandObjectProcessPlugin() override = default;
1081998255bfSGreg Clayton 
108213d21e9aSBruce Mitchener     CommandObject *
108313d21e9aSBruce Mitchener     GetProxyCommandObject() override
1084998255bfSGreg Clayton     {
1085e05b2efeSGreg Clayton         Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
1086998255bfSGreg Clayton         if (process)
1087998255bfSGreg Clayton             return process->GetPluginCommandObject();
108849bcfd80SEugene Zelenko         return nullptr;
1089998255bfSGreg Clayton     }
1090998255bfSGreg Clayton };
1091998255bfSGreg Clayton 
1092998255bfSGreg Clayton //-------------------------------------------------------------------------
10938f343b09SGreg Clayton // CommandObjectProcessLoad
10948f343b09SGreg Clayton //-------------------------------------------------------------------------
1095bb9caf73SJim Ingham #pragma mark CommandObjectProcessLoad
10968f343b09SGreg Clayton 
10975a988416SJim Ingham class CommandObjectProcessLoad : public CommandObjectParsed
10988f343b09SGreg Clayton {
10998f343b09SGreg Clayton public:
11004fbd67acSTamas Berghammer     class CommandOptions : public Options
11014fbd67acSTamas Berghammer     {
11024fbd67acSTamas Berghammer     public:
11034fbd67acSTamas Berghammer         CommandOptions (CommandInterpreter &interpreter) :
11044fbd67acSTamas Berghammer             Options(interpreter)
11054fbd67acSTamas Berghammer         {
11064fbd67acSTamas Berghammer             // Keep default values of all options in one place: OptionParsingStarting ()
11074fbd67acSTamas Berghammer             OptionParsingStarting ();
11084fbd67acSTamas Berghammer         }
11094fbd67acSTamas Berghammer 
11104fbd67acSTamas Berghammer         ~CommandOptions() override = default;
11114fbd67acSTamas Berghammer 
11124fbd67acSTamas Berghammer         Error
11134fbd67acSTamas Berghammer         SetOptionValue (uint32_t option_idx, const char *option_arg) override
11144fbd67acSTamas Berghammer         {
11154fbd67acSTamas Berghammer             Error error;
11164fbd67acSTamas Berghammer             const int short_option = m_getopt_table[option_idx].val;
11174fbd67acSTamas Berghammer             switch (short_option)
11184fbd67acSTamas Berghammer             {
11194fbd67acSTamas Berghammer             case 'i':
11204fbd67acSTamas Berghammer                 do_install = true;
11214fbd67acSTamas Berghammer                 if (option_arg && option_arg[0])
11224fbd67acSTamas Berghammer                     install_path.SetFile(option_arg, false);
11234fbd67acSTamas Berghammer                 break;
11244fbd67acSTamas Berghammer             default:
11254fbd67acSTamas Berghammer                 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
11264fbd67acSTamas Berghammer                 break;
11274fbd67acSTamas Berghammer             }
11284fbd67acSTamas Berghammer             return error;
11294fbd67acSTamas Berghammer         }
11304fbd67acSTamas Berghammer 
11314fbd67acSTamas Berghammer         void
11324fbd67acSTamas Berghammer         OptionParsingStarting () override
11334fbd67acSTamas Berghammer         {
11344fbd67acSTamas Berghammer             do_install = false;
11354fbd67acSTamas Berghammer             install_path.Clear();
11364fbd67acSTamas Berghammer         }
11374fbd67acSTamas Berghammer 
11384fbd67acSTamas Berghammer         const OptionDefinition*
11394fbd67acSTamas Berghammer         GetDefinitions () override
11404fbd67acSTamas Berghammer         {
11414fbd67acSTamas Berghammer             return g_option_table;
11424fbd67acSTamas Berghammer         }
11434fbd67acSTamas Berghammer 
11444fbd67acSTamas Berghammer         // Options table: Required for subclasses of Options.
11454fbd67acSTamas Berghammer         static OptionDefinition g_option_table[];
11464fbd67acSTamas Berghammer 
11474fbd67acSTamas Berghammer         // Instance variables to hold the values for command options.
11484fbd67acSTamas Berghammer         bool do_install;
11494fbd67acSTamas Berghammer         FileSpec install_path;
11504fbd67acSTamas Berghammer     };
11518f343b09SGreg Clayton 
11528f343b09SGreg Clayton     CommandObjectProcessLoad (CommandInterpreter &interpreter) :
11535a988416SJim Ingham         CommandObjectParsed (interpreter,
11548f343b09SGreg Clayton                              "process load",
11558f343b09SGreg Clayton                              "Load a shared library into the current process.",
11568f343b09SGreg Clayton                              "process load <filename> [<filename> ...]",
1157e87764f2SEnrico Granata                              eCommandRequiresProcess       |
1158e87764f2SEnrico Granata                              eCommandTryTargetAPILock      |
1159e87764f2SEnrico Granata                              eCommandProcessMustBeLaunched |
11604fbd67acSTamas Berghammer                              eCommandProcessMustBePaused   ),
11614fbd67acSTamas Berghammer         m_options (interpreter)
11628f343b09SGreg Clayton     {
11638f343b09SGreg Clayton     }
11648f343b09SGreg Clayton 
11654fbd67acSTamas Berghammer     ~CommandObjectProcessLoad() override = default;
11664fbd67acSTamas Berghammer 
11674fbd67acSTamas Berghammer     Options *
11684fbd67acSTamas Berghammer     GetOptions () override
11698f343b09SGreg Clayton     {
11704fbd67acSTamas Berghammer         return &m_options;
11718f343b09SGreg Clayton     }
11728f343b09SGreg Clayton 
11735a988416SJim Ingham protected:
11748f343b09SGreg Clayton     bool
117513d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
11768f343b09SGreg Clayton     {
1177f9fc609fSGreg Clayton         Process *process = m_exe_ctx.GetProcessPtr();
11788f343b09SGreg Clayton 
1179c7bece56SGreg Clayton         const size_t argc = command.GetArgumentCount();
11808f343b09SGreg Clayton         for (uint32_t i = 0; i < argc; ++i)
11818f343b09SGreg Clayton         {
11828f343b09SGreg Clayton             Error error;
11833cb132a0STamas Berghammer             PlatformSP platform = process->GetTarget().GetPlatform();
11844fbd67acSTamas Berghammer             const char *image_path = command.GetArgumentAtIndex(i);
11854fbd67acSTamas Berghammer             uint32_t image_token = LLDB_INVALID_IMAGE_TOKEN;
11864fbd67acSTamas Berghammer 
11874fbd67acSTamas Berghammer             if (!m_options.do_install)
11884fbd67acSTamas Berghammer             {
11894fbd67acSTamas Berghammer                 FileSpec image_spec (image_path, false);
11903cb132a0STamas Berghammer                 platform->ResolveRemotePath(image_spec, image_spec);
11914fbd67acSTamas Berghammer                 image_token = platform->LoadImage(process, FileSpec(), image_spec, error);
11924fbd67acSTamas Berghammer             }
11934fbd67acSTamas Berghammer             else if (m_options.install_path)
11944fbd67acSTamas Berghammer             {
11954fbd67acSTamas Berghammer                 FileSpec image_spec (image_path, true);
11964fbd67acSTamas Berghammer                 platform->ResolveRemotePath(m_options.install_path, m_options.install_path);
11974fbd67acSTamas Berghammer                 image_token = platform->LoadImage(process, image_spec, m_options.install_path, error);
11984fbd67acSTamas Berghammer             }
11994fbd67acSTamas Berghammer             else
12004fbd67acSTamas Berghammer             {
12014fbd67acSTamas Berghammer                 FileSpec image_spec (image_path, true);
12024fbd67acSTamas Berghammer                 image_token = platform->LoadImage(process, image_spec, FileSpec(), error);
12034fbd67acSTamas Berghammer             }
12044fbd67acSTamas Berghammer 
12058f343b09SGreg Clayton             if (image_token != LLDB_INVALID_IMAGE_TOKEN)
12068f343b09SGreg Clayton             {
12078f343b09SGreg Clayton                 result.AppendMessageWithFormat ("Loading \"%s\"...ok\nImage %u loaded.\n", image_path, image_token);
12088f343b09SGreg Clayton                 result.SetStatus (eReturnStatusSuccessFinishResult);
12098f343b09SGreg Clayton             }
12108f343b09SGreg Clayton             else
12118f343b09SGreg Clayton             {
12128f343b09SGreg Clayton                 result.AppendErrorWithFormat ("failed to load '%s': %s", image_path, error.AsCString());
12138f343b09SGreg Clayton                 result.SetStatus (eReturnStatusFailed);
12148f343b09SGreg Clayton             }
12158f343b09SGreg Clayton         }
12168f343b09SGreg Clayton         return result.Succeeded();
12178f343b09SGreg Clayton     }
12184fbd67acSTamas Berghammer 
12194fbd67acSTamas Berghammer     CommandOptions m_options;
12208f343b09SGreg Clayton };
12218f343b09SGreg Clayton 
12224fbd67acSTamas Berghammer OptionDefinition
12234fbd67acSTamas Berghammer CommandObjectProcessLoad::CommandOptions::g_option_table[] =
12244fbd67acSTamas Berghammer {
12254fbd67acSTamas Berghammer     { 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."},
12264fbd67acSTamas Berghammer     { 0,                false, nullptr,    0 , 0,                               nullptr, nullptr, 0, eArgTypeNone, nullptr }
12274fbd67acSTamas Berghammer };
12288f343b09SGreg Clayton 
12298f343b09SGreg Clayton //-------------------------------------------------------------------------
12308f343b09SGreg Clayton // CommandObjectProcessUnload
12318f343b09SGreg Clayton //-------------------------------------------------------------------------
1232bb9caf73SJim Ingham #pragma mark CommandObjectProcessUnload
12338f343b09SGreg Clayton 
12345a988416SJim Ingham class CommandObjectProcessUnload : public CommandObjectParsed
12358f343b09SGreg Clayton {
12368f343b09SGreg Clayton public:
12378f343b09SGreg Clayton 
12388f343b09SGreg Clayton     CommandObjectProcessUnload (CommandInterpreter &interpreter) :
12395a988416SJim Ingham         CommandObjectParsed (interpreter,
12408f343b09SGreg Clayton                              "process unload",
12418f343b09SGreg Clayton                              "Unload a shared library from the current process using the index returned by a previous call to \"process load\".",
12428f343b09SGreg Clayton                              "process unload <index>",
1243e87764f2SEnrico Granata                              eCommandRequiresProcess       |
1244e87764f2SEnrico Granata                              eCommandTryTargetAPILock      |
1245e87764f2SEnrico Granata                              eCommandProcessMustBeLaunched |
1246e87764f2SEnrico Granata                              eCommandProcessMustBePaused   )
12478f343b09SGreg Clayton     {
12488f343b09SGreg Clayton     }
12498f343b09SGreg Clayton 
125049bcfd80SEugene Zelenko     ~CommandObjectProcessUnload() override = default;
12518f343b09SGreg Clayton 
12525a988416SJim Ingham protected:
12538f343b09SGreg Clayton     bool
125413d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
12558f343b09SGreg Clayton     {
1256f9fc609fSGreg Clayton         Process *process = m_exe_ctx.GetProcessPtr();
12578f343b09SGreg Clayton 
1258c7bece56SGreg Clayton         const size_t argc = command.GetArgumentCount();
12598f343b09SGreg Clayton 
12608f343b09SGreg Clayton         for (uint32_t i = 0; i < argc; ++i)
12618f343b09SGreg Clayton         {
12628f343b09SGreg Clayton             const char *image_token_cstr = command.GetArgumentAtIndex(i);
12635275aaa0SVince Harron             uint32_t image_token = StringConvert::ToUInt32(image_token_cstr, LLDB_INVALID_IMAGE_TOKEN, 0);
12648f343b09SGreg Clayton             if (image_token == LLDB_INVALID_IMAGE_TOKEN)
12658f343b09SGreg Clayton             {
12668f343b09SGreg Clayton                 result.AppendErrorWithFormat ("invalid image index argument '%s'", image_token_cstr);
12678f343b09SGreg Clayton                 result.SetStatus (eReturnStatusFailed);
12688f343b09SGreg Clayton                 break;
12698f343b09SGreg Clayton             }
12708f343b09SGreg Clayton             else
12718f343b09SGreg Clayton             {
12723cb132a0STamas Berghammer                 Error error (process->GetTarget().GetPlatform()->UnloadImage(process, image_token));
12738f343b09SGreg Clayton                 if (error.Success())
12748f343b09SGreg Clayton                 {
12758f343b09SGreg Clayton                     result.AppendMessageWithFormat ("Unloading shared library with index %u...ok\n", image_token);
12768f343b09SGreg Clayton                     result.SetStatus (eReturnStatusSuccessFinishResult);
12778f343b09SGreg Clayton                 }
12788f343b09SGreg Clayton                 else
12798f343b09SGreg Clayton                 {
12808f343b09SGreg Clayton                     result.AppendErrorWithFormat ("failed to unload image: %s", error.AsCString());
12818f343b09SGreg Clayton                     result.SetStatus (eReturnStatusFailed);
12828f343b09SGreg Clayton                     break;
12838f343b09SGreg Clayton                 }
12848f343b09SGreg Clayton             }
12858f343b09SGreg Clayton         }
12868f343b09SGreg Clayton         return result.Succeeded();
12878f343b09SGreg Clayton     }
12888f343b09SGreg Clayton };
12898f343b09SGreg Clayton 
12908f343b09SGreg Clayton //-------------------------------------------------------------------------
129130fdc8d8SChris Lattner // CommandObjectProcessSignal
129230fdc8d8SChris Lattner //-------------------------------------------------------------------------
1293bb9caf73SJim Ingham #pragma mark CommandObjectProcessSignal
129430fdc8d8SChris Lattner 
12955a988416SJim Ingham class CommandObjectProcessSignal : public CommandObjectParsed
129630fdc8d8SChris Lattner {
129730fdc8d8SChris Lattner public:
1298*7428a18cSKate Stone     CommandObjectProcessSignal(CommandInterpreter &interpreter)
1299*7428a18cSKate Stone         : CommandObjectParsed(interpreter, "process signal", "Send a UNIX signal to the current target process.",
1300*7428a18cSKate Stone                               nullptr, eCommandRequiresProcess | eCommandTryTargetAPILock)
130130fdc8d8SChris Lattner     {
1302405fe67fSCaroline Tice         CommandArgumentEntry arg;
1303405fe67fSCaroline Tice         CommandArgumentData signal_arg;
1304405fe67fSCaroline Tice 
1305405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
1306c0dbdfb6SCaroline Tice         signal_arg.arg_type = eArgTypeUnixSignal;
1307405fe67fSCaroline Tice         signal_arg.arg_repetition = eArgRepeatPlain;
1308405fe67fSCaroline Tice 
1309405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
1310405fe67fSCaroline Tice         arg.push_back (signal_arg);
1311405fe67fSCaroline Tice 
1312405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
1313405fe67fSCaroline Tice         m_arguments.push_back (arg);
131430fdc8d8SChris Lattner     }
131530fdc8d8SChris Lattner 
131649bcfd80SEugene Zelenko     ~CommandObjectProcessSignal() override = default;
131730fdc8d8SChris Lattner 
13185a988416SJim Ingham protected:
131930fdc8d8SChris Lattner     bool
132013d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
132130fdc8d8SChris Lattner     {
1322f9fc609fSGreg Clayton         Process *process = m_exe_ctx.GetProcessPtr();
132330fdc8d8SChris Lattner 
132430fdc8d8SChris Lattner         if (command.GetArgumentCount() == 1)
132530fdc8d8SChris Lattner         {
1326237cd906SGreg Clayton             int signo = LLDB_INVALID_SIGNAL_NUMBER;
1327237cd906SGreg Clayton 
1328237cd906SGreg Clayton             const char *signal_name = command.GetArgumentAtIndex(0);
1329237cd906SGreg Clayton             if (::isxdigit (signal_name[0]))
13305275aaa0SVince Harron                 signo = StringConvert::ToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0);
1331237cd906SGreg Clayton             else
133298d0a4b3SChaoren Lin                 signo = process->GetUnixSignals()->GetSignalNumberFromName(signal_name);
1333237cd906SGreg Clayton 
1334237cd906SGreg Clayton             if (signo == LLDB_INVALID_SIGNAL_NUMBER)
133530fdc8d8SChris Lattner             {
133630fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("Invalid signal argument '%s'.\n", command.GetArgumentAtIndex(0));
133730fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
133830fdc8d8SChris Lattner             }
133930fdc8d8SChris Lattner             else
134030fdc8d8SChris Lattner             {
134130fdc8d8SChris Lattner                 Error error (process->Signal (signo));
134230fdc8d8SChris Lattner                 if (error.Success())
134330fdc8d8SChris Lattner                 {
134430fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusSuccessFinishResult);
134530fdc8d8SChris Lattner                 }
134630fdc8d8SChris Lattner                 else
134730fdc8d8SChris Lattner                 {
134830fdc8d8SChris Lattner                     result.AppendErrorWithFormat ("Failed to send signal %i: %s\n", signo, error.AsCString());
134930fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
135030fdc8d8SChris Lattner                 }
135130fdc8d8SChris Lattner             }
135230fdc8d8SChris Lattner         }
135330fdc8d8SChris Lattner         else
135430fdc8d8SChris Lattner         {
1355fd54b368SJason Molenda             result.AppendErrorWithFormat("'%s' takes exactly one signal number argument:\nUsage: %s\n", m_cmd_name.c_str(),
135630fdc8d8SChris Lattner                                         m_cmd_syntax.c_str());
135730fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
135830fdc8d8SChris Lattner         }
135930fdc8d8SChris Lattner         return result.Succeeded();
136030fdc8d8SChris Lattner     }
136130fdc8d8SChris Lattner };
136230fdc8d8SChris Lattner 
136330fdc8d8SChris Lattner //-------------------------------------------------------------------------
136430fdc8d8SChris Lattner // CommandObjectProcessInterrupt
136530fdc8d8SChris Lattner //-------------------------------------------------------------------------
1366bb9caf73SJim Ingham #pragma mark CommandObjectProcessInterrupt
136730fdc8d8SChris Lattner 
13685a988416SJim Ingham class CommandObjectProcessInterrupt : public CommandObjectParsed
136930fdc8d8SChris Lattner {
137030fdc8d8SChris Lattner public:
1371*7428a18cSKate Stone     CommandObjectProcessInterrupt(CommandInterpreter &interpreter)
1372*7428a18cSKate Stone         : CommandObjectParsed(interpreter, "process interrupt", "Interrupt the current target process.",
1373a7015092SGreg Clayton                               "process interrupt",
1374*7428a18cSKate Stone                               eCommandRequiresProcess | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched)
137530fdc8d8SChris Lattner     {
137630fdc8d8SChris Lattner     }
137730fdc8d8SChris Lattner 
137849bcfd80SEugene Zelenko     ~CommandObjectProcessInterrupt() override = default;
137930fdc8d8SChris Lattner 
13805a988416SJim Ingham protected:
138130fdc8d8SChris Lattner     bool
138213d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
138330fdc8d8SChris Lattner     {
1384f9fc609fSGreg Clayton         Process *process = m_exe_ctx.GetProcessPtr();
138549bcfd80SEugene Zelenko         if (process == nullptr)
138630fdc8d8SChris Lattner         {
138730fdc8d8SChris Lattner             result.AppendError ("no process to halt");
138830fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
138930fdc8d8SChris Lattner             return false;
139030fdc8d8SChris Lattner         }
139130fdc8d8SChris Lattner 
139230fdc8d8SChris Lattner         if (command.GetArgumentCount() == 0)
139330fdc8d8SChris Lattner         {
1394f9b57b9dSGreg Clayton             bool clear_thread_plans = true;
1395f9b57b9dSGreg Clayton             Error error(process->Halt (clear_thread_plans));
139630fdc8d8SChris Lattner             if (error.Success())
139730fdc8d8SChris Lattner             {
139830fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusSuccessFinishResult);
139930fdc8d8SChris Lattner             }
140030fdc8d8SChris Lattner             else
140130fdc8d8SChris Lattner             {
140230fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("Failed to halt process: %s\n", error.AsCString());
140330fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
140430fdc8d8SChris Lattner             }
140530fdc8d8SChris Lattner         }
140630fdc8d8SChris Lattner         else
140730fdc8d8SChris Lattner         {
1408fd54b368SJason Molenda             result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n",
140930fdc8d8SChris Lattner                                         m_cmd_name.c_str(),
141030fdc8d8SChris Lattner                                         m_cmd_syntax.c_str());
141130fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
141230fdc8d8SChris Lattner         }
141330fdc8d8SChris Lattner         return result.Succeeded();
141430fdc8d8SChris Lattner     }
141530fdc8d8SChris Lattner };
141630fdc8d8SChris Lattner 
141730fdc8d8SChris Lattner //-------------------------------------------------------------------------
141830fdc8d8SChris Lattner // CommandObjectProcessKill
141930fdc8d8SChris Lattner //-------------------------------------------------------------------------
1420bb9caf73SJim Ingham #pragma mark CommandObjectProcessKill
142130fdc8d8SChris Lattner 
14225a988416SJim Ingham class CommandObjectProcessKill : public CommandObjectParsed
142330fdc8d8SChris Lattner {
142430fdc8d8SChris Lattner public:
1425*7428a18cSKate Stone     CommandObjectProcessKill(CommandInterpreter &interpreter)
1426*7428a18cSKate Stone         : CommandObjectParsed(interpreter, "process kill", "Terminate the current target process.", "process kill",
1427*7428a18cSKate Stone                               eCommandRequiresProcess | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched)
142830fdc8d8SChris Lattner     {
142930fdc8d8SChris Lattner     }
143030fdc8d8SChris Lattner 
143149bcfd80SEugene Zelenko     ~CommandObjectProcessKill() override = default;
143230fdc8d8SChris Lattner 
14335a988416SJim Ingham protected:
143430fdc8d8SChris Lattner     bool
143513d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
143630fdc8d8SChris Lattner     {
1437f9fc609fSGreg Clayton         Process *process = m_exe_ctx.GetProcessPtr();
143849bcfd80SEugene Zelenko         if (process == nullptr)
143930fdc8d8SChris Lattner         {
144030fdc8d8SChris Lattner             result.AppendError ("no process to kill");
144130fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
144230fdc8d8SChris Lattner             return false;
144330fdc8d8SChris Lattner         }
144430fdc8d8SChris Lattner 
144530fdc8d8SChris Lattner         if (command.GetArgumentCount() == 0)
144630fdc8d8SChris Lattner         {
14478980e6bcSJason Molenda             Error error (process->Destroy(true));
144830fdc8d8SChris Lattner             if (error.Success())
144930fdc8d8SChris Lattner             {
145030fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusSuccessFinishResult);
145130fdc8d8SChris Lattner             }
145230fdc8d8SChris Lattner             else
145330fdc8d8SChris Lattner             {
145430fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString());
145530fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
145630fdc8d8SChris Lattner             }
145730fdc8d8SChris Lattner         }
145830fdc8d8SChris Lattner         else
145930fdc8d8SChris Lattner         {
1460fd54b368SJason Molenda             result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n",
146130fdc8d8SChris Lattner                                         m_cmd_name.c_str(),
146230fdc8d8SChris Lattner                                         m_cmd_syntax.c_str());
146330fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
146430fdc8d8SChris Lattner         }
146530fdc8d8SChris Lattner         return result.Succeeded();
146630fdc8d8SChris Lattner     }
146730fdc8d8SChris Lattner };
146830fdc8d8SChris Lattner 
146930fdc8d8SChris Lattner //-------------------------------------------------------------------------
1470a2715cf1SGreg Clayton // CommandObjectProcessSaveCore
1471a2715cf1SGreg Clayton //-------------------------------------------------------------------------
1472a2715cf1SGreg Clayton #pragma mark CommandObjectProcessSaveCore
1473a2715cf1SGreg Clayton 
1474a2715cf1SGreg Clayton class CommandObjectProcessSaveCore : public CommandObjectParsed
1475a2715cf1SGreg Clayton {
1476a2715cf1SGreg Clayton public:
1477a2715cf1SGreg Clayton     CommandObjectProcessSaveCore (CommandInterpreter &interpreter) :
1478a2715cf1SGreg Clayton     CommandObjectParsed (interpreter,
1479a2715cf1SGreg Clayton                          "process save-core",
1480a2715cf1SGreg Clayton                          "Save the current process as a core file using an appropriate file type.",
1481a2715cf1SGreg Clayton                          "process save-core FILE",
1482e87764f2SEnrico Granata                          eCommandRequiresProcess      |
1483e87764f2SEnrico Granata                          eCommandTryTargetAPILock     |
1484e87764f2SEnrico Granata                          eCommandProcessMustBeLaunched)
1485a2715cf1SGreg Clayton     {
1486a2715cf1SGreg Clayton     }
1487a2715cf1SGreg Clayton 
148849bcfd80SEugene Zelenko     ~CommandObjectProcessSaveCore() override = default;
1489a2715cf1SGreg Clayton 
1490a2715cf1SGreg Clayton protected:
1491a2715cf1SGreg Clayton     bool
1492a2715cf1SGreg Clayton     DoExecute (Args& command,
149313d21e9aSBruce Mitchener                CommandReturnObject &result) override
1494a2715cf1SGreg Clayton     {
1495a2715cf1SGreg Clayton         ProcessSP process_sp = m_exe_ctx.GetProcessSP();
1496a2715cf1SGreg Clayton         if (process_sp)
1497a2715cf1SGreg Clayton         {
1498a2715cf1SGreg Clayton             if (command.GetArgumentCount() == 1)
1499a2715cf1SGreg Clayton             {
1500a2715cf1SGreg Clayton                 FileSpec output_file(command.GetArgumentAtIndex(0), false);
1501a2715cf1SGreg Clayton                 Error error = PluginManager::SaveCore(process_sp, output_file);
1502a2715cf1SGreg Clayton                 if (error.Success())
1503a2715cf1SGreg Clayton                 {
1504a2715cf1SGreg Clayton                     result.SetStatus (eReturnStatusSuccessFinishResult);
1505a2715cf1SGreg Clayton                 }
1506a2715cf1SGreg Clayton                 else
1507a2715cf1SGreg Clayton                 {
1508a2715cf1SGreg Clayton                     result.AppendErrorWithFormat ("Failed to save core file for process: %s\n", error.AsCString());
1509a2715cf1SGreg Clayton                     result.SetStatus (eReturnStatusFailed);
1510a2715cf1SGreg Clayton                 }
1511a2715cf1SGreg Clayton             }
1512a2715cf1SGreg Clayton             else
1513a2715cf1SGreg Clayton             {
1514a2715cf1SGreg Clayton                 result.AppendErrorWithFormat ("'%s' takes one arguments:\nUsage: %s\n",
1515a2715cf1SGreg Clayton                                               m_cmd_name.c_str(),
1516a2715cf1SGreg Clayton                                               m_cmd_syntax.c_str());
1517a2715cf1SGreg Clayton                 result.SetStatus (eReturnStatusFailed);
1518a2715cf1SGreg Clayton             }
1519a2715cf1SGreg Clayton         }
1520a2715cf1SGreg Clayton         else
1521a2715cf1SGreg Clayton         {
1522a2715cf1SGreg Clayton             result.AppendError ("invalid process");
1523a2715cf1SGreg Clayton             result.SetStatus (eReturnStatusFailed);
1524a2715cf1SGreg Clayton             return false;
1525a2715cf1SGreg Clayton         }
1526a2715cf1SGreg Clayton 
1527a2715cf1SGreg Clayton         return result.Succeeded();
1528a2715cf1SGreg Clayton     }
1529a2715cf1SGreg Clayton };
1530a2715cf1SGreg Clayton 
1531a2715cf1SGreg Clayton //-------------------------------------------------------------------------
15324b9bea87SJim Ingham // CommandObjectProcessStatus
15334b9bea87SJim Ingham //-------------------------------------------------------------------------
1534bb9caf73SJim Ingham #pragma mark CommandObjectProcessStatus
1535bb9caf73SJim Ingham 
15365a988416SJim Ingham class CommandObjectProcessStatus : public CommandObjectParsed
15374b9bea87SJim Ingham {
15384b9bea87SJim Ingham public:
1539*7428a18cSKate Stone     CommandObjectProcessStatus(CommandInterpreter &interpreter)
1540*7428a18cSKate Stone         : CommandObjectParsed(interpreter, "process status",
1541*7428a18cSKate Stone                               "Show status and stop location for the current target process.", "process status",
1542e87764f2SEnrico Granata                               eCommandRequiresProcess | eCommandTryTargetAPILock)
15434b9bea87SJim Ingham     {
15444b9bea87SJim Ingham     }
15454b9bea87SJim Ingham 
154649bcfd80SEugene Zelenko     ~CommandObjectProcessStatus() override = default;
15474b9bea87SJim Ingham 
15484b9bea87SJim Ingham     bool
154913d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
15504b9bea87SJim Ingham     {
15517260f620SGreg Clayton         Stream &strm = result.GetOutputStream();
15524b9bea87SJim Ingham         result.SetStatus (eReturnStatusSuccessFinishNoResult);
1553e87764f2SEnrico Granata         // No need to check "process" for validity as eCommandRequiresProcess ensures it is valid
1554f9fc609fSGreg Clayton         Process *process = m_exe_ctx.GetProcessPtr();
15557260f620SGreg Clayton         const bool only_threads_with_stop_reason = true;
15567260f620SGreg Clayton         const uint32_t start_frame = 0;
15577260f620SGreg Clayton         const uint32_t num_frames = 1;
15587260f620SGreg Clayton         const uint32_t num_frames_with_source = 1;
1559c14ee32dSGreg Clayton         process->GetStatus(strm);
1560c14ee32dSGreg Clayton         process->GetThreadStatus (strm,
15617260f620SGreg Clayton                                   only_threads_with_stop_reason,
15627260f620SGreg Clayton                                   start_frame,
15637260f620SGreg Clayton                                   num_frames,
15647260f620SGreg Clayton                                   num_frames_with_source);
15654b9bea87SJim Ingham         return result.Succeeded();
15664b9bea87SJim Ingham     }
15674b9bea87SJim Ingham };
15684b9bea87SJim Ingham 
15694b9bea87SJim Ingham //-------------------------------------------------------------------------
157035731357SCaroline Tice // CommandObjectProcessHandle
157135731357SCaroline Tice //-------------------------------------------------------------------------
1572bb9caf73SJim Ingham #pragma mark CommandObjectProcessHandle
157335731357SCaroline Tice 
15745a988416SJim Ingham class CommandObjectProcessHandle : public CommandObjectParsed
157535731357SCaroline Tice {
157635731357SCaroline Tice public:
157735731357SCaroline Tice     class CommandOptions : public Options
157835731357SCaroline Tice     {
157935731357SCaroline Tice     public:
1580eb0103f2SGreg Clayton         CommandOptions (CommandInterpreter &interpreter) :
1581eb0103f2SGreg Clayton             Options (interpreter)
158235731357SCaroline Tice         {
1583f6b8b581SGreg Clayton             OptionParsingStarting ();
158435731357SCaroline Tice         }
158535731357SCaroline Tice 
158649bcfd80SEugene Zelenko         ~CommandOptions() override = default;
158735731357SCaroline Tice 
158835731357SCaroline Tice         Error
158913d21e9aSBruce Mitchener         SetOptionValue (uint32_t option_idx, const char *option_arg) override
159035731357SCaroline Tice         {
159135731357SCaroline Tice             Error error;
15923bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
159335731357SCaroline Tice 
159435731357SCaroline Tice             switch (short_option)
159535731357SCaroline Tice             {
159635731357SCaroline Tice                 case 's':
159735731357SCaroline Tice                     stop = option_arg;
159835731357SCaroline Tice                     break;
159935731357SCaroline Tice                 case 'n':
160035731357SCaroline Tice                     notify = option_arg;
160135731357SCaroline Tice                     break;
160235731357SCaroline Tice                 case 'p':
160335731357SCaroline Tice                     pass = option_arg;
160435731357SCaroline Tice                     break;
160535731357SCaroline Tice                 default:
160686edbf41SGreg Clayton                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
160735731357SCaroline Tice                     break;
160835731357SCaroline Tice             }
160935731357SCaroline Tice             return error;
161035731357SCaroline Tice         }
161135731357SCaroline Tice 
161235731357SCaroline Tice         void
161313d21e9aSBruce Mitchener         OptionParsingStarting () override
161435731357SCaroline Tice         {
161535731357SCaroline Tice             stop.clear();
161635731357SCaroline Tice             notify.clear();
161735731357SCaroline Tice             pass.clear();
161835731357SCaroline Tice         }
161935731357SCaroline Tice 
1620e0d378b3SGreg Clayton         const OptionDefinition*
162113d21e9aSBruce Mitchener         GetDefinitions () override
162235731357SCaroline Tice         {
162335731357SCaroline Tice             return g_option_table;
162435731357SCaroline Tice         }
162535731357SCaroline Tice 
162635731357SCaroline Tice         // Options table: Required for subclasses of Options.
162735731357SCaroline Tice 
1628e0d378b3SGreg Clayton         static OptionDefinition g_option_table[];
162935731357SCaroline Tice 
163035731357SCaroline Tice         // Instance variables to hold the values for command options.
163135731357SCaroline Tice 
163235731357SCaroline Tice         std::string stop;
163335731357SCaroline Tice         std::string notify;
163435731357SCaroline Tice         std::string pass;
163535731357SCaroline Tice     };
163635731357SCaroline Tice 
1637*7428a18cSKate Stone     CommandObjectProcessHandle(CommandInterpreter &interpreter)
1638*7428a18cSKate Stone         : CommandObjectParsed(
1639*7428a18cSKate Stone               interpreter, "process handle",
1640*7428a18cSKate Stone               "Manage LLDB handling of OS signals for the current target process.  Defaults to showing current policy.",
164149bcfd80SEugene Zelenko               nullptr),
1642eb0103f2SGreg Clayton           m_options(interpreter)
164335731357SCaroline Tice     {
1644ea671fbdSKate Stone         SetHelpLong ("\nIf no signals are specified, update them all.  If no update "
1645ea671fbdSKate Stone                      "option is specified, list the current values.");
164635731357SCaroline Tice         CommandArgumentEntry arg;
1647c0dbdfb6SCaroline Tice         CommandArgumentData signal_arg;
164835731357SCaroline Tice 
1649c0dbdfb6SCaroline Tice         signal_arg.arg_type = eArgTypeUnixSignal;
1650c0dbdfb6SCaroline Tice         signal_arg.arg_repetition = eArgRepeatStar;
165135731357SCaroline Tice 
1652c0dbdfb6SCaroline Tice         arg.push_back (signal_arg);
165335731357SCaroline Tice 
165435731357SCaroline Tice         m_arguments.push_back (arg);
165535731357SCaroline Tice     }
165635731357SCaroline Tice 
165749bcfd80SEugene Zelenko     ~CommandObjectProcessHandle() override = default;
165835731357SCaroline Tice 
165935731357SCaroline Tice     Options *
166013d21e9aSBruce Mitchener     GetOptions () override
166135731357SCaroline Tice     {
166235731357SCaroline Tice         return &m_options;
166335731357SCaroline Tice     }
166435731357SCaroline Tice 
166535731357SCaroline Tice     bool
166610ad7993SCaroline Tice     VerifyCommandOptionValue (const std::string &option, int &real_value)
166735731357SCaroline Tice     {
166835731357SCaroline Tice         bool okay = true;
166910ad7993SCaroline Tice         bool success = false;
167010ad7993SCaroline Tice         bool tmp_value = Args::StringToBoolean (option.c_str(), false, &success);
167110ad7993SCaroline Tice 
167210ad7993SCaroline Tice         if (success && tmp_value)
167310ad7993SCaroline Tice             real_value = 1;
167410ad7993SCaroline Tice         else if (success && !tmp_value)
167510ad7993SCaroline Tice             real_value = 0;
167635731357SCaroline Tice         else
167735731357SCaroline Tice         {
167835731357SCaroline Tice             // If the value isn't 'true' or 'false', it had better be 0 or 1.
16795275aaa0SVince Harron             real_value = StringConvert::ToUInt32 (option.c_str(), 3);
168010ad7993SCaroline Tice             if (real_value != 0 && real_value != 1)
168135731357SCaroline Tice                 okay = false;
168235731357SCaroline Tice         }
168335731357SCaroline Tice 
168435731357SCaroline Tice         return okay;
168535731357SCaroline Tice     }
168635731357SCaroline Tice 
168710ad7993SCaroline Tice     void
168810ad7993SCaroline Tice     PrintSignalHeader (Stream &str)
168910ad7993SCaroline Tice     {
169010ad7993SCaroline Tice         str.Printf ("NAME         PASS   STOP   NOTIFY\n");
1691b84141a6SPavel Labath         str.Printf ("===========  =====  =====  ======\n");
169210ad7993SCaroline Tice     }
169310ad7993SCaroline Tice 
169410ad7993SCaroline Tice     void
169598d0a4b3SChaoren Lin     PrintSignal(Stream &str, int32_t signo, const char *sig_name, const UnixSignalsSP &signals_sp)
169610ad7993SCaroline Tice     {
169710ad7993SCaroline Tice         bool stop;
169810ad7993SCaroline Tice         bool suppress;
169910ad7993SCaroline Tice         bool notify;
170010ad7993SCaroline Tice 
1701b84141a6SPavel Labath         str.Printf ("%-11s  ", sig_name);
170298d0a4b3SChaoren Lin         if (signals_sp->GetSignalInfo(signo, suppress, stop, notify))
170310ad7993SCaroline Tice         {
170410ad7993SCaroline Tice             bool pass = !suppress;
170510ad7993SCaroline Tice             str.Printf ("%s  %s  %s",
170610ad7993SCaroline Tice                         (pass ? "true " : "false"),
170710ad7993SCaroline Tice                         (stop ? "true " : "false"),
170810ad7993SCaroline Tice                         (notify ? "true " : "false"));
170910ad7993SCaroline Tice         }
171010ad7993SCaroline Tice         str.Printf ("\n");
171110ad7993SCaroline Tice     }
171210ad7993SCaroline Tice 
171310ad7993SCaroline Tice     void
171498d0a4b3SChaoren Lin     PrintSignalInformation(Stream &str, Args &signal_args, int num_valid_signals, const UnixSignalsSP &signals_sp)
171510ad7993SCaroline Tice     {
171610ad7993SCaroline Tice         PrintSignalHeader (str);
171710ad7993SCaroline Tice 
171810ad7993SCaroline Tice         if (num_valid_signals > 0)
171910ad7993SCaroline Tice         {
172010ad7993SCaroline Tice             size_t num_args = signal_args.GetArgumentCount();
172110ad7993SCaroline Tice             for (size_t i = 0; i < num_args; ++i)
172210ad7993SCaroline Tice             {
172398d0a4b3SChaoren Lin                 int32_t signo = signals_sp->GetSignalNumberFromName(signal_args.GetArgumentAtIndex(i));
172410ad7993SCaroline Tice                 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
172598d0a4b3SChaoren Lin                     PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals_sp);
172610ad7993SCaroline Tice             }
172710ad7993SCaroline Tice         }
172810ad7993SCaroline Tice         else // Print info for ALL signals
172910ad7993SCaroline Tice         {
173098d0a4b3SChaoren Lin             int32_t signo = signals_sp->GetFirstSignalNumber();
173110ad7993SCaroline Tice             while (signo != LLDB_INVALID_SIGNAL_NUMBER)
173210ad7993SCaroline Tice             {
173398d0a4b3SChaoren Lin                 PrintSignal(str, signo, signals_sp->GetSignalAsCString(signo), signals_sp);
173498d0a4b3SChaoren Lin                 signo = signals_sp->GetNextSignalNumber(signo);
173510ad7993SCaroline Tice             }
173610ad7993SCaroline Tice         }
173710ad7993SCaroline Tice     }
173810ad7993SCaroline Tice 
17395a988416SJim Ingham protected:
174035731357SCaroline Tice     bool
174113d21e9aSBruce Mitchener     DoExecute (Args &signal_args, CommandReturnObject &result) override
174235731357SCaroline Tice     {
174335731357SCaroline Tice         TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
174435731357SCaroline Tice 
174535731357SCaroline Tice         if (!target_sp)
174635731357SCaroline Tice         {
174735731357SCaroline Tice             result.AppendError ("No current target;"
174835731357SCaroline Tice                                 " cannot handle signals until you have a valid target and process.\n");
174935731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
175035731357SCaroline Tice             return false;
175135731357SCaroline Tice         }
175235731357SCaroline Tice 
175335731357SCaroline Tice         ProcessSP process_sp = target_sp->GetProcessSP();
175435731357SCaroline Tice 
175535731357SCaroline Tice         if (!process_sp)
175635731357SCaroline Tice         {
175735731357SCaroline Tice             result.AppendError ("No current process; cannot handle signals until you have a valid process.\n");
175835731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
175935731357SCaroline Tice             return false;
176035731357SCaroline Tice         }
176135731357SCaroline Tice 
176235731357SCaroline Tice         int stop_action = -1;   // -1 means leave the current setting alone
176335731357SCaroline Tice         int pass_action = -1;   // -1 means leave the current setting alone
176435731357SCaroline Tice         int notify_action = -1; // -1 means leave the current setting alone
176535731357SCaroline Tice 
176635731357SCaroline Tice         if (! m_options.stop.empty()
176710ad7993SCaroline Tice             && ! VerifyCommandOptionValue (m_options.stop, stop_action))
176835731357SCaroline Tice         {
176935731357SCaroline Tice             result.AppendError ("Invalid argument for command option --stop; must be true or false.\n");
177035731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
177135731357SCaroline Tice             return false;
177235731357SCaroline Tice         }
177335731357SCaroline Tice 
177435731357SCaroline Tice         if (! m_options.notify.empty()
177510ad7993SCaroline Tice             && ! VerifyCommandOptionValue (m_options.notify, notify_action))
177635731357SCaroline Tice         {
177735731357SCaroline Tice             result.AppendError ("Invalid argument for command option --notify; must be true or false.\n");
177835731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
177935731357SCaroline Tice             return false;
178035731357SCaroline Tice         }
178135731357SCaroline Tice 
178235731357SCaroline Tice         if (! m_options.pass.empty()
178310ad7993SCaroline Tice             && ! VerifyCommandOptionValue (m_options.pass, pass_action))
178435731357SCaroline Tice         {
178535731357SCaroline Tice             result.AppendError ("Invalid argument for command option --pass; must be true or false.\n");
178635731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
178735731357SCaroline Tice             return false;
178835731357SCaroline Tice         }
178935731357SCaroline Tice 
179035731357SCaroline Tice         size_t num_args = signal_args.GetArgumentCount();
179198d0a4b3SChaoren Lin         UnixSignalsSP signals_sp = process_sp->GetUnixSignals();
179235731357SCaroline Tice         int num_signals_set = 0;
179335731357SCaroline Tice 
179410ad7993SCaroline Tice         if (num_args > 0)
179510ad7993SCaroline Tice         {
179635731357SCaroline Tice             for (size_t i = 0; i < num_args; ++i)
179735731357SCaroline Tice             {
179898d0a4b3SChaoren Lin                 int32_t signo = signals_sp->GetSignalNumberFromName(signal_args.GetArgumentAtIndex(i));
179935731357SCaroline Tice                 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
180035731357SCaroline Tice                 {
180110ad7993SCaroline Tice                     // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees
180235731357SCaroline Tice                     // the value is either 0 or 1.
180335731357SCaroline Tice                     if (stop_action != -1)
180498d0a4b3SChaoren Lin                         signals_sp->SetShouldStop(signo, stop_action);
180535731357SCaroline Tice                     if (pass_action != -1)
180635731357SCaroline Tice                     {
180798d0a4b3SChaoren Lin                         bool suppress = !pass_action;
180898d0a4b3SChaoren Lin                         signals_sp->SetShouldSuppress(signo, suppress);
180935731357SCaroline Tice                     }
181035731357SCaroline Tice                     if (notify_action != -1)
181198d0a4b3SChaoren Lin                         signals_sp->SetShouldNotify(signo, notify_action);
181235731357SCaroline Tice                     ++num_signals_set;
181335731357SCaroline Tice                 }
181435731357SCaroline Tice                 else
181535731357SCaroline Tice                 {
181635731357SCaroline Tice                     result.AppendErrorWithFormat ("Invalid signal name '%s'\n", signal_args.GetArgumentAtIndex (i));
181735731357SCaroline Tice                 }
181835731357SCaroline Tice             }
181910ad7993SCaroline Tice         }
182010ad7993SCaroline Tice         else
182110ad7993SCaroline Tice         {
182210ad7993SCaroline Tice             // No signal specified, if any command options were specified, update ALL signals.
182310ad7993SCaroline Tice             if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1))
182410ad7993SCaroline Tice             {
182510ad7993SCaroline Tice                 if (m_interpreter.Confirm ("Do you really want to update all the signals?", false))
182610ad7993SCaroline Tice                 {
182798d0a4b3SChaoren Lin                     int32_t signo = signals_sp->GetFirstSignalNumber();
182810ad7993SCaroline Tice                     while (signo != LLDB_INVALID_SIGNAL_NUMBER)
182910ad7993SCaroline Tice                     {
183010ad7993SCaroline Tice                         if (notify_action != -1)
183198d0a4b3SChaoren Lin                             signals_sp->SetShouldNotify(signo, notify_action);
183210ad7993SCaroline Tice                         if (stop_action != -1)
183398d0a4b3SChaoren Lin                             signals_sp->SetShouldStop(signo, stop_action);
183410ad7993SCaroline Tice                         if (pass_action != -1)
183510ad7993SCaroline Tice                         {
183698d0a4b3SChaoren Lin                             bool suppress = !pass_action;
183798d0a4b3SChaoren Lin                             signals_sp->SetShouldSuppress(signo, suppress);
183810ad7993SCaroline Tice                         }
183998d0a4b3SChaoren Lin                         signo = signals_sp->GetNextSignalNumber(signo);
184010ad7993SCaroline Tice                     }
184110ad7993SCaroline Tice                 }
184210ad7993SCaroline Tice             }
184310ad7993SCaroline Tice         }
184410ad7993SCaroline Tice 
184598d0a4b3SChaoren Lin         PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals_sp);
184635731357SCaroline Tice 
184735731357SCaroline Tice         if (num_signals_set > 0)
184835731357SCaroline Tice             result.SetStatus (eReturnStatusSuccessFinishNoResult);
184935731357SCaroline Tice         else
185035731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
185135731357SCaroline Tice 
185235731357SCaroline Tice         return result.Succeeded();
185335731357SCaroline Tice     }
185435731357SCaroline Tice 
185535731357SCaroline Tice     CommandOptions m_options;
185635731357SCaroline Tice };
185735731357SCaroline Tice 
1858e0d378b3SGreg Clayton OptionDefinition
185935731357SCaroline Tice CommandObjectProcessHandle::CommandOptions::g_option_table[] =
186035731357SCaroline Tice {
186149bcfd80SEugene Zelenko { 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." },
186249bcfd80SEugene Zelenko { 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." },
186349bcfd80SEugene Zelenko { LLDB_OPT_SET_1, false, "pass",  'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." },
186449bcfd80SEugene Zelenko { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
186535731357SCaroline Tice };
186635731357SCaroline Tice 
186735731357SCaroline Tice //-------------------------------------------------------------------------
186830fdc8d8SChris Lattner // CommandObjectMultiwordProcess
186930fdc8d8SChris Lattner //-------------------------------------------------------------------------
187030fdc8d8SChris Lattner 
1871*7428a18cSKate Stone CommandObjectMultiwordProcess::CommandObjectMultiwordProcess(CommandInterpreter &interpreter)
1872*7428a18cSKate Stone     : CommandObjectMultiword(interpreter, "process", "Commands for interacting with processes on the current platform.",
187330fdc8d8SChris Lattner                              "process <subcommand> [<subcommand-options>]")
187430fdc8d8SChris Lattner {
1875a7015092SGreg Clayton     LoadSubCommand ("attach",      CommandObjectSP (new CommandObjectProcessAttach    (interpreter)));
1876a7015092SGreg Clayton     LoadSubCommand ("launch",      CommandObjectSP (new CommandObjectProcessLaunch    (interpreter)));
1877a7015092SGreg Clayton     LoadSubCommand ("continue",    CommandObjectSP (new CommandObjectProcessContinue  (interpreter)));
1878b766a73dSGreg Clayton     LoadSubCommand ("connect",     CommandObjectSP (new CommandObjectProcessConnect   (interpreter)));
1879a7015092SGreg Clayton     LoadSubCommand ("detach",      CommandObjectSP (new CommandObjectProcessDetach    (interpreter)));
18808f343b09SGreg Clayton     LoadSubCommand ("load",        CommandObjectSP (new CommandObjectProcessLoad      (interpreter)));
18818f343b09SGreg Clayton     LoadSubCommand ("unload",      CommandObjectSP (new CommandObjectProcessUnload    (interpreter)));
1882a7015092SGreg Clayton     LoadSubCommand ("signal",      CommandObjectSP (new CommandObjectProcessSignal    (interpreter)));
188335731357SCaroline Tice     LoadSubCommand ("handle",      CommandObjectSP (new CommandObjectProcessHandle    (interpreter)));
1884a7015092SGreg Clayton     LoadSubCommand ("status",      CommandObjectSP (new CommandObjectProcessStatus    (interpreter)));
1885a7015092SGreg Clayton     LoadSubCommand ("interrupt",   CommandObjectSP (new CommandObjectProcessInterrupt (interpreter)));
1886a7015092SGreg Clayton     LoadSubCommand ("kill",        CommandObjectSP (new CommandObjectProcessKill      (interpreter)));
1887998255bfSGreg Clayton     LoadSubCommand ("plugin",      CommandObjectSP (new CommandObjectProcessPlugin    (interpreter)));
1888a2715cf1SGreg Clayton     LoadSubCommand ("save-core",   CommandObjectSP (new CommandObjectProcessSaveCore  (interpreter)));
188930fdc8d8SChris Lattner }
189030fdc8d8SChris Lattner 
189149bcfd80SEugene Zelenko CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess() = default;
1892