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"),
129e1cfbc79STodd Fiala         m_options()
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 
160e1cfbc79STodd Fiala         CommandCompletions::InvokeCommonCompletionCallbacks(GetCommandInterpreter(),
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 //{
306*ac9c3a62SKate Stone //  // clang-format off
30749bcfd80SEugene 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."},
30849bcfd80SEugene Zelenko //  {SET1,               false, "stdin",         'i', OptionParser::eRequiredArgument, nullptr, 0, eArgTypeDirectoryName, "Redirect stdin for the process to <path>."},
30949bcfd80SEugene Zelenko //  {SET1,               false, "stdout",        'o', OptionParser::eRequiredArgument, nullptr, 0, eArgTypeDirectoryName, "Redirect stdout for the process to <path>."},
31049bcfd80SEugene Zelenko //  {SET1,               false, "stderr",        'e', OptionParser::eRequiredArgument, nullptr, 0, eArgTypeDirectoryName, "Redirect stderr for the process to <path>."},
31149bcfd80SEugene Zelenko //  {SET1 | SET2 | SET3, false, "plugin",        'p', OptionParser::eRequiredArgument, nullptr, 0, eArgTypePlugin,        "Name of the process plugin you want to use."},
31249bcfd80SEugene 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."},
31349bcfd80SEugene Zelenko //  {              SET3, false, "no-stdio",      'n', OptionParser::eNoArgument,       nullptr, 0, eArgTypeNone,          "Do not set up for terminal I/O to go to running process."},
31449bcfd80SEugene Zelenko //  {SET1 | SET2 | SET3, false, "working-dir",   'w', OptionParser::eRequiredArgument, nullptr, 0, eArgTypeDirectoryName, "Set the current working directory to <path> when running the inferior."},
31549bcfd80SEugene Zelenko //  {0, false, nullptr, 0, 0, nullptr, 0, eArgTypeNone, nullptr}
316*ac9c3a62SKate Stone //  // clang-format on
317982c9762SGreg Clayton //};
318982c9762SGreg Clayton //
319982c9762SGreg Clayton //#undef SET1
320982c9762SGreg Clayton //#undef SET2
321982c9762SGreg Clayton //#undef SET3
32230fdc8d8SChris Lattner 
32330fdc8d8SChris Lattner //-------------------------------------------------------------------------
32430fdc8d8SChris Lattner // CommandObjectProcessAttach
32530fdc8d8SChris Lattner //-------------------------------------------------------------------------
326bb9caf73SJim Ingham #pragma mark CommandObjectProcessAttach
327dcb1d856SJim Ingham class CommandObjectProcessAttach : public CommandObjectProcessLaunchOrAttach
32830fdc8d8SChris Lattner {
32930fdc8d8SChris Lattner public:
33030fdc8d8SChris Lattner     class CommandOptions : public Options
33130fdc8d8SChris Lattner     {
33230fdc8d8SChris Lattner     public:
333e1cfbc79STodd Fiala         CommandOptions() :
334e1cfbc79STodd Fiala             Options()
33530fdc8d8SChris Lattner         {
336f6b8b581SGreg Clayton             // Keep default values of all options in one place: OptionParsingStarting ()
337e1cfbc79STodd Fiala             OptionParsingStarting(nullptr);
33830fdc8d8SChris Lattner         }
33930fdc8d8SChris Lattner 
34049bcfd80SEugene Zelenko         ~CommandOptions() override = default;
34130fdc8d8SChris Lattner 
34230fdc8d8SChris Lattner         Error
343e1cfbc79STodd Fiala         SetOptionValue (uint32_t option_idx, const char *option_arg,
344e1cfbc79STodd Fiala                         ExecutionContext *execution_context) override
34530fdc8d8SChris Lattner         {
34630fdc8d8SChris Lattner             Error error;
3473bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
34830fdc8d8SChris Lattner             bool success = false;
34930fdc8d8SChris Lattner             switch (short_option)
35030fdc8d8SChris Lattner             {
351a95ce623SJohnny Chen                 case 'c':
352a95ce623SJohnny Chen                     attach_info.SetContinueOnceAttached(true);
353a95ce623SJohnny Chen                     break;
354a95ce623SJohnny Chen 
35530fdc8d8SChris Lattner                 case 'p':
356144f3a9cSGreg Clayton                     {
3575275aaa0SVince Harron                         lldb::pid_t pid = StringConvert::ToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success);
35830fdc8d8SChris Lattner                         if (!success || pid == LLDB_INVALID_PROCESS_ID)
35930fdc8d8SChris Lattner                         {
36086edbf41SGreg Clayton                             error.SetErrorStringWithFormat("invalid process ID '%s'", option_arg);
36130fdc8d8SChris Lattner                         }
362144f3a9cSGreg Clayton                         else
363144f3a9cSGreg Clayton                         {
364144f3a9cSGreg Clayton                             attach_info.SetProcessID (pid);
365144f3a9cSGreg Clayton                         }
366144f3a9cSGreg Clayton                     }
36730fdc8d8SChris Lattner                     break;
36830fdc8d8SChris Lattner 
36930fdc8d8SChris Lattner                 case 'P':
370144f3a9cSGreg Clayton                     attach_info.SetProcessPluginName (option_arg);
37130fdc8d8SChris Lattner                     break;
37230fdc8d8SChris Lattner 
37330fdc8d8SChris Lattner                 case 'n':
374144f3a9cSGreg Clayton                     attach_info.GetExecutableFile().SetFile(option_arg, false);
37530fdc8d8SChris Lattner                     break;
37630fdc8d8SChris Lattner 
37730fdc8d8SChris Lattner                 case 'w':
378144f3a9cSGreg Clayton                     attach_info.SetWaitForLaunch(true);
37930fdc8d8SChris Lattner                     break;
38030fdc8d8SChris Lattner 
381cd16df91SJim Ingham                 case 'i':
382cd16df91SJim Ingham                     attach_info.SetIgnoreExisting(false);
383cd16df91SJim Ingham                     break;
384cd16df91SJim Ingham 
38530fdc8d8SChris Lattner                 default:
38686edbf41SGreg Clayton                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
38730fdc8d8SChris Lattner                     break;
38830fdc8d8SChris Lattner             }
38930fdc8d8SChris Lattner             return error;
39030fdc8d8SChris Lattner         }
39130fdc8d8SChris Lattner 
39230fdc8d8SChris Lattner         void
393e1cfbc79STodd Fiala         OptionParsingStarting(ExecutionContext *execution_context) override
39430fdc8d8SChris Lattner         {
395144f3a9cSGreg Clayton             attach_info.Clear();
39630fdc8d8SChris Lattner         }
39730fdc8d8SChris Lattner 
398e0d378b3SGreg Clayton         const OptionDefinition*
39913d21e9aSBruce Mitchener         GetDefinitions () override
40030fdc8d8SChris Lattner         {
40130fdc8d8SChris Lattner             return g_option_table;
40230fdc8d8SChris Lattner         }
40330fdc8d8SChris Lattner 
40413d21e9aSBruce Mitchener         bool
405eb0103f2SGreg Clayton         HandleOptionArgumentCompletion (Args &input,
4065aee162fSJim Ingham                                         int cursor_index,
4075aee162fSJim Ingham                                         int char_pos,
4085aee162fSJim Ingham                                         OptionElementVector &opt_element_vector,
4095aee162fSJim Ingham                                         int opt_element_index,
4105aee162fSJim Ingham                                         int match_start_point,
4115aee162fSJim Ingham                                         int max_return_elements,
412e1cfbc79STodd Fiala                                         CommandInterpreter &interpreter,
4135aee162fSJim Ingham                                         bool &word_complete,
41413d21e9aSBruce Mitchener                                         StringList &matches) override
4155aee162fSJim Ingham         {
4165aee162fSJim Ingham             int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
4175aee162fSJim Ingham             int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
4185aee162fSJim Ingham 
4195aee162fSJim Ingham             // We are only completing the name option for now...
4205aee162fSJim Ingham 
421e0d378b3SGreg Clayton             const OptionDefinition *opt_defs = GetDefinitions();
4225aee162fSJim Ingham             if (opt_defs[opt_defs_index].short_option == 'n')
4235aee162fSJim Ingham             {
4245aee162fSJim Ingham                 // Are we in the name?
4255aee162fSJim Ingham 
4265aee162fSJim Ingham                 // Look to see if there is a -P argument provided, and if so use that plugin, otherwise
4275aee162fSJim Ingham                 // use the default plugin.
4285aee162fSJim Ingham 
42949bcfd80SEugene Zelenko                 const char *partial_name = nullptr;
4305aee162fSJim Ingham                 partial_name = input.GetArgumentAtIndex(opt_arg_pos);
4315aee162fSJim Ingham 
432e1cfbc79STodd Fiala                 PlatformSP platform_sp(interpreter.GetPlatform(true));
433e996fd30SGreg Clayton                 if (platform_sp)
4345aee162fSJim Ingham                 {
4358b82f087SGreg Clayton                     ProcessInstanceInfoList process_infos;
4368b82f087SGreg Clayton                     ProcessInstanceInfoMatch match_info;
43732e0a750SGreg Clayton                     if (partial_name)
43832e0a750SGreg Clayton                     {
439144f3a9cSGreg Clayton                         match_info.GetProcessInfo().GetExecutableFile().SetFile(partial_name, false);
44032e0a750SGreg Clayton                         match_info.SetNameMatchType(eNameMatchStartsWith);
44132e0a750SGreg Clayton                     }
44232e0a750SGreg Clayton                     platform_sp->FindProcesses (match_info, process_infos);
443c7bece56SGreg Clayton                     const size_t num_matches = process_infos.GetSize();
444e996fd30SGreg Clayton                     if (num_matches > 0)
445e996fd30SGreg Clayton                     {
446c7bece56SGreg Clayton                         for (size_t i = 0; i < num_matches; ++i)
447e996fd30SGreg Clayton                         {
448e996fd30SGreg Clayton                             matches.AppendString (process_infos.GetProcessNameAtIndex(i),
449e996fd30SGreg Clayton                                                   process_infos.GetProcessNameLengthAtIndex(i));
4505aee162fSJim Ingham                         }
4515aee162fSJim Ingham                     }
4525aee162fSJim Ingham                 }
4535aee162fSJim Ingham             }
4545aee162fSJim Ingham 
4555aee162fSJim Ingham             return false;
4565aee162fSJim Ingham         }
4575aee162fSJim Ingham 
45830fdc8d8SChris Lattner         // Options table: Required for subclasses of Options.
45930fdc8d8SChris Lattner 
460e0d378b3SGreg Clayton         static OptionDefinition g_option_table[];
46130fdc8d8SChris Lattner 
46230fdc8d8SChris Lattner         // Instance variables to hold the values for command options.
46330fdc8d8SChris Lattner 
464144f3a9cSGreg Clayton         ProcessAttachInfo attach_info;
46530fdc8d8SChris Lattner     };
46630fdc8d8SChris Lattner 
467a7015092SGreg Clayton     CommandObjectProcessAttach (CommandInterpreter &interpreter) :
468dcb1d856SJim Ingham         CommandObjectProcessLaunchOrAttach (interpreter,
469a7015092SGreg Clayton                                             "process attach",
470e3d26315SCaroline Tice                                             "Attach to a process.",
471dcb1d856SJim Ingham                                             "process attach <cmd-options>",
472dcb1d856SJim Ingham                                             0,
473dcb1d856SJim Ingham                                             "attach"),
474e1cfbc79STodd Fiala         m_options()
4755aee162fSJim Ingham     {
4765aee162fSJim Ingham     }
4775aee162fSJim Ingham 
47849bcfd80SEugene Zelenko     ~CommandObjectProcessAttach() override = default;
4795aee162fSJim Ingham 
4805a988416SJim Ingham     Options *
48113d21e9aSBruce Mitchener     GetOptions () override
4825a988416SJim Ingham     {
4835a988416SJim Ingham         return &m_options;
4845a988416SJim Ingham     }
4855a988416SJim Ingham 
4865a988416SJim Ingham protected:
4875aee162fSJim Ingham     bool
48813d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
4895aee162fSJim Ingham     {
490926af0cdSOleksiy Vyalov         PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
491926af0cdSOleksiy Vyalov 
492a7015092SGreg Clayton         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
49331412642SJim Ingham         // N.B. The attach should be synchronous.  It doesn't help much to get the prompt back between initiating the attach
49431412642SJim Ingham         // and the target actually stopping.  So even if the interpreter is set to be asynchronous, we wait for the stop
49531412642SJim Ingham         // ourselves here.
4965aee162fSJim Ingham 
49771337622SGreg Clayton         StateType state = eStateInvalid;
498dcb1d856SJim Ingham         Process *process = m_exe_ctx.GetProcessPtr();
499dcb1d856SJim Ingham 
500dcb1d856SJim Ingham         if (!StopProcessIfNecessary (process, state, result))
5015aee162fSJim Ingham             return false;
5025aee162fSJim Ingham 
50349bcfd80SEugene Zelenko         if (target == nullptr)
5045aee162fSJim Ingham         {
5055aee162fSJim Ingham             // If there isn't a current target create one.
5065aee162fSJim Ingham             TargetSP new_target_sp;
5075aee162fSJim Ingham             Error error;
5085aee162fSJim Ingham 
509a7015092SGreg Clayton             error = m_interpreter.GetDebugger().GetTargetList().CreateTarget(m_interpreter.GetDebugger(),
51049bcfd80SEugene Zelenko                                                                              nullptr,
51149bcfd80SEugene Zelenko                                                                              nullptr,
5125aee162fSJim Ingham                                                                              false,
51349bcfd80SEugene Zelenko                                                                              nullptr, // No platform options
5145aee162fSJim Ingham                                                                              new_target_sp);
5155aee162fSJim Ingham             target = new_target_sp.get();
51649bcfd80SEugene Zelenko             if (target == nullptr || error.Fail())
5175aee162fSJim Ingham             {
518b766a73dSGreg Clayton                 result.AppendError(error.AsCString("Error creating target"));
5195aee162fSJim Ingham                 return false;
5205aee162fSJim Ingham             }
521a7015092SGreg Clayton             m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target);
5225aee162fSJim Ingham         }
5235aee162fSJim Ingham 
5245aee162fSJim Ingham         // Record the old executable module, we want to issue a warning if the process of attaching changed the
5255aee162fSJim Ingham         // current executable (like somebody said "file foo" then attached to a PID whose executable was bar.)
5265aee162fSJim Ingham 
5275aee162fSJim Ingham         ModuleSP old_exec_module_sp = target->GetExecutableModule();
5285aee162fSJim Ingham         ArchSpec old_arch_spec = target->GetArchitecture();
5295aee162fSJim Ingham 
5305aee162fSJim Ingham         if (command.GetArgumentCount())
5315aee162fSJim Ingham         {
532fd54b368SJason Molenda             result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
5335aee162fSJim Ingham             result.SetStatus (eReturnStatusFailed);
534926af0cdSOleksiy Vyalov             return false;
53571337622SGreg Clayton         }
5365aee162fSJim Ingham 
537926af0cdSOleksiy Vyalov         m_interpreter.UpdateExecutionContext(nullptr);
53837386143SOleksiy Vyalov         StreamString stream;
53937386143SOleksiy Vyalov         const auto error = target->Attach(m_options.attach_info, &stream);
540144f3a9cSGreg Clayton         if (error.Success())
5413a0b9cdfSJim Ingham         {
54237386143SOleksiy Vyalov             ProcessSP process_sp (target->GetProcessSP());
54337386143SOleksiy Vyalov             if (process_sp)
544926af0cdSOleksiy Vyalov             {
545dc6224e0SGreg Clayton                 if (stream.GetData())
546dc6224e0SGreg Clayton                     result.AppendMessage(stream.GetData());
547bb3a283bSJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
54837386143SOleksiy Vyalov                 result.SetDidChangeProcessState (true);
549962260c8SJim Ingham                 result.SetAbnormalStopWasExpected(true);
550bb3a283bSJim Ingham             }
551aa739093SJohnny Chen             else
552aa739093SJohnny Chen             {
55337386143SOleksiy Vyalov                 result.AppendError("no error returned from Target::Attach, and target has no process");
554aa739093SJohnny Chen                 result.SetStatus (eReturnStatusFailed);
55544d93782SGreg Clayton             }
55644d93782SGreg Clayton         }
55744d93782SGreg Clayton         else
55844d93782SGreg Clayton         {
55944d93782SGreg Clayton             result.AppendErrorWithFormat ("attach failed: %s\n", error.AsCString());
56044d93782SGreg Clayton             result.SetStatus (eReturnStatusFailed);
561aa739093SJohnny Chen         }
5625aee162fSJim Ingham 
563926af0cdSOleksiy Vyalov         if (!result.Succeeded())
564926af0cdSOleksiy Vyalov             return false;
565926af0cdSOleksiy Vyalov 
5665aee162fSJim Ingham         // Okay, we're done.  Last step is to warn if the executable module has changed:
567513c26ceSGreg Clayton         char new_path[PATH_MAX];
568aa149cbdSGreg Clayton         ModuleSP new_exec_module_sp (target->GetExecutableModule());
5695aee162fSJim Ingham         if (!old_exec_module_sp)
5705aee162fSJim Ingham         {
571513c26ceSGreg Clayton             // We might not have a module if we attached to a raw pid...
572aa149cbdSGreg Clayton             if (new_exec_module_sp)
573513c26ceSGreg Clayton             {
574aa149cbdSGreg Clayton                 new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX);
575513c26ceSGreg Clayton                 result.AppendMessageWithFormat("Executable module set to \"%s\".\n", new_path);
576513c26ceSGreg Clayton             }
5775aee162fSJim Ingham         }
578aa149cbdSGreg Clayton         else if (old_exec_module_sp->GetFileSpec() != new_exec_module_sp->GetFileSpec())
5795aee162fSJim Ingham         {
580513c26ceSGreg Clayton             char old_path[PATH_MAX];
5815aee162fSJim Ingham 
5825aee162fSJim Ingham             old_exec_module_sp->GetFileSpec().GetPath (old_path, PATH_MAX);
583aa149cbdSGreg Clayton             new_exec_module_sp->GetFileSpec().GetPath (new_path, PATH_MAX);
5845aee162fSJim Ingham 
5855aee162fSJim Ingham             result.AppendWarningWithFormat("Executable module changed from \"%s\" to \"%s\".\n",
5865aee162fSJim Ingham                                                 old_path, new_path);
5875aee162fSJim Ingham         }
5885aee162fSJim Ingham 
5895aee162fSJim Ingham         if (!old_arch_spec.IsValid())
5905aee162fSJim Ingham         {
591c1b1f1eaSGreg Clayton             result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().GetTriple().getTriple().c_str());
5925aee162fSJim Ingham         }
593bf4b7be6SSean Callanan         else if (!old_arch_spec.IsExactMatch(target->GetArchitecture()))
5945aee162fSJim Ingham         {
5955aee162fSJim Ingham             result.AppendWarningWithFormat("Architecture changed from %s to %s.\n",
596c1b1f1eaSGreg Clayton                                            old_arch_spec.GetTriple().getTriple().c_str(),
597c1b1f1eaSGreg Clayton                                            target->GetArchitecture().GetTriple().getTriple().c_str());
5985aee162fSJim Ingham         }
599a95ce623SJohnny Chen 
600a95ce623SJohnny Chen         // This supports the use-case scenario of immediately continuing the process once attached.
601a95ce623SJohnny Chen         if (m_options.attach_info.GetContinueOnceAttached())
6025bcaf583SSean Callanan             m_interpreter.HandleCommand("process continue", eLazyBoolNo, result);
603926af0cdSOleksiy Vyalov 
6045aee162fSJim Ingham         return result.Succeeded();
6055aee162fSJim Ingham     }
6065aee162fSJim Ingham 
60730fdc8d8SChris Lattner     CommandOptions m_options;
60830fdc8d8SChris Lattner };
60930fdc8d8SChris Lattner 
610e0d378b3SGreg Clayton OptionDefinition
61130fdc8d8SChris Lattner CommandObjectProcessAttach::CommandOptions::g_option_table[] =
61230fdc8d8SChris Lattner {
613*ac9c3a62SKate Stone   // clang-format off
61449bcfd80SEugene Zelenko   {LLDB_OPT_SET_ALL, false, "continue",         'c', OptionParser::eNoArgument,       nullptr, nullptr, 0, eArgTypeNone,         "Immediately continue the process once attached."},
61549bcfd80SEugene Zelenko   {LLDB_OPT_SET_ALL, false, "plugin",           'P', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePlugin,       "Name of the process plugin you want to use."},
61649bcfd80SEugene Zelenko   {LLDB_OPT_SET_1,   false, "pid",              'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePid,          "The process ID of an existing process to attach to."},
61749bcfd80SEugene Zelenko   {LLDB_OPT_SET_2,   false, "name",             'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeProcessName,  "The name of the process to attach to."},
61849bcfd80SEugene Zelenko   {LLDB_OPT_SET_2,   false, "include-existing", 'i', OptionParser::eNoArgument,       nullptr, nullptr, 0, eArgTypeNone,         "Include existing processes when doing attach -w."},
61949bcfd80SEugene Zelenko   {LLDB_OPT_SET_2,   false, "waitfor",          'w', OptionParser::eNoArgument,       nullptr, nullptr, 0, eArgTypeNone,         "Wait for the process with <process-name> to launch."},
62049bcfd80SEugene Zelenko   {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr}
621*ac9c3a62SKate Stone   // clang-format on
62230fdc8d8SChris Lattner };
62330fdc8d8SChris Lattner 
62430fdc8d8SChris Lattner //-------------------------------------------------------------------------
62530fdc8d8SChris Lattner // CommandObjectProcessContinue
62630fdc8d8SChris Lattner //-------------------------------------------------------------------------
627bb9caf73SJim Ingham #pragma mark CommandObjectProcessContinue
62830fdc8d8SChris Lattner 
6295a988416SJim Ingham class CommandObjectProcessContinue : public CommandObjectParsed
63030fdc8d8SChris Lattner {
63130fdc8d8SChris Lattner public:
632a7015092SGreg Clayton     CommandObjectProcessContinue (CommandInterpreter &interpreter) :
6335a988416SJim Ingham         CommandObjectParsed (interpreter,
634a7015092SGreg Clayton                              "process continue",
635e3d26315SCaroline Tice                              "Continue execution of all threads in the current process.",
63630fdc8d8SChris Lattner                              "process continue",
637e87764f2SEnrico Granata                              eCommandRequiresProcess       |
638e87764f2SEnrico Granata                              eCommandTryTargetAPILock      |
639e87764f2SEnrico Granata                              eCommandProcessMustBeLaunched |
640e87764f2SEnrico Granata                              eCommandProcessMustBePaused   ),
641e1cfbc79STodd Fiala         m_options()
64230fdc8d8SChris Lattner     {
64330fdc8d8SChris Lattner     }
64430fdc8d8SChris Lattner 
64549bcfd80SEugene Zelenko     ~CommandObjectProcessContinue() override = default;
64630fdc8d8SChris Lattner 
6475a988416SJim Ingham protected:
6480e41084aSJim Ingham     class CommandOptions : public Options
6490e41084aSJim Ingham     {
6500e41084aSJim Ingham     public:
651e1cfbc79STodd Fiala         CommandOptions() :
652e1cfbc79STodd Fiala             Options()
6530e41084aSJim Ingham         {
6540e41084aSJim Ingham             // Keep default values of all options in one place: OptionParsingStarting ()
655e1cfbc79STodd Fiala             OptionParsingStarting(nullptr);
6560e41084aSJim Ingham         }
6570e41084aSJim Ingham 
65849bcfd80SEugene Zelenko         ~CommandOptions() override = default;
6590e41084aSJim Ingham 
6600e41084aSJim Ingham         Error
661e1cfbc79STodd Fiala         SetOptionValue(uint32_t option_idx, const char *option_arg,
662e1cfbc79STodd Fiala                        ExecutionContext *execution_context) override
6630e41084aSJim Ingham         {
6640e41084aSJim Ingham             Error error;
6653bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
6660e41084aSJim Ingham             bool success = false;
6670e41084aSJim Ingham             switch (short_option)
6680e41084aSJim Ingham             {
6690e41084aSJim Ingham                 case 'i':
6705275aaa0SVince Harron                     m_ignore = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
6710e41084aSJim Ingham                     if (!success)
6720e41084aSJim Ingham                         error.SetErrorStringWithFormat ("invalid value for ignore option: \"%s\", should be a number.", option_arg);
6730e41084aSJim Ingham                     break;
6740e41084aSJim Ingham 
6750e41084aSJim Ingham                 default:
6760e41084aSJim Ingham                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
6770e41084aSJim Ingham                     break;
6780e41084aSJim Ingham             }
6790e41084aSJim Ingham             return error;
6800e41084aSJim Ingham         }
6810e41084aSJim Ingham 
6820e41084aSJim Ingham         void
683e1cfbc79STodd Fiala         OptionParsingStarting(ExecutionContext *execution_context) override
6840e41084aSJim Ingham         {
6850e41084aSJim Ingham             m_ignore = 0;
6860e41084aSJim Ingham         }
6870e41084aSJim Ingham 
6880e41084aSJim Ingham         const OptionDefinition*
68913d21e9aSBruce Mitchener         GetDefinitions () override
6900e41084aSJim Ingham         {
6910e41084aSJim Ingham             return g_option_table;
6920e41084aSJim Ingham         }
6930e41084aSJim Ingham 
6940e41084aSJim Ingham         // Options table: Required for subclasses of Options.
6950e41084aSJim Ingham 
6960e41084aSJim Ingham         static OptionDefinition g_option_table[];
6970e41084aSJim Ingham 
6980e41084aSJim Ingham         uint32_t m_ignore;
6990e41084aSJim Ingham     };
7000e41084aSJim Ingham 
70130fdc8d8SChris Lattner     bool
70213d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
70330fdc8d8SChris Lattner     {
704f9fc609fSGreg Clayton         Process *process = m_exe_ctx.GetProcessPtr();
705a7015092SGreg Clayton         bool synchronous_execution = m_interpreter.GetSynchronous ();
70630fdc8d8SChris Lattner         StateType state = process->GetState();
70730fdc8d8SChris Lattner         if (state == eStateStopped)
70830fdc8d8SChris Lattner         {
70930fdc8d8SChris Lattner             if (command.GetArgumentCount() != 0)
71030fdc8d8SChris Lattner             {
71130fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("The '%s' command does not take any arguments.\n", m_cmd_name.c_str());
71230fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
71330fdc8d8SChris Lattner                 return false;
71430fdc8d8SChris Lattner             }
71530fdc8d8SChris Lattner 
7160e41084aSJim Ingham             if (m_options.m_ignore > 0)
7170e41084aSJim Ingham             {
7188d94ba0fSJim Ingham                 ThreadSP sel_thread_sp(GetDefaultThread()->shared_from_this());
7190e41084aSJim Ingham                 if (sel_thread_sp)
7200e41084aSJim Ingham                 {
7210e41084aSJim Ingham                     StopInfoSP stop_info_sp = sel_thread_sp->GetStopInfo();
7220e41084aSJim Ingham                     if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonBreakpoint)
7230e41084aSJim Ingham                     {
724c7bece56SGreg Clayton                         lldb::break_id_t bp_site_id = (lldb::break_id_t)stop_info_sp->GetValue();
7250e41084aSJim Ingham                         BreakpointSiteSP bp_site_sp(process->GetBreakpointSiteList().FindByID(bp_site_id));
7260e41084aSJim Ingham                         if (bp_site_sp)
7270e41084aSJim Ingham                         {
728c7bece56SGreg Clayton                             const size_t num_owners = bp_site_sp->GetNumberOfOwners();
729c7bece56SGreg Clayton                             for (size_t i = 0; i < num_owners; i++)
7300e41084aSJim Ingham                             {
7310e41084aSJim Ingham                                 Breakpoint &bp_ref = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
7320e41084aSJim Ingham                                 if (!bp_ref.IsInternal())
7330e41084aSJim Ingham                                 {
7340e41084aSJim Ingham                                     bp_ref.SetIgnoreCount(m_options.m_ignore);
7350e41084aSJim Ingham                                 }
7360e41084aSJim Ingham                             }
7370e41084aSJim Ingham                         }
7380e41084aSJim Ingham                     }
7390e41084aSJim Ingham                 }
7400e41084aSJim Ingham             }
7410e41084aSJim Ingham 
74241f2b940SJim Ingham             {  // Scope for thread list mutex:
743bb19a13cSSaleem Abdulrasool                 std::lock_guard<std::recursive_mutex> guard(process->GetThreadList().GetMutex());
74430fdc8d8SChris Lattner                 const uint32_t num_threads = process->GetThreadList().GetSize();
74530fdc8d8SChris Lattner 
74630fdc8d8SChris Lattner                 // Set the actions that the threads should each take when resuming
74730fdc8d8SChris Lattner                 for (uint32_t idx=0; idx<num_threads; ++idx)
74830fdc8d8SChris Lattner                 {
7496c9ed91cSJim Ingham                     const bool override_suspend = false;
7506c9ed91cSJim Ingham                     process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState (eStateRunning, override_suspend);
75130fdc8d8SChris Lattner                 }
75241f2b940SJim Ingham             }
75330fdc8d8SChris Lattner 
7544446487dSPavel Labath             const uint32_t iohandler_id = process->GetIOHandlerID();
7554446487dSPavel Labath 
756dc6224e0SGreg Clayton             StreamString stream;
757dc6224e0SGreg Clayton             Error error;
758dc6224e0SGreg Clayton             if (synchronous_execution)
759dc6224e0SGreg Clayton                 error = process->ResumeSynchronous (&stream);
760dc6224e0SGreg Clayton             else
761dc6224e0SGreg Clayton                 error = process->Resume ();
762a3b89e27STodd Fiala 
76330fdc8d8SChris Lattner             if (error.Success())
76430fdc8d8SChris Lattner             {
765a3b89e27STodd Fiala                 // There is a race condition where this thread will return up the call stack to the main command
766a3b89e27STodd Fiala                  // handler and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has
767a3b89e27STodd Fiala                  // a chance to call PushProcessIOHandler().
7684446487dSPavel Labath                 process->SyncIOHandler(iohandler_id, 2000);
769a3b89e27STodd Fiala 
770d01b2953SDaniel Malea                 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
77130fdc8d8SChris Lattner                 if (synchronous_execution)
77230fdc8d8SChris Lattner                 {
773dc6224e0SGreg Clayton                     // If any state changed events had anything to say, add that to the result
774dc6224e0SGreg Clayton                     if (stream.GetData())
775dc6224e0SGreg Clayton                         result.AppendMessage(stream.GetData());
77630fdc8d8SChris Lattner 
77730fdc8d8SChris Lattner                     result.SetDidChangeProcessState (true);
77830fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
77930fdc8d8SChris Lattner                 }
78030fdc8d8SChris Lattner                 else
78130fdc8d8SChris Lattner                 {
78230fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusSuccessContinuingNoResult);
78330fdc8d8SChris Lattner                 }
78430fdc8d8SChris Lattner             }
78530fdc8d8SChris Lattner             else
78630fdc8d8SChris Lattner             {
78730fdc8d8SChris Lattner                 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
78830fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
78930fdc8d8SChris Lattner             }
79030fdc8d8SChris Lattner         }
79130fdc8d8SChris Lattner         else
79230fdc8d8SChris Lattner         {
79330fdc8d8SChris Lattner             result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
79430fdc8d8SChris Lattner                                          StateAsCString(state));
79530fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
79630fdc8d8SChris Lattner         }
79730fdc8d8SChris Lattner         return result.Succeeded();
79830fdc8d8SChris Lattner     }
7990e41084aSJim Ingham 
8000e41084aSJim Ingham     Options *
80113d21e9aSBruce Mitchener     GetOptions () override
8020e41084aSJim Ingham     {
8030e41084aSJim Ingham         return &m_options;
8040e41084aSJim Ingham     }
8050e41084aSJim Ingham 
8060e41084aSJim Ingham     CommandOptions m_options;
8070e41084aSJim Ingham };
8080e41084aSJim Ingham 
8090e41084aSJim Ingham OptionDefinition
8100e41084aSJim Ingham CommandObjectProcessContinue::CommandOptions::g_option_table[] =
8110e41084aSJim Ingham {
812*ac9c3a62SKate Stone   // clang-format off
813*ac9c3a62SKate Stone   {LLDB_OPT_SET_ALL, false, "ignore-count",'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger, "Ignore <N> crossings of the breakpoint (if it exists) for the currently selected thread."},
81449bcfd80SEugene Zelenko   {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr}
815*ac9c3a62SKate Stone   // clang-format on
81630fdc8d8SChris Lattner };
81730fdc8d8SChris Lattner 
81830fdc8d8SChris Lattner //-------------------------------------------------------------------------
81930fdc8d8SChris Lattner // CommandObjectProcessDetach
82030fdc8d8SChris Lattner //-------------------------------------------------------------------------
821bb9caf73SJim Ingham #pragma mark CommandObjectProcessDetach
82230fdc8d8SChris Lattner 
8235a988416SJim Ingham class CommandObjectProcessDetach : public CommandObjectParsed
82430fdc8d8SChris Lattner {
82530fdc8d8SChris Lattner public:
826acff8950SJim Ingham     class CommandOptions : public Options
827acff8950SJim Ingham     {
828acff8950SJim Ingham     public:
829e1cfbc79STodd Fiala         CommandOptions() :
830e1cfbc79STodd Fiala             Options()
831acff8950SJim Ingham         {
832e1cfbc79STodd Fiala             OptionParsingStarting(nullptr);
833acff8950SJim Ingham         }
834acff8950SJim Ingham 
83549bcfd80SEugene Zelenko         ~CommandOptions() override = default;
836acff8950SJim Ingham 
837acff8950SJim Ingham         Error
838e1cfbc79STodd Fiala         SetOptionValue(uint32_t option_idx, const char *option_arg,
839e1cfbc79STodd Fiala                        ExecutionContext *execution_context) override
840acff8950SJim Ingham         {
841acff8950SJim Ingham             Error error;
842acff8950SJim Ingham             const int short_option = m_getopt_table[option_idx].val;
843acff8950SJim Ingham 
844acff8950SJim Ingham             switch (short_option)
845acff8950SJim Ingham             {
846acff8950SJim Ingham                 case 's':
847acff8950SJim Ingham                     bool tmp_result;
848acff8950SJim Ingham                     bool success;
849acff8950SJim Ingham                     tmp_result = Args::StringToBoolean(option_arg, false, &success);
850acff8950SJim Ingham                     if (!success)
851acff8950SJim Ingham                         error.SetErrorStringWithFormat("invalid boolean option: \"%s\"", option_arg);
852acff8950SJim Ingham                     else
853acff8950SJim Ingham                     {
854acff8950SJim Ingham                         if (tmp_result)
855acff8950SJim Ingham                             m_keep_stopped = eLazyBoolYes;
856acff8950SJim Ingham                         else
857acff8950SJim Ingham                             m_keep_stopped = eLazyBoolNo;
858acff8950SJim Ingham                     }
859acff8950SJim Ingham                     break;
860acff8950SJim Ingham                 default:
861acff8950SJim Ingham                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
862acff8950SJim Ingham                     break;
863acff8950SJim Ingham             }
864acff8950SJim Ingham             return error;
865acff8950SJim Ingham         }
866acff8950SJim Ingham 
867acff8950SJim Ingham         void
868e1cfbc79STodd Fiala         OptionParsingStarting(ExecutionContext *execution_context) override
869acff8950SJim Ingham         {
870acff8950SJim Ingham             m_keep_stopped = eLazyBoolCalculate;
871acff8950SJim Ingham         }
872acff8950SJim Ingham 
873acff8950SJim Ingham         const OptionDefinition*
87413d21e9aSBruce Mitchener         GetDefinitions () override
875acff8950SJim Ingham         {
876acff8950SJim Ingham             return g_option_table;
877acff8950SJim Ingham         }
878acff8950SJim Ingham 
879acff8950SJim Ingham         // Options table: Required for subclasses of Options.
880acff8950SJim Ingham 
881acff8950SJim Ingham         static OptionDefinition g_option_table[];
882acff8950SJim Ingham 
883acff8950SJim Ingham         // Instance variables to hold the values for command options.
884acff8950SJim Ingham         LazyBool m_keep_stopped;
885acff8950SJim Ingham     };
88630fdc8d8SChris Lattner 
8877428a18cSKate Stone     CommandObjectProcessDetach(CommandInterpreter &interpreter)
8887428a18cSKate Stone         : CommandObjectParsed(interpreter, "process detach", "Detach from the current target process.",
889a7015092SGreg Clayton                               "process detach",
8907428a18cSKate Stone                               eCommandRequiresProcess | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched),
891e1cfbc79STodd Fiala           m_options()
89230fdc8d8SChris Lattner     {
89330fdc8d8SChris Lattner     }
89430fdc8d8SChris Lattner 
89549bcfd80SEugene Zelenko     ~CommandObjectProcessDetach() override = default;
89630fdc8d8SChris Lattner 
897acff8950SJim Ingham     Options *
89813d21e9aSBruce Mitchener     GetOptions () override
899acff8950SJim Ingham     {
900acff8950SJim Ingham         return &m_options;
901acff8950SJim Ingham     }
902acff8950SJim Ingham 
9035a988416SJim Ingham protected:
90430fdc8d8SChris Lattner     bool
90513d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
90630fdc8d8SChris Lattner     {
907f9fc609fSGreg Clayton         Process *process = m_exe_ctx.GetProcessPtr();
908acff8950SJim Ingham         // FIXME: This will be a Command Option:
909acff8950SJim Ingham         bool keep_stopped;
910acff8950SJim Ingham         if (m_options.m_keep_stopped == eLazyBoolCalculate)
911acff8950SJim Ingham         {
912acff8950SJim Ingham             // Check the process default:
91349bcfd80SEugene Zelenko             keep_stopped = process->GetDetachKeepsStopped();
914acff8950SJim Ingham         }
915acff8950SJim Ingham         else if (m_options.m_keep_stopped == eLazyBoolYes)
916acff8950SJim Ingham             keep_stopped = true;
917acff8950SJim Ingham         else
918acff8950SJim Ingham             keep_stopped = false;
919acff8950SJim Ingham 
920acff8950SJim Ingham         Error error (process->Detach(keep_stopped));
92130fdc8d8SChris Lattner         if (error.Success())
92230fdc8d8SChris Lattner         {
92330fdc8d8SChris Lattner             result.SetStatus (eReturnStatusSuccessFinishResult);
92430fdc8d8SChris Lattner         }
92530fdc8d8SChris Lattner         else
92630fdc8d8SChris Lattner         {
92730fdc8d8SChris Lattner             result.AppendErrorWithFormat ("Detach failed: %s\n", error.AsCString());
92830fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
92930fdc8d8SChris Lattner             return false;
93030fdc8d8SChris Lattner         }
93130fdc8d8SChris Lattner         return result.Succeeded();
93230fdc8d8SChris Lattner     }
933acff8950SJim Ingham 
934acff8950SJim Ingham     CommandOptions m_options;
935acff8950SJim Ingham };
936acff8950SJim Ingham 
937acff8950SJim Ingham OptionDefinition
938acff8950SJim Ingham CommandObjectProcessDetach::CommandOptions::g_option_table[] =
939acff8950SJim Ingham {
940*ac9c3a62SKate Stone   // clang-format off
94149bcfd80SEugene 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)."},
94249bcfd80SEugene Zelenko   {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr}
943*ac9c3a62SKate Stone   // clang-format on
94430fdc8d8SChris Lattner };
94530fdc8d8SChris Lattner 
94630fdc8d8SChris Lattner //-------------------------------------------------------------------------
947b766a73dSGreg Clayton // CommandObjectProcessConnect
948b766a73dSGreg Clayton //-------------------------------------------------------------------------
949b766a73dSGreg Clayton #pragma mark CommandObjectProcessConnect
950b766a73dSGreg Clayton 
9515a988416SJim Ingham class CommandObjectProcessConnect : public CommandObjectParsed
952b766a73dSGreg Clayton {
953b766a73dSGreg Clayton public:
954b766a73dSGreg Clayton     class CommandOptions : public Options
955b766a73dSGreg Clayton     {
956b766a73dSGreg Clayton     public:
957e1cfbc79STodd Fiala         CommandOptions() :
958e1cfbc79STodd Fiala             Options()
959b766a73dSGreg Clayton         {
960f6b8b581SGreg Clayton             // Keep default values of all options in one place: OptionParsingStarting ()
961e1cfbc79STodd Fiala             OptionParsingStarting(nullptr);
962b766a73dSGreg Clayton         }
963b766a73dSGreg Clayton 
96449bcfd80SEugene Zelenko         ~CommandOptions() override = default;
965b766a73dSGreg Clayton 
966b766a73dSGreg Clayton         Error
967e1cfbc79STodd Fiala         SetOptionValue(uint32_t option_idx, const char *option_arg,
968e1cfbc79STodd Fiala                        ExecutionContext *execution_context) override
969b766a73dSGreg Clayton         {
970b766a73dSGreg Clayton             Error error;
9713bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
972b766a73dSGreg Clayton 
973b766a73dSGreg Clayton             switch (short_option)
974b766a73dSGreg Clayton             {
975b766a73dSGreg Clayton             case 'p':
976b766a73dSGreg Clayton                 plugin_name.assign (option_arg);
977b766a73dSGreg Clayton                 break;
978b766a73dSGreg Clayton 
979b766a73dSGreg Clayton             default:
98086edbf41SGreg Clayton                 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
981b766a73dSGreg Clayton                 break;
982b766a73dSGreg Clayton             }
983b766a73dSGreg Clayton             return error;
984b766a73dSGreg Clayton         }
985b766a73dSGreg Clayton 
986b766a73dSGreg Clayton         void
987e1cfbc79STodd Fiala         OptionParsingStarting(ExecutionContext *execution_context) override
988b766a73dSGreg Clayton         {
989b766a73dSGreg Clayton             plugin_name.clear();
990b766a73dSGreg Clayton         }
991b766a73dSGreg Clayton 
992e0d378b3SGreg Clayton         const OptionDefinition*
99313d21e9aSBruce Mitchener         GetDefinitions () override
994b766a73dSGreg Clayton         {
995b766a73dSGreg Clayton             return g_option_table;
996b766a73dSGreg Clayton         }
997b766a73dSGreg Clayton 
998b766a73dSGreg Clayton         // Options table: Required for subclasses of Options.
999b766a73dSGreg Clayton 
1000e0d378b3SGreg Clayton         static OptionDefinition g_option_table[];
1001b766a73dSGreg Clayton 
1002b766a73dSGreg Clayton         // Instance variables to hold the values for command options.
1003b766a73dSGreg Clayton 
1004b766a73dSGreg Clayton         std::string plugin_name;
1005b766a73dSGreg Clayton     };
1006b766a73dSGreg Clayton 
1007b766a73dSGreg Clayton     CommandObjectProcessConnect (CommandInterpreter &interpreter) :
10085a988416SJim Ingham         CommandObjectParsed (interpreter,
1009b766a73dSGreg Clayton                              "process connect",
1010b766a73dSGreg Clayton                              "Connect to a remote debug service.",
1011b766a73dSGreg Clayton                              "process connect <remote-url>",
1012eb0103f2SGreg Clayton                              0),
1013e1cfbc79STodd Fiala         m_options()
1014b766a73dSGreg Clayton     {
1015b766a73dSGreg Clayton     }
1016b766a73dSGreg Clayton 
101749bcfd80SEugene Zelenko     ~CommandObjectProcessConnect() override = default;
1018b766a73dSGreg Clayton 
10195a988416SJim Ingham     Options *
102013d21e9aSBruce Mitchener     GetOptions () override
10215a988416SJim Ingham     {
10225a988416SJim Ingham         return &m_options;
10235a988416SJim Ingham     }
10245a988416SJim Ingham 
10255a988416SJim Ingham protected:
1026b766a73dSGreg Clayton     bool
102713d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
1028b766a73dSGreg Clayton     {
1029ccd6cffbSTamas Berghammer         if (command.GetArgumentCount() != 1)
1030b766a73dSGreg Clayton         {
1031ccd6cffbSTamas Berghammer             result.AppendErrorWithFormat ("'%s' takes exactly one argument:\nUsage: %s\n",
1032ccd6cffbSTamas Berghammer                                           m_cmd_name.c_str(),
1033ccd6cffbSTamas Berghammer                                           m_cmd_syntax.c_str());
1034ccd6cffbSTamas Berghammer             result.SetStatus (eReturnStatusFailed);
1035ccd6cffbSTamas Berghammer             return false;
1036ccd6cffbSTamas Berghammer         }
1037ccd6cffbSTamas Berghammer 
1038ccd6cffbSTamas Berghammer         Process *process = m_exe_ctx.GetProcessPtr();
1039ccd6cffbSTamas Berghammer         if (process && process->IsAlive())
1040b766a73dSGreg Clayton         {
1041d01b2953SDaniel Malea             result.AppendErrorWithFormat ("Process %" PRIu64 " is currently being debugged, kill the process before connecting.\n",
1042b766a73dSGreg Clayton                                           process->GetID());
1043b766a73dSGreg Clayton             result.SetStatus (eReturnStatusFailed);
1044b766a73dSGreg Clayton             return false;
1045b766a73dSGreg Clayton         }
1046b766a73dSGreg Clayton 
1047ccd6cffbSTamas Berghammer         const char *plugin_name = nullptr;
1048b766a73dSGreg Clayton         if (!m_options.plugin_name.empty())
1049b766a73dSGreg Clayton             plugin_name = m_options.plugin_name.c_str();
1050b766a73dSGreg Clayton 
1051ccd6cffbSTamas Berghammer         Error error;
1052ccd6cffbSTamas Berghammer         Debugger& debugger = m_interpreter.GetDebugger();
1053ccd6cffbSTamas Berghammer         PlatformSP platform_sp = m_interpreter.GetPlatform(true);
1054ccd6cffbSTamas Berghammer         ProcessSP process_sp = platform_sp->ConnectProcess(command.GetArgumentAtIndex(0),
1055ccd6cffbSTamas Berghammer                                                            plugin_name,
1056ccd6cffbSTamas Berghammer                                                            debugger,
1057ccd6cffbSTamas Berghammer                                                            debugger.GetSelectedTarget().get(),
1058ccd6cffbSTamas Berghammer                                                            error);
1059ccd6cffbSTamas Berghammer         if (error.Fail() || process_sp == nullptr)
1060b766a73dSGreg Clayton         {
1061ccd6cffbSTamas Berghammer             result.AppendError(error.AsCString("Error connecting to the process"));
1062b766a73dSGreg Clayton             result.SetStatus (eReturnStatusFailed);
1063b766a73dSGreg Clayton             return false;
1064b766a73dSGreg Clayton         }
1065ccd6cffbSTamas Berghammer         return true;
1066b766a73dSGreg Clayton     }
1067b766a73dSGreg Clayton 
1068b766a73dSGreg Clayton     CommandOptions m_options;
1069b766a73dSGreg Clayton };
1070b766a73dSGreg Clayton 
1071e0d378b3SGreg Clayton OptionDefinition
1072b766a73dSGreg Clayton CommandObjectProcessConnect::CommandOptions::g_option_table[] =
1073b766a73dSGreg Clayton {
1074*ac9c3a62SKate Stone   // clang-format off
107549bcfd80SEugene Zelenko   {LLDB_OPT_SET_ALL, false, "plugin", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePlugin, "Name of the process plugin you want to use."},
107649bcfd80SEugene Zelenko   {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr}
1077*ac9c3a62SKate Stone   // clang-format on
1078b766a73dSGreg Clayton };
1079b766a73dSGreg Clayton 
1080b766a73dSGreg Clayton //-------------------------------------------------------------------------
1081998255bfSGreg Clayton // CommandObjectProcessPlugin
1082998255bfSGreg Clayton //-------------------------------------------------------------------------
1083998255bfSGreg Clayton #pragma mark CommandObjectProcessPlugin
1084998255bfSGreg Clayton 
1085998255bfSGreg Clayton class CommandObjectProcessPlugin : public CommandObjectProxy
1086998255bfSGreg Clayton {
1087998255bfSGreg Clayton public:
10887428a18cSKate Stone     CommandObjectProcessPlugin(CommandInterpreter &interpreter)
10897428a18cSKate Stone         : CommandObjectProxy(interpreter, "process plugin",
10907428a18cSKate Stone                              "Send a custom command to the current target process plug-in.", "process plugin <args>", 0)
1091998255bfSGreg Clayton     {
1092998255bfSGreg Clayton     }
1093998255bfSGreg Clayton 
109449bcfd80SEugene Zelenko     ~CommandObjectProcessPlugin() override = default;
1095998255bfSGreg Clayton 
109613d21e9aSBruce Mitchener     CommandObject *
109713d21e9aSBruce Mitchener     GetProxyCommandObject() override
1098998255bfSGreg Clayton     {
1099e05b2efeSGreg Clayton         Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
1100998255bfSGreg Clayton         if (process)
1101998255bfSGreg Clayton             return process->GetPluginCommandObject();
110249bcfd80SEugene Zelenko         return nullptr;
1103998255bfSGreg Clayton     }
1104998255bfSGreg Clayton };
1105998255bfSGreg Clayton 
1106998255bfSGreg Clayton //-------------------------------------------------------------------------
11078f343b09SGreg Clayton // CommandObjectProcessLoad
11088f343b09SGreg Clayton //-------------------------------------------------------------------------
1109bb9caf73SJim Ingham #pragma mark CommandObjectProcessLoad
11108f343b09SGreg Clayton 
11115a988416SJim Ingham class CommandObjectProcessLoad : public CommandObjectParsed
11128f343b09SGreg Clayton {
11138f343b09SGreg Clayton public:
11144fbd67acSTamas Berghammer     class CommandOptions : public Options
11154fbd67acSTamas Berghammer     {
11164fbd67acSTamas Berghammer     public:
1117e1cfbc79STodd Fiala         CommandOptions() :
1118e1cfbc79STodd Fiala             Options()
11194fbd67acSTamas Berghammer         {
11204fbd67acSTamas Berghammer             // Keep default values of all options in one place: OptionParsingStarting ()
1121e1cfbc79STodd Fiala             OptionParsingStarting(nullptr);
11224fbd67acSTamas Berghammer         }
11234fbd67acSTamas Berghammer 
11244fbd67acSTamas Berghammer         ~CommandOptions() override = default;
11254fbd67acSTamas Berghammer 
11264fbd67acSTamas Berghammer         Error
1127e1cfbc79STodd Fiala         SetOptionValue(uint32_t option_idx, const char *option_arg,
1128e1cfbc79STodd Fiala                        ExecutionContext *execution_context) override
11294fbd67acSTamas Berghammer         {
11304fbd67acSTamas Berghammer             Error error;
11314fbd67acSTamas Berghammer             const int short_option = m_getopt_table[option_idx].val;
11324fbd67acSTamas Berghammer             switch (short_option)
11334fbd67acSTamas Berghammer             {
11344fbd67acSTamas Berghammer             case 'i':
11354fbd67acSTamas Berghammer                 do_install = true;
11364fbd67acSTamas Berghammer                 if (option_arg && option_arg[0])
11374fbd67acSTamas Berghammer                     install_path.SetFile(option_arg, false);
11384fbd67acSTamas Berghammer                 break;
11394fbd67acSTamas Berghammer             default:
11404fbd67acSTamas Berghammer                 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
11414fbd67acSTamas Berghammer                 break;
11424fbd67acSTamas Berghammer             }
11434fbd67acSTamas Berghammer             return error;
11444fbd67acSTamas Berghammer         }
11454fbd67acSTamas Berghammer 
11464fbd67acSTamas Berghammer         void
1147e1cfbc79STodd Fiala         OptionParsingStarting(ExecutionContext *execution_context) override
11484fbd67acSTamas Berghammer         {
11494fbd67acSTamas Berghammer             do_install = false;
11504fbd67acSTamas Berghammer             install_path.Clear();
11514fbd67acSTamas Berghammer         }
11524fbd67acSTamas Berghammer 
11534fbd67acSTamas Berghammer         const OptionDefinition*
11544fbd67acSTamas Berghammer         GetDefinitions () override
11554fbd67acSTamas Berghammer         {
11564fbd67acSTamas Berghammer             return g_option_table;
11574fbd67acSTamas Berghammer         }
11584fbd67acSTamas Berghammer 
11594fbd67acSTamas Berghammer         // Options table: Required for subclasses of Options.
11604fbd67acSTamas Berghammer         static OptionDefinition g_option_table[];
11614fbd67acSTamas Berghammer 
11624fbd67acSTamas Berghammer         // Instance variables to hold the values for command options.
11634fbd67acSTamas Berghammer         bool do_install;
11644fbd67acSTamas Berghammer         FileSpec install_path;
11654fbd67acSTamas Berghammer     };
11668f343b09SGreg Clayton 
11678f343b09SGreg Clayton     CommandObjectProcessLoad (CommandInterpreter &interpreter) :
11685a988416SJim Ingham         CommandObjectParsed (interpreter,
11698f343b09SGreg Clayton                              "process load",
11708f343b09SGreg Clayton                              "Load a shared library into the current process.",
11718f343b09SGreg Clayton                              "process load <filename> [<filename> ...]",
1172e87764f2SEnrico Granata                              eCommandRequiresProcess       |
1173e87764f2SEnrico Granata                              eCommandTryTargetAPILock      |
1174e87764f2SEnrico Granata                              eCommandProcessMustBeLaunched |
11754fbd67acSTamas Berghammer                              eCommandProcessMustBePaused   ),
1176e1cfbc79STodd Fiala         m_options()
11778f343b09SGreg Clayton     {
11788f343b09SGreg Clayton     }
11798f343b09SGreg Clayton 
11804fbd67acSTamas Berghammer     ~CommandObjectProcessLoad() override = default;
11814fbd67acSTamas Berghammer 
11824fbd67acSTamas Berghammer     Options *
11834fbd67acSTamas Berghammer     GetOptions () override
11848f343b09SGreg Clayton     {
11854fbd67acSTamas Berghammer         return &m_options;
11868f343b09SGreg Clayton     }
11878f343b09SGreg Clayton 
11885a988416SJim Ingham protected:
11898f343b09SGreg Clayton     bool
119013d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
11918f343b09SGreg Clayton     {
1192f9fc609fSGreg Clayton         Process *process = m_exe_ctx.GetProcessPtr();
11938f343b09SGreg Clayton 
1194c7bece56SGreg Clayton         const size_t argc = command.GetArgumentCount();
11958f343b09SGreg Clayton         for (uint32_t i = 0; i < argc; ++i)
11968f343b09SGreg Clayton         {
11978f343b09SGreg Clayton             Error error;
11983cb132a0STamas Berghammer             PlatformSP platform = process->GetTarget().GetPlatform();
11994fbd67acSTamas Berghammer             const char *image_path = command.GetArgumentAtIndex(i);
12004fbd67acSTamas Berghammer             uint32_t image_token = LLDB_INVALID_IMAGE_TOKEN;
12014fbd67acSTamas Berghammer 
12024fbd67acSTamas Berghammer             if (!m_options.do_install)
12034fbd67acSTamas Berghammer             {
12044fbd67acSTamas Berghammer                 FileSpec image_spec (image_path, false);
12053cb132a0STamas Berghammer                 platform->ResolveRemotePath(image_spec, image_spec);
12064fbd67acSTamas Berghammer                 image_token = platform->LoadImage(process, FileSpec(), image_spec, error);
12074fbd67acSTamas Berghammer             }
12084fbd67acSTamas Berghammer             else if (m_options.install_path)
12094fbd67acSTamas Berghammer             {
12104fbd67acSTamas Berghammer                 FileSpec image_spec (image_path, true);
12114fbd67acSTamas Berghammer                 platform->ResolveRemotePath(m_options.install_path, m_options.install_path);
12124fbd67acSTamas Berghammer                 image_token = platform->LoadImage(process, image_spec, m_options.install_path, error);
12134fbd67acSTamas Berghammer             }
12144fbd67acSTamas Berghammer             else
12154fbd67acSTamas Berghammer             {
12164fbd67acSTamas Berghammer                 FileSpec image_spec (image_path, true);
12174fbd67acSTamas Berghammer                 image_token = platform->LoadImage(process, image_spec, FileSpec(), error);
12184fbd67acSTamas Berghammer             }
12194fbd67acSTamas Berghammer 
12208f343b09SGreg Clayton             if (image_token != LLDB_INVALID_IMAGE_TOKEN)
12218f343b09SGreg Clayton             {
12228f343b09SGreg Clayton                 result.AppendMessageWithFormat ("Loading \"%s\"...ok\nImage %u loaded.\n", image_path, image_token);
12238f343b09SGreg Clayton                 result.SetStatus (eReturnStatusSuccessFinishResult);
12248f343b09SGreg Clayton             }
12258f343b09SGreg Clayton             else
12268f343b09SGreg Clayton             {
12278f343b09SGreg Clayton                 result.AppendErrorWithFormat ("failed to load '%s': %s", image_path, error.AsCString());
12288f343b09SGreg Clayton                 result.SetStatus (eReturnStatusFailed);
12298f343b09SGreg Clayton             }
12308f343b09SGreg Clayton         }
12318f343b09SGreg Clayton         return result.Succeeded();
12328f343b09SGreg Clayton     }
12334fbd67acSTamas Berghammer 
12344fbd67acSTamas Berghammer     CommandOptions m_options;
12358f343b09SGreg Clayton };
12368f343b09SGreg Clayton 
12374fbd67acSTamas Berghammer OptionDefinition
12384fbd67acSTamas Berghammer CommandObjectProcessLoad::CommandOptions::g_option_table[] =
12394fbd67acSTamas Berghammer {
1240*ac9c3a62SKate Stone   // clang-format off
12414fbd67acSTamas 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."},
12424fbd67acSTamas Berghammer   {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr}
1243*ac9c3a62SKate Stone   // clang-format on
12444fbd67acSTamas Berghammer };
12458f343b09SGreg Clayton 
12468f343b09SGreg Clayton //-------------------------------------------------------------------------
12478f343b09SGreg Clayton // CommandObjectProcessUnload
12488f343b09SGreg Clayton //-------------------------------------------------------------------------
1249bb9caf73SJim Ingham #pragma mark CommandObjectProcessUnload
12508f343b09SGreg Clayton 
12515a988416SJim Ingham class CommandObjectProcessUnload : public CommandObjectParsed
12528f343b09SGreg Clayton {
12538f343b09SGreg Clayton public:
12548f343b09SGreg Clayton 
12558f343b09SGreg Clayton     CommandObjectProcessUnload (CommandInterpreter &interpreter) :
12565a988416SJim Ingham         CommandObjectParsed (interpreter,
12578f343b09SGreg Clayton                              "process unload",
12588f343b09SGreg Clayton                              "Unload a shared library from the current process using the index returned by a previous call to \"process load\".",
12598f343b09SGreg Clayton                              "process unload <index>",
1260e87764f2SEnrico Granata                              eCommandRequiresProcess       |
1261e87764f2SEnrico Granata                              eCommandTryTargetAPILock      |
1262e87764f2SEnrico Granata                              eCommandProcessMustBeLaunched |
1263e87764f2SEnrico Granata                              eCommandProcessMustBePaused   )
12648f343b09SGreg Clayton     {
12658f343b09SGreg Clayton     }
12668f343b09SGreg Clayton 
126749bcfd80SEugene Zelenko     ~CommandObjectProcessUnload() override = default;
12688f343b09SGreg Clayton 
12695a988416SJim Ingham protected:
12708f343b09SGreg Clayton     bool
127113d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
12728f343b09SGreg Clayton     {
1273f9fc609fSGreg Clayton         Process *process = m_exe_ctx.GetProcessPtr();
12748f343b09SGreg Clayton 
1275c7bece56SGreg Clayton         const size_t argc = command.GetArgumentCount();
12768f343b09SGreg Clayton 
12778f343b09SGreg Clayton         for (uint32_t i = 0; i < argc; ++i)
12788f343b09SGreg Clayton         {
12798f343b09SGreg Clayton             const char *image_token_cstr = command.GetArgumentAtIndex(i);
12805275aaa0SVince Harron             uint32_t image_token = StringConvert::ToUInt32(image_token_cstr, LLDB_INVALID_IMAGE_TOKEN, 0);
12818f343b09SGreg Clayton             if (image_token == LLDB_INVALID_IMAGE_TOKEN)
12828f343b09SGreg Clayton             {
12838f343b09SGreg Clayton                 result.AppendErrorWithFormat ("invalid image index argument '%s'", image_token_cstr);
12848f343b09SGreg Clayton                 result.SetStatus (eReturnStatusFailed);
12858f343b09SGreg Clayton                 break;
12868f343b09SGreg Clayton             }
12878f343b09SGreg Clayton             else
12888f343b09SGreg Clayton             {
12893cb132a0STamas Berghammer                 Error error (process->GetTarget().GetPlatform()->UnloadImage(process, image_token));
12908f343b09SGreg Clayton                 if (error.Success())
12918f343b09SGreg Clayton                 {
12928f343b09SGreg Clayton                     result.AppendMessageWithFormat ("Unloading shared library with index %u...ok\n", image_token);
12938f343b09SGreg Clayton                     result.SetStatus (eReturnStatusSuccessFinishResult);
12948f343b09SGreg Clayton                 }
12958f343b09SGreg Clayton                 else
12968f343b09SGreg Clayton                 {
12978f343b09SGreg Clayton                     result.AppendErrorWithFormat ("failed to unload image: %s", error.AsCString());
12988f343b09SGreg Clayton                     result.SetStatus (eReturnStatusFailed);
12998f343b09SGreg Clayton                     break;
13008f343b09SGreg Clayton                 }
13018f343b09SGreg Clayton             }
13028f343b09SGreg Clayton         }
13038f343b09SGreg Clayton         return result.Succeeded();
13048f343b09SGreg Clayton     }
13058f343b09SGreg Clayton };
13068f343b09SGreg Clayton 
13078f343b09SGreg Clayton //-------------------------------------------------------------------------
130830fdc8d8SChris Lattner // CommandObjectProcessSignal
130930fdc8d8SChris Lattner //-------------------------------------------------------------------------
1310bb9caf73SJim Ingham #pragma mark CommandObjectProcessSignal
131130fdc8d8SChris Lattner 
13125a988416SJim Ingham class CommandObjectProcessSignal : public CommandObjectParsed
131330fdc8d8SChris Lattner {
131430fdc8d8SChris Lattner public:
13157428a18cSKate Stone     CommandObjectProcessSignal(CommandInterpreter &interpreter)
13167428a18cSKate Stone         : CommandObjectParsed(interpreter, "process signal", "Send a UNIX signal to the current target process.",
13177428a18cSKate Stone                               nullptr, eCommandRequiresProcess | eCommandTryTargetAPILock)
131830fdc8d8SChris Lattner     {
1319405fe67fSCaroline Tice         CommandArgumentEntry arg;
1320405fe67fSCaroline Tice         CommandArgumentData signal_arg;
1321405fe67fSCaroline Tice 
1322405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
1323c0dbdfb6SCaroline Tice         signal_arg.arg_type = eArgTypeUnixSignal;
1324405fe67fSCaroline Tice         signal_arg.arg_repetition = eArgRepeatPlain;
1325405fe67fSCaroline Tice 
1326405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
1327405fe67fSCaroline Tice         arg.push_back (signal_arg);
1328405fe67fSCaroline Tice 
1329405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
1330405fe67fSCaroline Tice         m_arguments.push_back (arg);
133130fdc8d8SChris Lattner     }
133230fdc8d8SChris Lattner 
133349bcfd80SEugene Zelenko     ~CommandObjectProcessSignal() override = default;
133430fdc8d8SChris Lattner 
13355a988416SJim Ingham protected:
133630fdc8d8SChris Lattner     bool
133713d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
133830fdc8d8SChris Lattner     {
1339f9fc609fSGreg Clayton         Process *process = m_exe_ctx.GetProcessPtr();
134030fdc8d8SChris Lattner 
134130fdc8d8SChris Lattner         if (command.GetArgumentCount() == 1)
134230fdc8d8SChris Lattner         {
1343237cd906SGreg Clayton             int signo = LLDB_INVALID_SIGNAL_NUMBER;
1344237cd906SGreg Clayton 
1345237cd906SGreg Clayton             const char *signal_name = command.GetArgumentAtIndex(0);
1346237cd906SGreg Clayton             if (::isxdigit (signal_name[0]))
13475275aaa0SVince Harron                 signo = StringConvert::ToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0);
1348237cd906SGreg Clayton             else
134998d0a4b3SChaoren Lin                 signo = process->GetUnixSignals()->GetSignalNumberFromName(signal_name);
1350237cd906SGreg Clayton 
1351237cd906SGreg Clayton             if (signo == LLDB_INVALID_SIGNAL_NUMBER)
135230fdc8d8SChris Lattner             {
135330fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("Invalid signal argument '%s'.\n", command.GetArgumentAtIndex(0));
135430fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
135530fdc8d8SChris Lattner             }
135630fdc8d8SChris Lattner             else
135730fdc8d8SChris Lattner             {
135830fdc8d8SChris Lattner                 Error error (process->Signal (signo));
135930fdc8d8SChris Lattner                 if (error.Success())
136030fdc8d8SChris Lattner                 {
136130fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusSuccessFinishResult);
136230fdc8d8SChris Lattner                 }
136330fdc8d8SChris Lattner                 else
136430fdc8d8SChris Lattner                 {
136530fdc8d8SChris Lattner                     result.AppendErrorWithFormat ("Failed to send signal %i: %s\n", signo, error.AsCString());
136630fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
136730fdc8d8SChris Lattner                 }
136830fdc8d8SChris Lattner             }
136930fdc8d8SChris Lattner         }
137030fdc8d8SChris Lattner         else
137130fdc8d8SChris Lattner         {
1372fd54b368SJason Molenda             result.AppendErrorWithFormat("'%s' takes exactly one signal number argument:\nUsage: %s\n", m_cmd_name.c_str(),
137330fdc8d8SChris Lattner                                         m_cmd_syntax.c_str());
137430fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
137530fdc8d8SChris Lattner         }
137630fdc8d8SChris Lattner         return result.Succeeded();
137730fdc8d8SChris Lattner     }
137830fdc8d8SChris Lattner };
137930fdc8d8SChris Lattner 
138030fdc8d8SChris Lattner //-------------------------------------------------------------------------
138130fdc8d8SChris Lattner // CommandObjectProcessInterrupt
138230fdc8d8SChris Lattner //-------------------------------------------------------------------------
1383bb9caf73SJim Ingham #pragma mark CommandObjectProcessInterrupt
138430fdc8d8SChris Lattner 
13855a988416SJim Ingham class CommandObjectProcessInterrupt : public CommandObjectParsed
138630fdc8d8SChris Lattner {
138730fdc8d8SChris Lattner public:
13887428a18cSKate Stone     CommandObjectProcessInterrupt(CommandInterpreter &interpreter)
13897428a18cSKate Stone         : CommandObjectParsed(interpreter, "process interrupt", "Interrupt the current target process.",
1390a7015092SGreg Clayton                               "process interrupt",
13917428a18cSKate Stone                               eCommandRequiresProcess | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched)
139230fdc8d8SChris Lattner     {
139330fdc8d8SChris Lattner     }
139430fdc8d8SChris Lattner 
139549bcfd80SEugene Zelenko     ~CommandObjectProcessInterrupt() override = default;
139630fdc8d8SChris Lattner 
13975a988416SJim Ingham protected:
139830fdc8d8SChris Lattner     bool
139913d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
140030fdc8d8SChris Lattner     {
1401f9fc609fSGreg Clayton         Process *process = m_exe_ctx.GetProcessPtr();
140249bcfd80SEugene Zelenko         if (process == nullptr)
140330fdc8d8SChris Lattner         {
140430fdc8d8SChris Lattner             result.AppendError ("no process to halt");
140530fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
140630fdc8d8SChris Lattner             return false;
140730fdc8d8SChris Lattner         }
140830fdc8d8SChris Lattner 
140930fdc8d8SChris Lattner         if (command.GetArgumentCount() == 0)
141030fdc8d8SChris Lattner         {
1411f9b57b9dSGreg Clayton             bool clear_thread_plans = true;
1412f9b57b9dSGreg Clayton             Error error(process->Halt (clear_thread_plans));
141330fdc8d8SChris Lattner             if (error.Success())
141430fdc8d8SChris Lattner             {
141530fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusSuccessFinishResult);
141630fdc8d8SChris Lattner             }
141730fdc8d8SChris Lattner             else
141830fdc8d8SChris Lattner             {
141930fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("Failed to halt process: %s\n", error.AsCString());
142030fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
142130fdc8d8SChris Lattner             }
142230fdc8d8SChris Lattner         }
142330fdc8d8SChris Lattner         else
142430fdc8d8SChris Lattner         {
1425fd54b368SJason Molenda             result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n",
142630fdc8d8SChris Lattner                                         m_cmd_name.c_str(),
142730fdc8d8SChris Lattner                                         m_cmd_syntax.c_str());
142830fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
142930fdc8d8SChris Lattner         }
143030fdc8d8SChris Lattner         return result.Succeeded();
143130fdc8d8SChris Lattner     }
143230fdc8d8SChris Lattner };
143330fdc8d8SChris Lattner 
143430fdc8d8SChris Lattner //-------------------------------------------------------------------------
143530fdc8d8SChris Lattner // CommandObjectProcessKill
143630fdc8d8SChris Lattner //-------------------------------------------------------------------------
1437bb9caf73SJim Ingham #pragma mark CommandObjectProcessKill
143830fdc8d8SChris Lattner 
14395a988416SJim Ingham class CommandObjectProcessKill : public CommandObjectParsed
144030fdc8d8SChris Lattner {
144130fdc8d8SChris Lattner public:
14427428a18cSKate Stone     CommandObjectProcessKill(CommandInterpreter &interpreter)
14437428a18cSKate Stone         : CommandObjectParsed(interpreter, "process kill", "Terminate the current target process.", "process kill",
14447428a18cSKate Stone                               eCommandRequiresProcess | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched)
144530fdc8d8SChris Lattner     {
144630fdc8d8SChris Lattner     }
144730fdc8d8SChris Lattner 
144849bcfd80SEugene Zelenko     ~CommandObjectProcessKill() override = default;
144930fdc8d8SChris Lattner 
14505a988416SJim Ingham protected:
145130fdc8d8SChris Lattner     bool
145213d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
145330fdc8d8SChris Lattner     {
1454f9fc609fSGreg Clayton         Process *process = m_exe_ctx.GetProcessPtr();
145549bcfd80SEugene Zelenko         if (process == nullptr)
145630fdc8d8SChris Lattner         {
145730fdc8d8SChris Lattner             result.AppendError ("no process to kill");
145830fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
145930fdc8d8SChris Lattner             return false;
146030fdc8d8SChris Lattner         }
146130fdc8d8SChris Lattner 
146230fdc8d8SChris Lattner         if (command.GetArgumentCount() == 0)
146330fdc8d8SChris Lattner         {
14648980e6bcSJason Molenda             Error error (process->Destroy(true));
146530fdc8d8SChris Lattner             if (error.Success())
146630fdc8d8SChris Lattner             {
146730fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusSuccessFinishResult);
146830fdc8d8SChris Lattner             }
146930fdc8d8SChris Lattner             else
147030fdc8d8SChris Lattner             {
147130fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString());
147230fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
147330fdc8d8SChris Lattner             }
147430fdc8d8SChris Lattner         }
147530fdc8d8SChris Lattner         else
147630fdc8d8SChris Lattner         {
1477fd54b368SJason Molenda             result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n",
147830fdc8d8SChris Lattner                                         m_cmd_name.c_str(),
147930fdc8d8SChris Lattner                                         m_cmd_syntax.c_str());
148030fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
148130fdc8d8SChris Lattner         }
148230fdc8d8SChris Lattner         return result.Succeeded();
148330fdc8d8SChris Lattner     }
148430fdc8d8SChris Lattner };
148530fdc8d8SChris Lattner 
148630fdc8d8SChris Lattner //-------------------------------------------------------------------------
1487a2715cf1SGreg Clayton // CommandObjectProcessSaveCore
1488a2715cf1SGreg Clayton //-------------------------------------------------------------------------
1489a2715cf1SGreg Clayton #pragma mark CommandObjectProcessSaveCore
1490a2715cf1SGreg Clayton 
1491a2715cf1SGreg Clayton class CommandObjectProcessSaveCore : public CommandObjectParsed
1492a2715cf1SGreg Clayton {
1493a2715cf1SGreg Clayton public:
1494a2715cf1SGreg Clayton     CommandObjectProcessSaveCore (CommandInterpreter &interpreter) :
1495a2715cf1SGreg Clayton     CommandObjectParsed (interpreter,
1496a2715cf1SGreg Clayton                          "process save-core",
1497a2715cf1SGreg Clayton                          "Save the current process as a core file using an appropriate file type.",
1498a2715cf1SGreg Clayton                          "process save-core FILE",
1499e87764f2SEnrico Granata                          eCommandRequiresProcess      |
1500e87764f2SEnrico Granata                          eCommandTryTargetAPILock     |
1501e87764f2SEnrico Granata                          eCommandProcessMustBeLaunched)
1502a2715cf1SGreg Clayton     {
1503a2715cf1SGreg Clayton     }
1504a2715cf1SGreg Clayton 
150549bcfd80SEugene Zelenko     ~CommandObjectProcessSaveCore() override = default;
1506a2715cf1SGreg Clayton 
1507a2715cf1SGreg Clayton protected:
1508a2715cf1SGreg Clayton     bool
1509a2715cf1SGreg Clayton     DoExecute (Args& command,
151013d21e9aSBruce Mitchener                CommandReturnObject &result) override
1511a2715cf1SGreg Clayton     {
1512a2715cf1SGreg Clayton         ProcessSP process_sp = m_exe_ctx.GetProcessSP();
1513a2715cf1SGreg Clayton         if (process_sp)
1514a2715cf1SGreg Clayton         {
1515a2715cf1SGreg Clayton             if (command.GetArgumentCount() == 1)
1516a2715cf1SGreg Clayton             {
1517a2715cf1SGreg Clayton                 FileSpec output_file(command.GetArgumentAtIndex(0), false);
1518a2715cf1SGreg Clayton                 Error error = PluginManager::SaveCore(process_sp, output_file);
1519a2715cf1SGreg Clayton                 if (error.Success())
1520a2715cf1SGreg Clayton                 {
1521a2715cf1SGreg Clayton                     result.SetStatus (eReturnStatusSuccessFinishResult);
1522a2715cf1SGreg Clayton                 }
1523a2715cf1SGreg Clayton                 else
1524a2715cf1SGreg Clayton                 {
1525a2715cf1SGreg Clayton                     result.AppendErrorWithFormat ("Failed to save core file for process: %s\n", error.AsCString());
1526a2715cf1SGreg Clayton                     result.SetStatus (eReturnStatusFailed);
1527a2715cf1SGreg Clayton                 }
1528a2715cf1SGreg Clayton             }
1529a2715cf1SGreg Clayton             else
1530a2715cf1SGreg Clayton             {
1531a2715cf1SGreg Clayton                 result.AppendErrorWithFormat ("'%s' takes one arguments:\nUsage: %s\n",
1532a2715cf1SGreg Clayton                                               m_cmd_name.c_str(),
1533a2715cf1SGreg Clayton                                               m_cmd_syntax.c_str());
1534a2715cf1SGreg Clayton                 result.SetStatus (eReturnStatusFailed);
1535a2715cf1SGreg Clayton             }
1536a2715cf1SGreg Clayton         }
1537a2715cf1SGreg Clayton         else
1538a2715cf1SGreg Clayton         {
1539a2715cf1SGreg Clayton             result.AppendError ("invalid process");
1540a2715cf1SGreg Clayton             result.SetStatus (eReturnStatusFailed);
1541a2715cf1SGreg Clayton             return false;
1542a2715cf1SGreg Clayton         }
1543a2715cf1SGreg Clayton 
1544a2715cf1SGreg Clayton         return result.Succeeded();
1545a2715cf1SGreg Clayton     }
1546a2715cf1SGreg Clayton };
1547a2715cf1SGreg Clayton 
1548a2715cf1SGreg Clayton //-------------------------------------------------------------------------
15494b9bea87SJim Ingham // CommandObjectProcessStatus
15504b9bea87SJim Ingham //-------------------------------------------------------------------------
1551bb9caf73SJim Ingham #pragma mark CommandObjectProcessStatus
1552bb9caf73SJim Ingham 
15535a988416SJim Ingham class CommandObjectProcessStatus : public CommandObjectParsed
15544b9bea87SJim Ingham {
15554b9bea87SJim Ingham public:
15567428a18cSKate Stone     CommandObjectProcessStatus(CommandInterpreter &interpreter)
15577428a18cSKate Stone         : CommandObjectParsed(interpreter, "process status",
15587428a18cSKate Stone                               "Show status and stop location for the current target process.", "process status",
1559e87764f2SEnrico Granata                               eCommandRequiresProcess | eCommandTryTargetAPILock)
15604b9bea87SJim Ingham     {
15614b9bea87SJim Ingham     }
15624b9bea87SJim Ingham 
156349bcfd80SEugene Zelenko     ~CommandObjectProcessStatus() override = default;
15644b9bea87SJim Ingham 
15654b9bea87SJim Ingham     bool
156613d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
15674b9bea87SJim Ingham     {
15687260f620SGreg Clayton         Stream &strm = result.GetOutputStream();
15694b9bea87SJim Ingham         result.SetStatus (eReturnStatusSuccessFinishNoResult);
1570e87764f2SEnrico Granata         // No need to check "process" for validity as eCommandRequiresProcess ensures it is valid
1571f9fc609fSGreg Clayton         Process *process = m_exe_ctx.GetProcessPtr();
15727260f620SGreg Clayton         const bool only_threads_with_stop_reason = true;
15737260f620SGreg Clayton         const uint32_t start_frame = 0;
15747260f620SGreg Clayton         const uint32_t num_frames = 1;
15757260f620SGreg Clayton         const uint32_t num_frames_with_source = 1;
1576c14ee32dSGreg Clayton         process->GetStatus(strm);
1577c14ee32dSGreg Clayton         process->GetThreadStatus (strm,
15787260f620SGreg Clayton                                   only_threads_with_stop_reason,
15797260f620SGreg Clayton                                   start_frame,
15807260f620SGreg Clayton                                   num_frames,
15817260f620SGreg Clayton                                   num_frames_with_source);
15824b9bea87SJim Ingham         return result.Succeeded();
15834b9bea87SJim Ingham     }
15844b9bea87SJim Ingham };
15854b9bea87SJim Ingham 
15864b9bea87SJim Ingham //-------------------------------------------------------------------------
158735731357SCaroline Tice // CommandObjectProcessHandle
158835731357SCaroline Tice //-------------------------------------------------------------------------
1589bb9caf73SJim Ingham #pragma mark CommandObjectProcessHandle
159035731357SCaroline Tice 
15915a988416SJim Ingham class CommandObjectProcessHandle : public CommandObjectParsed
159235731357SCaroline Tice {
159335731357SCaroline Tice public:
159435731357SCaroline Tice     class CommandOptions : public Options
159535731357SCaroline Tice     {
159635731357SCaroline Tice     public:
1597e1cfbc79STodd Fiala         CommandOptions() :
1598e1cfbc79STodd Fiala             Options()
159935731357SCaroline Tice         {
1600e1cfbc79STodd Fiala             OptionParsingStarting(nullptr);
160135731357SCaroline Tice         }
160235731357SCaroline Tice 
160349bcfd80SEugene Zelenko         ~CommandOptions() override = default;
160435731357SCaroline Tice 
160535731357SCaroline Tice         Error
1606e1cfbc79STodd Fiala         SetOptionValue(uint32_t option_idx, const char *option_arg,
1607e1cfbc79STodd Fiala                        ExecutionContext *execution_context) override
160835731357SCaroline Tice         {
160935731357SCaroline Tice             Error error;
16103bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
161135731357SCaroline Tice 
161235731357SCaroline Tice             switch (short_option)
161335731357SCaroline Tice             {
161435731357SCaroline Tice                 case 's':
161535731357SCaroline Tice                     stop = option_arg;
161635731357SCaroline Tice                     break;
161735731357SCaroline Tice                 case 'n':
161835731357SCaroline Tice                     notify = option_arg;
161935731357SCaroline Tice                     break;
162035731357SCaroline Tice                 case 'p':
162135731357SCaroline Tice                     pass = option_arg;
162235731357SCaroline Tice                     break;
162335731357SCaroline Tice                 default:
162486edbf41SGreg Clayton                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
162535731357SCaroline Tice                     break;
162635731357SCaroline Tice             }
162735731357SCaroline Tice             return error;
162835731357SCaroline Tice         }
162935731357SCaroline Tice 
163035731357SCaroline Tice         void
1631e1cfbc79STodd Fiala         OptionParsingStarting(ExecutionContext *execution_context) override
163235731357SCaroline Tice         {
163335731357SCaroline Tice             stop.clear();
163435731357SCaroline Tice             notify.clear();
163535731357SCaroline Tice             pass.clear();
163635731357SCaroline Tice         }
163735731357SCaroline Tice 
1638e0d378b3SGreg Clayton         const OptionDefinition*
163913d21e9aSBruce Mitchener         GetDefinitions () override
164035731357SCaroline Tice         {
164135731357SCaroline Tice             return g_option_table;
164235731357SCaroline Tice         }
164335731357SCaroline Tice 
164435731357SCaroline Tice         // Options table: Required for subclasses of Options.
164535731357SCaroline Tice 
1646e0d378b3SGreg Clayton         static OptionDefinition g_option_table[];
164735731357SCaroline Tice 
164835731357SCaroline Tice         // Instance variables to hold the values for command options.
164935731357SCaroline Tice 
165035731357SCaroline Tice         std::string stop;
165135731357SCaroline Tice         std::string notify;
165235731357SCaroline Tice         std::string pass;
165335731357SCaroline Tice     };
165435731357SCaroline Tice 
16557428a18cSKate Stone     CommandObjectProcessHandle(CommandInterpreter &interpreter)
16567428a18cSKate Stone         : CommandObjectParsed(
16577428a18cSKate Stone               interpreter, "process handle",
16587428a18cSKate Stone               "Manage LLDB handling of OS signals for the current target process.  Defaults to showing current policy.",
165949bcfd80SEugene Zelenko               nullptr),
1660e1cfbc79STodd Fiala           m_options()
166135731357SCaroline Tice     {
1662ea671fbdSKate Stone         SetHelpLong ("\nIf no signals are specified, update them all.  If no update "
1663ea671fbdSKate Stone                      "option is specified, list the current values.");
166435731357SCaroline Tice         CommandArgumentEntry arg;
1665c0dbdfb6SCaroline Tice         CommandArgumentData signal_arg;
166635731357SCaroline Tice 
1667c0dbdfb6SCaroline Tice         signal_arg.arg_type = eArgTypeUnixSignal;
1668c0dbdfb6SCaroline Tice         signal_arg.arg_repetition = eArgRepeatStar;
166935731357SCaroline Tice 
1670c0dbdfb6SCaroline Tice         arg.push_back (signal_arg);
167135731357SCaroline Tice 
167235731357SCaroline Tice         m_arguments.push_back (arg);
167335731357SCaroline Tice     }
167435731357SCaroline Tice 
167549bcfd80SEugene Zelenko     ~CommandObjectProcessHandle() override = default;
167635731357SCaroline Tice 
167735731357SCaroline Tice     Options *
167813d21e9aSBruce Mitchener     GetOptions () override
167935731357SCaroline Tice     {
168035731357SCaroline Tice         return &m_options;
168135731357SCaroline Tice     }
168235731357SCaroline Tice 
168335731357SCaroline Tice     bool
168410ad7993SCaroline Tice     VerifyCommandOptionValue (const std::string &option, int &real_value)
168535731357SCaroline Tice     {
168635731357SCaroline Tice         bool okay = true;
168710ad7993SCaroline Tice         bool success = false;
168810ad7993SCaroline Tice         bool tmp_value = Args::StringToBoolean (option.c_str(), false, &success);
168910ad7993SCaroline Tice 
169010ad7993SCaroline Tice         if (success && tmp_value)
169110ad7993SCaroline Tice             real_value = 1;
169210ad7993SCaroline Tice         else if (success && !tmp_value)
169310ad7993SCaroline Tice             real_value = 0;
169435731357SCaroline Tice         else
169535731357SCaroline Tice         {
169635731357SCaroline Tice             // If the value isn't 'true' or 'false', it had better be 0 or 1.
16975275aaa0SVince Harron             real_value = StringConvert::ToUInt32 (option.c_str(), 3);
169810ad7993SCaroline Tice             if (real_value != 0 && real_value != 1)
169935731357SCaroline Tice                 okay = false;
170035731357SCaroline Tice         }
170135731357SCaroline Tice 
170235731357SCaroline Tice         return okay;
170335731357SCaroline Tice     }
170435731357SCaroline Tice 
170510ad7993SCaroline Tice     void
170610ad7993SCaroline Tice     PrintSignalHeader (Stream &str)
170710ad7993SCaroline Tice     {
170810ad7993SCaroline Tice         str.Printf ("NAME         PASS   STOP   NOTIFY\n");
1709b84141a6SPavel Labath         str.Printf ("===========  =====  =====  ======\n");
171010ad7993SCaroline Tice     }
171110ad7993SCaroline Tice 
171210ad7993SCaroline Tice     void
171398d0a4b3SChaoren Lin     PrintSignal(Stream &str, int32_t signo, const char *sig_name, const UnixSignalsSP &signals_sp)
171410ad7993SCaroline Tice     {
171510ad7993SCaroline Tice         bool stop;
171610ad7993SCaroline Tice         bool suppress;
171710ad7993SCaroline Tice         bool notify;
171810ad7993SCaroline Tice 
1719b84141a6SPavel Labath         str.Printf ("%-11s  ", sig_name);
172098d0a4b3SChaoren Lin         if (signals_sp->GetSignalInfo(signo, suppress, stop, notify))
172110ad7993SCaroline Tice         {
172210ad7993SCaroline Tice             bool pass = !suppress;
172310ad7993SCaroline Tice             str.Printf ("%s  %s  %s",
172410ad7993SCaroline Tice                         (pass ? "true " : "false"),
172510ad7993SCaroline Tice                         (stop ? "true " : "false"),
172610ad7993SCaroline Tice                         (notify ? "true " : "false"));
172710ad7993SCaroline Tice         }
172810ad7993SCaroline Tice         str.Printf ("\n");
172910ad7993SCaroline Tice     }
173010ad7993SCaroline Tice 
173110ad7993SCaroline Tice     void
173298d0a4b3SChaoren Lin     PrintSignalInformation(Stream &str, Args &signal_args, int num_valid_signals, const UnixSignalsSP &signals_sp)
173310ad7993SCaroline Tice     {
173410ad7993SCaroline Tice         PrintSignalHeader (str);
173510ad7993SCaroline Tice 
173610ad7993SCaroline Tice         if (num_valid_signals > 0)
173710ad7993SCaroline Tice         {
173810ad7993SCaroline Tice             size_t num_args = signal_args.GetArgumentCount();
173910ad7993SCaroline Tice             for (size_t i = 0; i < num_args; ++i)
174010ad7993SCaroline Tice             {
174198d0a4b3SChaoren Lin                 int32_t signo = signals_sp->GetSignalNumberFromName(signal_args.GetArgumentAtIndex(i));
174210ad7993SCaroline Tice                 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
174398d0a4b3SChaoren Lin                     PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals_sp);
174410ad7993SCaroline Tice             }
174510ad7993SCaroline Tice         }
174610ad7993SCaroline Tice         else // Print info for ALL signals
174710ad7993SCaroline Tice         {
174898d0a4b3SChaoren Lin             int32_t signo = signals_sp->GetFirstSignalNumber();
174910ad7993SCaroline Tice             while (signo != LLDB_INVALID_SIGNAL_NUMBER)
175010ad7993SCaroline Tice             {
175198d0a4b3SChaoren Lin                 PrintSignal(str, signo, signals_sp->GetSignalAsCString(signo), signals_sp);
175298d0a4b3SChaoren Lin                 signo = signals_sp->GetNextSignalNumber(signo);
175310ad7993SCaroline Tice             }
175410ad7993SCaroline Tice         }
175510ad7993SCaroline Tice     }
175610ad7993SCaroline Tice 
17575a988416SJim Ingham protected:
175835731357SCaroline Tice     bool
175913d21e9aSBruce Mitchener     DoExecute (Args &signal_args, CommandReturnObject &result) override
176035731357SCaroline Tice     {
176135731357SCaroline Tice         TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
176235731357SCaroline Tice 
176335731357SCaroline Tice         if (!target_sp)
176435731357SCaroline Tice         {
176535731357SCaroline Tice             result.AppendError ("No current target;"
176635731357SCaroline Tice                                 " cannot handle signals until you have a valid target and process.\n");
176735731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
176835731357SCaroline Tice             return false;
176935731357SCaroline Tice         }
177035731357SCaroline Tice 
177135731357SCaroline Tice         ProcessSP process_sp = target_sp->GetProcessSP();
177235731357SCaroline Tice 
177335731357SCaroline Tice         if (!process_sp)
177435731357SCaroline Tice         {
177535731357SCaroline Tice             result.AppendError ("No current process; cannot handle signals until you have a valid process.\n");
177635731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
177735731357SCaroline Tice             return false;
177835731357SCaroline Tice         }
177935731357SCaroline Tice 
178035731357SCaroline Tice         int stop_action = -1;   // -1 means leave the current setting alone
178135731357SCaroline Tice         int pass_action = -1;   // -1 means leave the current setting alone
178235731357SCaroline Tice         int notify_action = -1; // -1 means leave the current setting alone
178335731357SCaroline Tice 
178435731357SCaroline Tice         if (! m_options.stop.empty()
178510ad7993SCaroline Tice             && ! VerifyCommandOptionValue (m_options.stop, stop_action))
178635731357SCaroline Tice         {
178735731357SCaroline Tice             result.AppendError ("Invalid argument for command option --stop; must be true or false.\n");
178835731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
178935731357SCaroline Tice             return false;
179035731357SCaroline Tice         }
179135731357SCaroline Tice 
179235731357SCaroline Tice         if (! m_options.notify.empty()
179310ad7993SCaroline Tice             && ! VerifyCommandOptionValue (m_options.notify, notify_action))
179435731357SCaroline Tice         {
179535731357SCaroline Tice             result.AppendError ("Invalid argument for command option --notify; must be true or false.\n");
179635731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
179735731357SCaroline Tice             return false;
179835731357SCaroline Tice         }
179935731357SCaroline Tice 
180035731357SCaroline Tice         if (! m_options.pass.empty()
180110ad7993SCaroline Tice             && ! VerifyCommandOptionValue (m_options.pass, pass_action))
180235731357SCaroline Tice         {
180335731357SCaroline Tice             result.AppendError ("Invalid argument for command option --pass; must be true or false.\n");
180435731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
180535731357SCaroline Tice             return false;
180635731357SCaroline Tice         }
180735731357SCaroline Tice 
180835731357SCaroline Tice         size_t num_args = signal_args.GetArgumentCount();
180998d0a4b3SChaoren Lin         UnixSignalsSP signals_sp = process_sp->GetUnixSignals();
181035731357SCaroline Tice         int num_signals_set = 0;
181135731357SCaroline Tice 
181210ad7993SCaroline Tice         if (num_args > 0)
181310ad7993SCaroline Tice         {
181435731357SCaroline Tice             for (size_t i = 0; i < num_args; ++i)
181535731357SCaroline Tice             {
181698d0a4b3SChaoren Lin                 int32_t signo = signals_sp->GetSignalNumberFromName(signal_args.GetArgumentAtIndex(i));
181735731357SCaroline Tice                 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
181835731357SCaroline Tice                 {
181910ad7993SCaroline Tice                     // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees
182035731357SCaroline Tice                     // the value is either 0 or 1.
182135731357SCaroline Tice                     if (stop_action != -1)
182298d0a4b3SChaoren Lin                         signals_sp->SetShouldStop(signo, stop_action);
182335731357SCaroline Tice                     if (pass_action != -1)
182435731357SCaroline Tice                     {
182598d0a4b3SChaoren Lin                         bool suppress = !pass_action;
182698d0a4b3SChaoren Lin                         signals_sp->SetShouldSuppress(signo, suppress);
182735731357SCaroline Tice                     }
182835731357SCaroline Tice                     if (notify_action != -1)
182998d0a4b3SChaoren Lin                         signals_sp->SetShouldNotify(signo, notify_action);
183035731357SCaroline Tice                     ++num_signals_set;
183135731357SCaroline Tice                 }
183235731357SCaroline Tice                 else
183335731357SCaroline Tice                 {
183435731357SCaroline Tice                     result.AppendErrorWithFormat ("Invalid signal name '%s'\n", signal_args.GetArgumentAtIndex (i));
183535731357SCaroline Tice                 }
183635731357SCaroline Tice             }
183710ad7993SCaroline Tice         }
183810ad7993SCaroline Tice         else
183910ad7993SCaroline Tice         {
184010ad7993SCaroline Tice             // No signal specified, if any command options were specified, update ALL signals.
184110ad7993SCaroline Tice             if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1))
184210ad7993SCaroline Tice             {
184310ad7993SCaroline Tice                 if (m_interpreter.Confirm ("Do you really want to update all the signals?", false))
184410ad7993SCaroline Tice                 {
184598d0a4b3SChaoren Lin                     int32_t signo = signals_sp->GetFirstSignalNumber();
184610ad7993SCaroline Tice                     while (signo != LLDB_INVALID_SIGNAL_NUMBER)
184710ad7993SCaroline Tice                     {
184810ad7993SCaroline Tice                         if (notify_action != -1)
184998d0a4b3SChaoren Lin                             signals_sp->SetShouldNotify(signo, notify_action);
185010ad7993SCaroline Tice                         if (stop_action != -1)
185198d0a4b3SChaoren Lin                             signals_sp->SetShouldStop(signo, stop_action);
185210ad7993SCaroline Tice                         if (pass_action != -1)
185310ad7993SCaroline Tice                         {
185498d0a4b3SChaoren Lin                             bool suppress = !pass_action;
185598d0a4b3SChaoren Lin                             signals_sp->SetShouldSuppress(signo, suppress);
185610ad7993SCaroline Tice                         }
185798d0a4b3SChaoren Lin                         signo = signals_sp->GetNextSignalNumber(signo);
185810ad7993SCaroline Tice                     }
185910ad7993SCaroline Tice                 }
186010ad7993SCaroline Tice             }
186110ad7993SCaroline Tice         }
186210ad7993SCaroline Tice 
186398d0a4b3SChaoren Lin         PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals_sp);
186435731357SCaroline Tice 
186535731357SCaroline Tice         if (num_signals_set > 0)
186635731357SCaroline Tice             result.SetStatus (eReturnStatusSuccessFinishNoResult);
186735731357SCaroline Tice         else
186835731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
186935731357SCaroline Tice 
187035731357SCaroline Tice         return result.Succeeded();
187135731357SCaroline Tice     }
187235731357SCaroline Tice 
187335731357SCaroline Tice     CommandOptions m_options;
187435731357SCaroline Tice };
187535731357SCaroline Tice 
1876e0d378b3SGreg Clayton OptionDefinition
187735731357SCaroline Tice CommandObjectProcessHandle::CommandOptions::g_option_table[] =
187835731357SCaroline Tice {
1879*ac9c3a62SKate Stone   // clang-format off
188049bcfd80SEugene 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."},
188149bcfd80SEugene 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."},
188249bcfd80SEugene 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."},
188349bcfd80SEugene Zelenko   {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr}
1884*ac9c3a62SKate Stone   // clang-format on
188535731357SCaroline Tice };
188635731357SCaroline Tice 
188735731357SCaroline Tice //-------------------------------------------------------------------------
188830fdc8d8SChris Lattner // CommandObjectMultiwordProcess
188930fdc8d8SChris Lattner //-------------------------------------------------------------------------
189030fdc8d8SChris Lattner 
18917428a18cSKate Stone CommandObjectMultiwordProcess::CommandObjectMultiwordProcess(CommandInterpreter &interpreter)
18927428a18cSKate Stone     : CommandObjectMultiword(interpreter, "process", "Commands for interacting with processes on the current platform.",
189330fdc8d8SChris Lattner                              "process <subcommand> [<subcommand-options>]")
189430fdc8d8SChris Lattner {
1895a7015092SGreg Clayton     LoadSubCommand ("attach",      CommandObjectSP (new CommandObjectProcessAttach    (interpreter)));
1896a7015092SGreg Clayton     LoadSubCommand ("launch",      CommandObjectSP (new CommandObjectProcessLaunch    (interpreter)));
1897a7015092SGreg Clayton     LoadSubCommand ("continue",    CommandObjectSP (new CommandObjectProcessContinue  (interpreter)));
1898b766a73dSGreg Clayton     LoadSubCommand ("connect",     CommandObjectSP (new CommandObjectProcessConnect   (interpreter)));
1899a7015092SGreg Clayton     LoadSubCommand ("detach",      CommandObjectSP (new CommandObjectProcessDetach    (interpreter)));
19008f343b09SGreg Clayton     LoadSubCommand ("load",        CommandObjectSP (new CommandObjectProcessLoad      (interpreter)));
19018f343b09SGreg Clayton     LoadSubCommand ("unload",      CommandObjectSP (new CommandObjectProcessUnload    (interpreter)));
1902a7015092SGreg Clayton     LoadSubCommand ("signal",      CommandObjectSP (new CommandObjectProcessSignal    (interpreter)));
190335731357SCaroline Tice     LoadSubCommand ("handle",      CommandObjectSP (new CommandObjectProcessHandle    (interpreter)));
1904a7015092SGreg Clayton     LoadSubCommand ("status",      CommandObjectSP (new CommandObjectProcessStatus    (interpreter)));
1905a7015092SGreg Clayton     LoadSubCommand ("interrupt",   CommandObjectSP (new CommandObjectProcessInterrupt (interpreter)));
1906a7015092SGreg Clayton     LoadSubCommand ("kill",        CommandObjectSP (new CommandObjectProcessKill      (interpreter)));
1907998255bfSGreg Clayton     LoadSubCommand ("plugin",      CommandObjectSP (new CommandObjectProcessPlugin    (interpreter)));
1908a2715cf1SGreg Clayton     LoadSubCommand ("save-core",   CommandObjectSP (new CommandObjectProcessSaveCore  (interpreter)));
190930fdc8d8SChris Lattner }
191030fdc8d8SChris Lattner 
191149bcfd80SEugene Zelenko CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess() = default;
1912