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"),
129*e1cfbc79STodd 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 
160*e1cfbc79STodd 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 //{
30649bcfd80SEugene Zelenko //{ SET1 | SET2 | SET3, false, "stop-at-entry", 's', OptionParser::eNoArgument,       nullptr, 0, eArgTypeNone,    "Stop at the entry point of the program when launching a process."},
30749bcfd80SEugene Zelenko //{ SET1              , false, "stdin",         'i', OptionParser::eRequiredArgument, nullptr, 0, eArgTypeDirectoryName,    "Redirect stdin for the process to <path>."},
30849bcfd80SEugene Zelenko //{ SET1              , false, "stdout",        'o', OptionParser::eRequiredArgument, nullptr, 0, eArgTypeDirectoryName,    "Redirect stdout for the process to <path>."},
30949bcfd80SEugene Zelenko //{ SET1              , false, "stderr",        'e', OptionParser::eRequiredArgument, nullptr, 0, eArgTypeDirectoryName,    "Redirect stderr for the process to <path>."},
31049bcfd80SEugene Zelenko //{ SET1 | SET2 | SET3, false, "plugin",        'p', OptionParser::eRequiredArgument, nullptr, 0, eArgTypePlugin,  "Name of the process plugin you want to use."},
31149bcfd80SEugene Zelenko //{        SET2       , false, "tty",           't', OptionParser::eOptionalArgument, nullptr, 0, eArgTypeDirectoryName,    "Start the process in a terminal. If <path> is specified, look for a terminal whose name contains <path>, else start the process in a new terminal."},
31249bcfd80SEugene Zelenko //{               SET3, false, "no-stdio",      'n', OptionParser::eNoArgument,       nullptr, 0, eArgTypeNone,    "Do not set up for terminal I/O to go to running process."},
31349bcfd80SEugene Zelenko //{ SET1 | SET2 | SET3, false, "working-dir",   'w', OptionParser::eRequiredArgument, nullptr, 0, eArgTypeDirectoryName,    "Set the current working directory to <path> when running the inferior."},
31449bcfd80SEugene Zelenko //{ 0,                  false, nullptr,             0,  0,                 nullptr, 0, eArgTypeNone,    nullptr }
315982c9762SGreg Clayton //};
316982c9762SGreg Clayton //
317982c9762SGreg Clayton //#undef SET1
318982c9762SGreg Clayton //#undef SET2
319982c9762SGreg Clayton //#undef SET3
32030fdc8d8SChris Lattner 
32130fdc8d8SChris Lattner //-------------------------------------------------------------------------
32230fdc8d8SChris Lattner // CommandObjectProcessAttach
32330fdc8d8SChris Lattner //-------------------------------------------------------------------------
324bb9caf73SJim Ingham #pragma mark CommandObjectProcessAttach
325dcb1d856SJim Ingham class CommandObjectProcessAttach : public CommandObjectProcessLaunchOrAttach
32630fdc8d8SChris Lattner {
32730fdc8d8SChris Lattner public:
32830fdc8d8SChris Lattner     class CommandOptions : public Options
32930fdc8d8SChris Lattner     {
33030fdc8d8SChris Lattner     public:
331*e1cfbc79STodd Fiala         CommandOptions() :
332*e1cfbc79STodd Fiala             Options()
33330fdc8d8SChris Lattner         {
334f6b8b581SGreg Clayton             // Keep default values of all options in one place: OptionParsingStarting ()
335*e1cfbc79STodd Fiala             OptionParsingStarting(nullptr);
33630fdc8d8SChris Lattner         }
33730fdc8d8SChris Lattner 
33849bcfd80SEugene Zelenko         ~CommandOptions() override = default;
33930fdc8d8SChris Lattner 
34030fdc8d8SChris Lattner         Error
341*e1cfbc79STodd Fiala         SetOptionValue (uint32_t option_idx, const char *option_arg,
342*e1cfbc79STodd Fiala                         ExecutionContext *execution_context) override
34330fdc8d8SChris Lattner         {
34430fdc8d8SChris Lattner             Error error;
3453bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
34630fdc8d8SChris Lattner             bool success = false;
34730fdc8d8SChris Lattner             switch (short_option)
34830fdc8d8SChris Lattner             {
349a95ce623SJohnny Chen                 case 'c':
350a95ce623SJohnny Chen                     attach_info.SetContinueOnceAttached(true);
351a95ce623SJohnny Chen                     break;
352a95ce623SJohnny Chen 
35330fdc8d8SChris Lattner                 case 'p':
354144f3a9cSGreg Clayton                     {
3555275aaa0SVince Harron                         lldb::pid_t pid = StringConvert::ToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success);
35630fdc8d8SChris Lattner                         if (!success || pid == LLDB_INVALID_PROCESS_ID)
35730fdc8d8SChris Lattner                         {
35886edbf41SGreg Clayton                             error.SetErrorStringWithFormat("invalid process ID '%s'", option_arg);
35930fdc8d8SChris Lattner                         }
360144f3a9cSGreg Clayton                         else
361144f3a9cSGreg Clayton                         {
362144f3a9cSGreg Clayton                             attach_info.SetProcessID (pid);
363144f3a9cSGreg Clayton                         }
364144f3a9cSGreg Clayton                     }
36530fdc8d8SChris Lattner                     break;
36630fdc8d8SChris Lattner 
36730fdc8d8SChris Lattner                 case 'P':
368144f3a9cSGreg Clayton                     attach_info.SetProcessPluginName (option_arg);
36930fdc8d8SChris Lattner                     break;
37030fdc8d8SChris Lattner 
37130fdc8d8SChris Lattner                 case 'n':
372144f3a9cSGreg Clayton                     attach_info.GetExecutableFile().SetFile(option_arg, false);
37330fdc8d8SChris Lattner                     break;
37430fdc8d8SChris Lattner 
37530fdc8d8SChris Lattner                 case 'w':
376144f3a9cSGreg Clayton                     attach_info.SetWaitForLaunch(true);
37730fdc8d8SChris Lattner                     break;
37830fdc8d8SChris Lattner 
379cd16df91SJim Ingham                 case 'i':
380cd16df91SJim Ingham                     attach_info.SetIgnoreExisting(false);
381cd16df91SJim Ingham                     break;
382cd16df91SJim Ingham 
38330fdc8d8SChris Lattner                 default:
38486edbf41SGreg Clayton                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
38530fdc8d8SChris Lattner                     break;
38630fdc8d8SChris Lattner             }
38730fdc8d8SChris Lattner             return error;
38830fdc8d8SChris Lattner         }
38930fdc8d8SChris Lattner 
39030fdc8d8SChris Lattner         void
391*e1cfbc79STodd Fiala         OptionParsingStarting(ExecutionContext *execution_context) override
39230fdc8d8SChris Lattner         {
393144f3a9cSGreg Clayton             attach_info.Clear();
39430fdc8d8SChris Lattner         }
39530fdc8d8SChris Lattner 
396e0d378b3SGreg Clayton         const OptionDefinition*
39713d21e9aSBruce Mitchener         GetDefinitions () override
39830fdc8d8SChris Lattner         {
39930fdc8d8SChris Lattner             return g_option_table;
40030fdc8d8SChris Lattner         }
40130fdc8d8SChris Lattner 
40213d21e9aSBruce Mitchener         bool
403eb0103f2SGreg Clayton         HandleOptionArgumentCompletion (Args &input,
4045aee162fSJim Ingham                                         int cursor_index,
4055aee162fSJim Ingham                                         int char_pos,
4065aee162fSJim Ingham                                         OptionElementVector &opt_element_vector,
4075aee162fSJim Ingham                                         int opt_element_index,
4085aee162fSJim Ingham                                         int match_start_point,
4095aee162fSJim Ingham                                         int max_return_elements,
410*e1cfbc79STodd Fiala                                         CommandInterpreter &interpreter,
4115aee162fSJim Ingham                                         bool &word_complete,
41213d21e9aSBruce Mitchener                                         StringList &matches) override
4135aee162fSJim Ingham         {
4145aee162fSJim Ingham             int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
4155aee162fSJim Ingham             int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
4165aee162fSJim Ingham 
4175aee162fSJim Ingham             // We are only completing the name option for now...
4185aee162fSJim Ingham 
419e0d378b3SGreg Clayton             const OptionDefinition *opt_defs = GetDefinitions();
4205aee162fSJim Ingham             if (opt_defs[opt_defs_index].short_option == 'n')
4215aee162fSJim Ingham             {
4225aee162fSJim Ingham                 // Are we in the name?
4235aee162fSJim Ingham 
4245aee162fSJim Ingham                 // Look to see if there is a -P argument provided, and if so use that plugin, otherwise
4255aee162fSJim Ingham                 // use the default plugin.
4265aee162fSJim Ingham 
42749bcfd80SEugene Zelenko                 const char *partial_name = nullptr;
4285aee162fSJim Ingham                 partial_name = input.GetArgumentAtIndex(opt_arg_pos);
4295aee162fSJim Ingham 
430*e1cfbc79STodd Fiala                 PlatformSP platform_sp(interpreter.GetPlatform(true));
431e996fd30SGreg Clayton                 if (platform_sp)
4325aee162fSJim Ingham                 {
4338b82f087SGreg Clayton                     ProcessInstanceInfoList process_infos;
4348b82f087SGreg Clayton                     ProcessInstanceInfoMatch match_info;
43532e0a750SGreg Clayton                     if (partial_name)
43632e0a750SGreg Clayton                     {
437144f3a9cSGreg Clayton                         match_info.GetProcessInfo().GetExecutableFile().SetFile(partial_name, false);
43832e0a750SGreg Clayton                         match_info.SetNameMatchType(eNameMatchStartsWith);
43932e0a750SGreg Clayton                     }
44032e0a750SGreg Clayton                     platform_sp->FindProcesses (match_info, process_infos);
441c7bece56SGreg Clayton                     const size_t num_matches = process_infos.GetSize();
442e996fd30SGreg Clayton                     if (num_matches > 0)
443e996fd30SGreg Clayton                     {
444c7bece56SGreg Clayton                         for (size_t i = 0; i < num_matches; ++i)
445e996fd30SGreg Clayton                         {
446e996fd30SGreg Clayton                             matches.AppendString (process_infos.GetProcessNameAtIndex(i),
447e996fd30SGreg Clayton                                                   process_infos.GetProcessNameLengthAtIndex(i));
4485aee162fSJim Ingham                         }
4495aee162fSJim Ingham                     }
4505aee162fSJim Ingham                 }
4515aee162fSJim Ingham             }
4525aee162fSJim Ingham 
4535aee162fSJim Ingham             return false;
4545aee162fSJim Ingham         }
4555aee162fSJim Ingham 
45630fdc8d8SChris Lattner         // Options table: Required for subclasses of Options.
45730fdc8d8SChris Lattner 
458e0d378b3SGreg Clayton         static OptionDefinition g_option_table[];
45930fdc8d8SChris Lattner 
46030fdc8d8SChris Lattner         // Instance variables to hold the values for command options.
46130fdc8d8SChris Lattner 
462144f3a9cSGreg Clayton         ProcessAttachInfo attach_info;
46330fdc8d8SChris Lattner     };
46430fdc8d8SChris Lattner 
465a7015092SGreg Clayton     CommandObjectProcessAttach (CommandInterpreter &interpreter) :
466dcb1d856SJim Ingham         CommandObjectProcessLaunchOrAttach (interpreter,
467a7015092SGreg Clayton                                             "process attach",
468e3d26315SCaroline Tice                                             "Attach to a process.",
469dcb1d856SJim Ingham                                             "process attach <cmd-options>",
470dcb1d856SJim Ingham                                             0,
471dcb1d856SJim Ingham                                             "attach"),
472*e1cfbc79STodd Fiala         m_options()
4735aee162fSJim Ingham     {
4745aee162fSJim Ingham     }
4755aee162fSJim Ingham 
47649bcfd80SEugene Zelenko     ~CommandObjectProcessAttach() override = default;
4775aee162fSJim Ingham 
4785a988416SJim Ingham     Options *
47913d21e9aSBruce Mitchener     GetOptions () override
4805a988416SJim Ingham     {
4815a988416SJim Ingham         return &m_options;
4825a988416SJim Ingham     }
4835a988416SJim Ingham 
4845a988416SJim Ingham protected:
4855aee162fSJim Ingham     bool
48613d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
4875aee162fSJim Ingham     {
488926af0cdSOleksiy Vyalov         PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
489926af0cdSOleksiy Vyalov 
490a7015092SGreg Clayton         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
49131412642SJim Ingham         // N.B. The attach should be synchronous.  It doesn't help much to get the prompt back between initiating the attach
49231412642SJim Ingham         // and the target actually stopping.  So even if the interpreter is set to be asynchronous, we wait for the stop
49331412642SJim Ingham         // ourselves here.
4945aee162fSJim Ingham 
49571337622SGreg Clayton         StateType state = eStateInvalid;
496dcb1d856SJim Ingham         Process *process = m_exe_ctx.GetProcessPtr();
497dcb1d856SJim Ingham 
498dcb1d856SJim Ingham         if (!StopProcessIfNecessary (process, state, result))
4995aee162fSJim Ingham             return false;
5005aee162fSJim Ingham 
50149bcfd80SEugene Zelenko         if (target == nullptr)
5025aee162fSJim Ingham         {
5035aee162fSJim Ingham             // If there isn't a current target create one.
5045aee162fSJim Ingham             TargetSP new_target_sp;
5055aee162fSJim Ingham             Error error;
5065aee162fSJim Ingham 
507a7015092SGreg Clayton             error = m_interpreter.GetDebugger().GetTargetList().CreateTarget(m_interpreter.GetDebugger(),
50849bcfd80SEugene Zelenko                                                                              nullptr,
50949bcfd80SEugene Zelenko                                                                              nullptr,
5105aee162fSJim Ingham                                                                              false,
51149bcfd80SEugene Zelenko                                                                              nullptr, // No platform options
5125aee162fSJim Ingham                                                                              new_target_sp);
5135aee162fSJim Ingham             target = new_target_sp.get();
51449bcfd80SEugene Zelenko             if (target == nullptr || error.Fail())
5155aee162fSJim Ingham             {
516b766a73dSGreg Clayton                 result.AppendError(error.AsCString("Error creating target"));
5175aee162fSJim Ingham                 return false;
5185aee162fSJim Ingham             }
519a7015092SGreg Clayton             m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target);
5205aee162fSJim Ingham         }
5215aee162fSJim Ingham 
5225aee162fSJim Ingham         // Record the old executable module, we want to issue a warning if the process of attaching changed the
5235aee162fSJim Ingham         // current executable (like somebody said "file foo" then attached to a PID whose executable was bar.)
5245aee162fSJim Ingham 
5255aee162fSJim Ingham         ModuleSP old_exec_module_sp = target->GetExecutableModule();
5265aee162fSJim Ingham         ArchSpec old_arch_spec = target->GetArchitecture();
5275aee162fSJim Ingham 
5285aee162fSJim Ingham         if (command.GetArgumentCount())
5295aee162fSJim Ingham         {
530fd54b368SJason Molenda             result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
5315aee162fSJim Ingham             result.SetStatus (eReturnStatusFailed);
532926af0cdSOleksiy Vyalov             return false;
53371337622SGreg Clayton         }
5345aee162fSJim Ingham 
535926af0cdSOleksiy Vyalov         m_interpreter.UpdateExecutionContext(nullptr);
53637386143SOleksiy Vyalov         StreamString stream;
53737386143SOleksiy Vyalov         const auto error = target->Attach(m_options.attach_info, &stream);
538144f3a9cSGreg Clayton         if (error.Success())
5393a0b9cdfSJim Ingham         {
54037386143SOleksiy Vyalov             ProcessSP process_sp (target->GetProcessSP());
54137386143SOleksiy Vyalov             if (process_sp)
542926af0cdSOleksiy Vyalov             {
543dc6224e0SGreg Clayton                 if (stream.GetData())
544dc6224e0SGreg Clayton                     result.AppendMessage(stream.GetData());
545bb3a283bSJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
54637386143SOleksiy Vyalov                 result.SetDidChangeProcessState (true);
547962260c8SJim Ingham                 result.SetAbnormalStopWasExpected(true);
548bb3a283bSJim Ingham             }
549aa739093SJohnny Chen             else
550aa739093SJohnny Chen             {
55137386143SOleksiy Vyalov                 result.AppendError("no error returned from Target::Attach, and target has no process");
552aa739093SJohnny Chen                 result.SetStatus (eReturnStatusFailed);
55344d93782SGreg Clayton             }
55444d93782SGreg Clayton         }
55544d93782SGreg Clayton         else
55644d93782SGreg Clayton         {
55744d93782SGreg Clayton             result.AppendErrorWithFormat ("attach failed: %s\n", error.AsCString());
55844d93782SGreg Clayton             result.SetStatus (eReturnStatusFailed);
559aa739093SJohnny Chen         }
5605aee162fSJim Ingham 
561926af0cdSOleksiy Vyalov         if (!result.Succeeded())
562926af0cdSOleksiy Vyalov             return false;
563926af0cdSOleksiy Vyalov 
5645aee162fSJim Ingham         // Okay, we're done.  Last step is to warn if the executable module has changed:
565513c26ceSGreg Clayton         char new_path[PATH_MAX];
566aa149cbdSGreg Clayton         ModuleSP new_exec_module_sp (target->GetExecutableModule());
5675aee162fSJim Ingham         if (!old_exec_module_sp)
5685aee162fSJim Ingham         {
569513c26ceSGreg Clayton             // We might not have a module if we attached to a raw pid...
570aa149cbdSGreg Clayton             if (new_exec_module_sp)
571513c26ceSGreg Clayton             {
572aa149cbdSGreg Clayton                 new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX);
573513c26ceSGreg Clayton                 result.AppendMessageWithFormat("Executable module set to \"%s\".\n", new_path);
574513c26ceSGreg Clayton             }
5755aee162fSJim Ingham         }
576aa149cbdSGreg Clayton         else if (old_exec_module_sp->GetFileSpec() != new_exec_module_sp->GetFileSpec())
5775aee162fSJim Ingham         {
578513c26ceSGreg Clayton             char old_path[PATH_MAX];
5795aee162fSJim Ingham 
5805aee162fSJim Ingham             old_exec_module_sp->GetFileSpec().GetPath (old_path, PATH_MAX);
581aa149cbdSGreg Clayton             new_exec_module_sp->GetFileSpec().GetPath (new_path, PATH_MAX);
5825aee162fSJim Ingham 
5835aee162fSJim Ingham             result.AppendWarningWithFormat("Executable module changed from \"%s\" to \"%s\".\n",
5845aee162fSJim Ingham                                                 old_path, new_path);
5855aee162fSJim Ingham         }
5865aee162fSJim Ingham 
5875aee162fSJim Ingham         if (!old_arch_spec.IsValid())
5885aee162fSJim Ingham         {
589c1b1f1eaSGreg Clayton             result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().GetTriple().getTriple().c_str());
5905aee162fSJim Ingham         }
591bf4b7be6SSean Callanan         else if (!old_arch_spec.IsExactMatch(target->GetArchitecture()))
5925aee162fSJim Ingham         {
5935aee162fSJim Ingham             result.AppendWarningWithFormat("Architecture changed from %s to %s.\n",
594c1b1f1eaSGreg Clayton                                            old_arch_spec.GetTriple().getTriple().c_str(),
595c1b1f1eaSGreg Clayton                                            target->GetArchitecture().GetTriple().getTriple().c_str());
5965aee162fSJim Ingham         }
597a95ce623SJohnny Chen 
598a95ce623SJohnny Chen         // This supports the use-case scenario of immediately continuing the process once attached.
599a95ce623SJohnny Chen         if (m_options.attach_info.GetContinueOnceAttached())
6005bcaf583SSean Callanan             m_interpreter.HandleCommand("process continue", eLazyBoolNo, result);
601926af0cdSOleksiy Vyalov 
6025aee162fSJim Ingham         return result.Succeeded();
6035aee162fSJim Ingham     }
6045aee162fSJim Ingham 
60530fdc8d8SChris Lattner     CommandOptions m_options;
60630fdc8d8SChris Lattner };
60730fdc8d8SChris Lattner 
608e0d378b3SGreg Clayton OptionDefinition
60930fdc8d8SChris Lattner CommandObjectProcessAttach::CommandOptions::g_option_table[] =
61030fdc8d8SChris Lattner {
61149bcfd80SEugene Zelenko { LLDB_OPT_SET_ALL, false, "continue",'c', OptionParser::eNoArgument,         nullptr, nullptr, 0, eArgTypeNone,         "Immediately continue the process once attached."},
61249bcfd80SEugene Zelenko { LLDB_OPT_SET_ALL, false, "plugin",  'P', OptionParser::eRequiredArgument,   nullptr, nullptr, 0, eArgTypePlugin,       "Name of the process plugin you want to use."},
61349bcfd80SEugene Zelenko { LLDB_OPT_SET_1,   false, "pid",     'p', OptionParser::eRequiredArgument,   nullptr, nullptr, 0, eArgTypePid,          "The process ID of an existing process to attach to."},
61449bcfd80SEugene Zelenko { LLDB_OPT_SET_2,   false, "name",    'n', OptionParser::eRequiredArgument,   nullptr, nullptr, 0, eArgTypeProcessName,  "The name of the process to attach to."},
61549bcfd80SEugene Zelenko { LLDB_OPT_SET_2,   false, "include-existing", 'i', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,         "Include existing processes when doing attach -w."},
61649bcfd80SEugene Zelenko { LLDB_OPT_SET_2,   false, "waitfor", 'w', OptionParser::eNoArgument,         nullptr, nullptr, 0, eArgTypeNone,         "Wait for the process with <process-name> to launch."},
61749bcfd80SEugene Zelenko { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
61830fdc8d8SChris Lattner };
61930fdc8d8SChris Lattner 
62030fdc8d8SChris Lattner //-------------------------------------------------------------------------
62130fdc8d8SChris Lattner // CommandObjectProcessContinue
62230fdc8d8SChris Lattner //-------------------------------------------------------------------------
623bb9caf73SJim Ingham #pragma mark CommandObjectProcessContinue
62430fdc8d8SChris Lattner 
6255a988416SJim Ingham class CommandObjectProcessContinue : public CommandObjectParsed
62630fdc8d8SChris Lattner {
62730fdc8d8SChris Lattner public:
628a7015092SGreg Clayton     CommandObjectProcessContinue (CommandInterpreter &interpreter) :
6295a988416SJim Ingham         CommandObjectParsed (interpreter,
630a7015092SGreg Clayton                              "process continue",
631e3d26315SCaroline Tice                              "Continue execution of all threads in the current process.",
63230fdc8d8SChris Lattner                              "process continue",
633e87764f2SEnrico Granata                              eCommandRequiresProcess       |
634e87764f2SEnrico Granata                              eCommandTryTargetAPILock      |
635e87764f2SEnrico Granata                              eCommandProcessMustBeLaunched |
636e87764f2SEnrico Granata                              eCommandProcessMustBePaused   ),
637*e1cfbc79STodd Fiala         m_options()
63830fdc8d8SChris Lattner     {
63930fdc8d8SChris Lattner     }
64030fdc8d8SChris Lattner 
64149bcfd80SEugene Zelenko     ~CommandObjectProcessContinue() override = default;
64230fdc8d8SChris Lattner 
6435a988416SJim Ingham protected:
6440e41084aSJim Ingham     class CommandOptions : public Options
6450e41084aSJim Ingham     {
6460e41084aSJim Ingham     public:
647*e1cfbc79STodd Fiala         CommandOptions() :
648*e1cfbc79STodd Fiala             Options()
6490e41084aSJim Ingham         {
6500e41084aSJim Ingham             // Keep default values of all options in one place: OptionParsingStarting ()
651*e1cfbc79STodd Fiala             OptionParsingStarting(nullptr);
6520e41084aSJim Ingham         }
6530e41084aSJim Ingham 
65449bcfd80SEugene Zelenko         ~CommandOptions() override = default;
6550e41084aSJim Ingham 
6560e41084aSJim Ingham         Error
657*e1cfbc79STodd Fiala         SetOptionValue(uint32_t option_idx, const char *option_arg,
658*e1cfbc79STodd Fiala                        ExecutionContext *execution_context) override
6590e41084aSJim Ingham         {
6600e41084aSJim Ingham             Error error;
6613bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
6620e41084aSJim Ingham             bool success = false;
6630e41084aSJim Ingham             switch (short_option)
6640e41084aSJim Ingham             {
6650e41084aSJim Ingham                 case 'i':
6665275aaa0SVince Harron                     m_ignore = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
6670e41084aSJim Ingham                     if (!success)
6680e41084aSJim Ingham                         error.SetErrorStringWithFormat ("invalid value for ignore option: \"%s\", should be a number.", option_arg);
6690e41084aSJim Ingham                     break;
6700e41084aSJim Ingham 
6710e41084aSJim Ingham                 default:
6720e41084aSJim Ingham                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
6730e41084aSJim Ingham                     break;
6740e41084aSJim Ingham             }
6750e41084aSJim Ingham             return error;
6760e41084aSJim Ingham         }
6770e41084aSJim Ingham 
6780e41084aSJim Ingham         void
679*e1cfbc79STodd Fiala         OptionParsingStarting(ExecutionContext *execution_context) override
6800e41084aSJim Ingham         {
6810e41084aSJim Ingham             m_ignore = 0;
6820e41084aSJim Ingham         }
6830e41084aSJim Ingham 
6840e41084aSJim Ingham         const OptionDefinition*
68513d21e9aSBruce Mitchener         GetDefinitions () override
6860e41084aSJim Ingham         {
6870e41084aSJim Ingham             return g_option_table;
6880e41084aSJim Ingham         }
6890e41084aSJim Ingham 
6900e41084aSJim Ingham         // Options table: Required for subclasses of Options.
6910e41084aSJim Ingham 
6920e41084aSJim Ingham         static OptionDefinition g_option_table[];
6930e41084aSJim Ingham 
6940e41084aSJim Ingham         uint32_t m_ignore;
6950e41084aSJim Ingham     };
6960e41084aSJim Ingham 
69730fdc8d8SChris Lattner     bool
69813d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
69930fdc8d8SChris Lattner     {
700f9fc609fSGreg Clayton         Process *process = m_exe_ctx.GetProcessPtr();
701a7015092SGreg Clayton         bool synchronous_execution = m_interpreter.GetSynchronous ();
70230fdc8d8SChris Lattner         StateType state = process->GetState();
70330fdc8d8SChris Lattner         if (state == eStateStopped)
70430fdc8d8SChris Lattner         {
70530fdc8d8SChris Lattner             if (command.GetArgumentCount() != 0)
70630fdc8d8SChris Lattner             {
70730fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("The '%s' command does not take any arguments.\n", m_cmd_name.c_str());
70830fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
70930fdc8d8SChris Lattner                 return false;
71030fdc8d8SChris Lattner             }
71130fdc8d8SChris Lattner 
7120e41084aSJim Ingham             if (m_options.m_ignore > 0)
7130e41084aSJim Ingham             {
7148d94ba0fSJim Ingham                 ThreadSP sel_thread_sp(GetDefaultThread()->shared_from_this());
7150e41084aSJim Ingham                 if (sel_thread_sp)
7160e41084aSJim Ingham                 {
7170e41084aSJim Ingham                     StopInfoSP stop_info_sp = sel_thread_sp->GetStopInfo();
7180e41084aSJim Ingham                     if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonBreakpoint)
7190e41084aSJim Ingham                     {
720c7bece56SGreg Clayton                         lldb::break_id_t bp_site_id = (lldb::break_id_t)stop_info_sp->GetValue();
7210e41084aSJim Ingham                         BreakpointSiteSP bp_site_sp(process->GetBreakpointSiteList().FindByID(bp_site_id));
7220e41084aSJim Ingham                         if (bp_site_sp)
7230e41084aSJim Ingham                         {
724c7bece56SGreg Clayton                             const size_t num_owners = bp_site_sp->GetNumberOfOwners();
725c7bece56SGreg Clayton                             for (size_t i = 0; i < num_owners; i++)
7260e41084aSJim Ingham                             {
7270e41084aSJim Ingham                                 Breakpoint &bp_ref = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
7280e41084aSJim Ingham                                 if (!bp_ref.IsInternal())
7290e41084aSJim Ingham                                 {
7300e41084aSJim Ingham                                     bp_ref.SetIgnoreCount(m_options.m_ignore);
7310e41084aSJim Ingham                                 }
7320e41084aSJim Ingham                             }
7330e41084aSJim Ingham                         }
7340e41084aSJim Ingham                     }
7350e41084aSJim Ingham                 }
7360e41084aSJim Ingham             }
7370e41084aSJim Ingham 
73841f2b940SJim Ingham             {  // Scope for thread list mutex:
739bb19a13cSSaleem Abdulrasool                 std::lock_guard<std::recursive_mutex> guard(process->GetThreadList().GetMutex());
74030fdc8d8SChris Lattner                 const uint32_t num_threads = process->GetThreadList().GetSize();
74130fdc8d8SChris Lattner 
74230fdc8d8SChris Lattner                 // Set the actions that the threads should each take when resuming
74330fdc8d8SChris Lattner                 for (uint32_t idx=0; idx<num_threads; ++idx)
74430fdc8d8SChris Lattner                 {
7456c9ed91cSJim Ingham                     const bool override_suspend = false;
7466c9ed91cSJim Ingham                     process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState (eStateRunning, override_suspend);
74730fdc8d8SChris Lattner                 }
74841f2b940SJim Ingham             }
74930fdc8d8SChris Lattner 
7504446487dSPavel Labath             const uint32_t iohandler_id = process->GetIOHandlerID();
7514446487dSPavel Labath 
752dc6224e0SGreg Clayton             StreamString stream;
753dc6224e0SGreg Clayton             Error error;
754dc6224e0SGreg Clayton             if (synchronous_execution)
755dc6224e0SGreg Clayton                 error = process->ResumeSynchronous (&stream);
756dc6224e0SGreg Clayton             else
757dc6224e0SGreg Clayton                 error = process->Resume ();
758a3b89e27STodd Fiala 
75930fdc8d8SChris Lattner             if (error.Success())
76030fdc8d8SChris Lattner             {
761a3b89e27STodd Fiala                 // There is a race condition where this thread will return up the call stack to the main command
762a3b89e27STodd Fiala                  // handler and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has
763a3b89e27STodd Fiala                  // a chance to call PushProcessIOHandler().
7644446487dSPavel Labath                 process->SyncIOHandler(iohandler_id, 2000);
765a3b89e27STodd Fiala 
766d01b2953SDaniel Malea                 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
76730fdc8d8SChris Lattner                 if (synchronous_execution)
76830fdc8d8SChris Lattner                 {
769dc6224e0SGreg Clayton                     // If any state changed events had anything to say, add that to the result
770dc6224e0SGreg Clayton                     if (stream.GetData())
771dc6224e0SGreg Clayton                         result.AppendMessage(stream.GetData());
77230fdc8d8SChris Lattner 
77330fdc8d8SChris Lattner                     result.SetDidChangeProcessState (true);
77430fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
77530fdc8d8SChris Lattner                 }
77630fdc8d8SChris Lattner                 else
77730fdc8d8SChris Lattner                 {
77830fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusSuccessContinuingNoResult);
77930fdc8d8SChris Lattner                 }
78030fdc8d8SChris Lattner             }
78130fdc8d8SChris Lattner             else
78230fdc8d8SChris Lattner             {
78330fdc8d8SChris Lattner                 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
78430fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
78530fdc8d8SChris Lattner             }
78630fdc8d8SChris Lattner         }
78730fdc8d8SChris Lattner         else
78830fdc8d8SChris Lattner         {
78930fdc8d8SChris Lattner             result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
79030fdc8d8SChris Lattner                                          StateAsCString(state));
79130fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
79230fdc8d8SChris Lattner         }
79330fdc8d8SChris Lattner         return result.Succeeded();
79430fdc8d8SChris Lattner     }
7950e41084aSJim Ingham 
7960e41084aSJim Ingham     Options *
79713d21e9aSBruce Mitchener     GetOptions () override
7980e41084aSJim Ingham     {
7990e41084aSJim Ingham         return &m_options;
8000e41084aSJim Ingham     }
8010e41084aSJim Ingham 
8020e41084aSJim Ingham     CommandOptions m_options;
8030e41084aSJim Ingham };
8040e41084aSJim Ingham 
8050e41084aSJim Ingham OptionDefinition
8060e41084aSJim Ingham CommandObjectProcessContinue::CommandOptions::g_option_table[] =
8070e41084aSJim Ingham {
80849bcfd80SEugene Zelenko { LLDB_OPT_SET_ALL, false, "ignore-count",'i', OptionParser::eRequiredArgument,         nullptr, nullptr, 0, eArgTypeUnsignedInteger,
8090e41084aSJim Ingham                            "Ignore <N> crossings of the breakpoint (if it exists) for the currently selected thread."},
81049bcfd80SEugene Zelenko { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
81130fdc8d8SChris Lattner };
81230fdc8d8SChris Lattner 
81330fdc8d8SChris Lattner //-------------------------------------------------------------------------
81430fdc8d8SChris Lattner // CommandObjectProcessDetach
81530fdc8d8SChris Lattner //-------------------------------------------------------------------------
816bb9caf73SJim Ingham #pragma mark CommandObjectProcessDetach
81730fdc8d8SChris Lattner 
8185a988416SJim Ingham class CommandObjectProcessDetach : public CommandObjectParsed
81930fdc8d8SChris Lattner {
82030fdc8d8SChris Lattner public:
821acff8950SJim Ingham     class CommandOptions : public Options
822acff8950SJim Ingham     {
823acff8950SJim Ingham     public:
824*e1cfbc79STodd Fiala         CommandOptions() :
825*e1cfbc79STodd Fiala             Options()
826acff8950SJim Ingham         {
827*e1cfbc79STodd Fiala             OptionParsingStarting(nullptr);
828acff8950SJim Ingham         }
829acff8950SJim Ingham 
83049bcfd80SEugene Zelenko         ~CommandOptions() override = default;
831acff8950SJim Ingham 
832acff8950SJim Ingham         Error
833*e1cfbc79STodd Fiala         SetOptionValue(uint32_t option_idx, const char *option_arg,
834*e1cfbc79STodd Fiala                        ExecutionContext *execution_context) override
835acff8950SJim Ingham         {
836acff8950SJim Ingham             Error error;
837acff8950SJim Ingham             const int short_option = m_getopt_table[option_idx].val;
838acff8950SJim Ingham 
839acff8950SJim Ingham             switch (short_option)
840acff8950SJim Ingham             {
841acff8950SJim Ingham                 case 's':
842acff8950SJim Ingham                     bool tmp_result;
843acff8950SJim Ingham                     bool success;
844acff8950SJim Ingham                     tmp_result = Args::StringToBoolean(option_arg, false, &success);
845acff8950SJim Ingham                     if (!success)
846acff8950SJim Ingham                         error.SetErrorStringWithFormat("invalid boolean option: \"%s\"", option_arg);
847acff8950SJim Ingham                     else
848acff8950SJim Ingham                     {
849acff8950SJim Ingham                         if (tmp_result)
850acff8950SJim Ingham                             m_keep_stopped = eLazyBoolYes;
851acff8950SJim Ingham                         else
852acff8950SJim Ingham                             m_keep_stopped = eLazyBoolNo;
853acff8950SJim Ingham                     }
854acff8950SJim Ingham                     break;
855acff8950SJim Ingham                 default:
856acff8950SJim Ingham                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
857acff8950SJim Ingham                     break;
858acff8950SJim Ingham             }
859acff8950SJim Ingham             return error;
860acff8950SJim Ingham         }
861acff8950SJim Ingham 
862acff8950SJim Ingham         void
863*e1cfbc79STodd Fiala         OptionParsingStarting(ExecutionContext *execution_context) override
864acff8950SJim Ingham         {
865acff8950SJim Ingham             m_keep_stopped = eLazyBoolCalculate;
866acff8950SJim Ingham         }
867acff8950SJim Ingham 
868acff8950SJim Ingham         const OptionDefinition*
86913d21e9aSBruce Mitchener         GetDefinitions () override
870acff8950SJim Ingham         {
871acff8950SJim Ingham             return g_option_table;
872acff8950SJim Ingham         }
873acff8950SJim Ingham 
874acff8950SJim Ingham         // Options table: Required for subclasses of Options.
875acff8950SJim Ingham 
876acff8950SJim Ingham         static OptionDefinition g_option_table[];
877acff8950SJim Ingham 
878acff8950SJim Ingham         // Instance variables to hold the values for command options.
879acff8950SJim Ingham         LazyBool m_keep_stopped;
880acff8950SJim Ingham     };
88130fdc8d8SChris Lattner 
8827428a18cSKate Stone     CommandObjectProcessDetach(CommandInterpreter &interpreter)
8837428a18cSKate Stone         : CommandObjectParsed(interpreter, "process detach", "Detach from the current target process.",
884a7015092SGreg Clayton                               "process detach",
8857428a18cSKate Stone                               eCommandRequiresProcess | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched),
886*e1cfbc79STodd Fiala           m_options()
88730fdc8d8SChris Lattner     {
88830fdc8d8SChris Lattner     }
88930fdc8d8SChris Lattner 
89049bcfd80SEugene Zelenko     ~CommandObjectProcessDetach() override = default;
89130fdc8d8SChris Lattner 
892acff8950SJim Ingham     Options *
89313d21e9aSBruce Mitchener     GetOptions () override
894acff8950SJim Ingham     {
895acff8950SJim Ingham         return &m_options;
896acff8950SJim Ingham     }
897acff8950SJim Ingham 
8985a988416SJim Ingham protected:
89930fdc8d8SChris Lattner     bool
90013d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
90130fdc8d8SChris Lattner     {
902f9fc609fSGreg Clayton         Process *process = m_exe_ctx.GetProcessPtr();
903acff8950SJim Ingham         // FIXME: This will be a Command Option:
904acff8950SJim Ingham         bool keep_stopped;
905acff8950SJim Ingham         if (m_options.m_keep_stopped == eLazyBoolCalculate)
906acff8950SJim Ingham         {
907acff8950SJim Ingham             // Check the process default:
90849bcfd80SEugene Zelenko             keep_stopped = process->GetDetachKeepsStopped();
909acff8950SJim Ingham         }
910acff8950SJim Ingham         else if (m_options.m_keep_stopped == eLazyBoolYes)
911acff8950SJim Ingham             keep_stopped = true;
912acff8950SJim Ingham         else
913acff8950SJim Ingham             keep_stopped = false;
914acff8950SJim Ingham 
915acff8950SJim Ingham         Error error (process->Detach(keep_stopped));
91630fdc8d8SChris Lattner         if (error.Success())
91730fdc8d8SChris Lattner         {
91830fdc8d8SChris Lattner             result.SetStatus (eReturnStatusSuccessFinishResult);
91930fdc8d8SChris Lattner         }
92030fdc8d8SChris Lattner         else
92130fdc8d8SChris Lattner         {
92230fdc8d8SChris Lattner             result.AppendErrorWithFormat ("Detach failed: %s\n", error.AsCString());
92330fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
92430fdc8d8SChris Lattner             return false;
92530fdc8d8SChris Lattner         }
92630fdc8d8SChris Lattner         return result.Succeeded();
92730fdc8d8SChris Lattner     }
928acff8950SJim Ingham 
929acff8950SJim Ingham     CommandOptions m_options;
930acff8950SJim Ingham };
931acff8950SJim Ingham 
932acff8950SJim Ingham OptionDefinition
933acff8950SJim Ingham CommandObjectProcessDetach::CommandOptions::g_option_table[] =
934acff8950SJim Ingham {
93549bcfd80SEugene 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)." },
93649bcfd80SEugene Zelenko { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
93730fdc8d8SChris Lattner };
93830fdc8d8SChris Lattner 
93930fdc8d8SChris Lattner //-------------------------------------------------------------------------
940b766a73dSGreg Clayton // CommandObjectProcessConnect
941b766a73dSGreg Clayton //-------------------------------------------------------------------------
942b766a73dSGreg Clayton #pragma mark CommandObjectProcessConnect
943b766a73dSGreg Clayton 
9445a988416SJim Ingham class CommandObjectProcessConnect : public CommandObjectParsed
945b766a73dSGreg Clayton {
946b766a73dSGreg Clayton public:
947b766a73dSGreg Clayton     class CommandOptions : public Options
948b766a73dSGreg Clayton     {
949b766a73dSGreg Clayton     public:
950*e1cfbc79STodd Fiala         CommandOptions() :
951*e1cfbc79STodd Fiala             Options()
952b766a73dSGreg Clayton         {
953f6b8b581SGreg Clayton             // Keep default values of all options in one place: OptionParsingStarting ()
954*e1cfbc79STodd Fiala             OptionParsingStarting(nullptr);
955b766a73dSGreg Clayton         }
956b766a73dSGreg Clayton 
95749bcfd80SEugene Zelenko         ~CommandOptions() override = default;
958b766a73dSGreg Clayton 
959b766a73dSGreg Clayton         Error
960*e1cfbc79STodd Fiala         SetOptionValue(uint32_t option_idx, const char *option_arg,
961*e1cfbc79STodd Fiala                        ExecutionContext *execution_context) override
962b766a73dSGreg Clayton         {
963b766a73dSGreg Clayton             Error error;
9643bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
965b766a73dSGreg Clayton 
966b766a73dSGreg Clayton             switch (short_option)
967b766a73dSGreg Clayton             {
968b766a73dSGreg Clayton             case 'p':
969b766a73dSGreg Clayton                 plugin_name.assign (option_arg);
970b766a73dSGreg Clayton                 break;
971b766a73dSGreg Clayton 
972b766a73dSGreg Clayton             default:
97386edbf41SGreg Clayton                 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
974b766a73dSGreg Clayton                 break;
975b766a73dSGreg Clayton             }
976b766a73dSGreg Clayton             return error;
977b766a73dSGreg Clayton         }
978b766a73dSGreg Clayton 
979b766a73dSGreg Clayton         void
980*e1cfbc79STodd Fiala         OptionParsingStarting(ExecutionContext *execution_context) override
981b766a73dSGreg Clayton         {
982b766a73dSGreg Clayton             plugin_name.clear();
983b766a73dSGreg Clayton         }
984b766a73dSGreg Clayton 
985e0d378b3SGreg Clayton         const OptionDefinition*
98613d21e9aSBruce Mitchener         GetDefinitions () override
987b766a73dSGreg Clayton         {
988b766a73dSGreg Clayton             return g_option_table;
989b766a73dSGreg Clayton         }
990b766a73dSGreg Clayton 
991b766a73dSGreg Clayton         // Options table: Required for subclasses of Options.
992b766a73dSGreg Clayton 
993e0d378b3SGreg Clayton         static OptionDefinition g_option_table[];
994b766a73dSGreg Clayton 
995b766a73dSGreg Clayton         // Instance variables to hold the values for command options.
996b766a73dSGreg Clayton 
997b766a73dSGreg Clayton         std::string plugin_name;
998b766a73dSGreg Clayton     };
999b766a73dSGreg Clayton 
1000b766a73dSGreg Clayton     CommandObjectProcessConnect (CommandInterpreter &interpreter) :
10015a988416SJim Ingham         CommandObjectParsed (interpreter,
1002b766a73dSGreg Clayton                              "process connect",
1003b766a73dSGreg Clayton                              "Connect to a remote debug service.",
1004b766a73dSGreg Clayton                              "process connect <remote-url>",
1005eb0103f2SGreg Clayton                              0),
1006*e1cfbc79STodd Fiala         m_options()
1007b766a73dSGreg Clayton     {
1008b766a73dSGreg Clayton     }
1009b766a73dSGreg Clayton 
101049bcfd80SEugene Zelenko     ~CommandObjectProcessConnect() override = default;
1011b766a73dSGreg Clayton 
10125a988416SJim Ingham     Options *
101313d21e9aSBruce Mitchener     GetOptions () override
10145a988416SJim Ingham     {
10155a988416SJim Ingham         return &m_options;
10165a988416SJim Ingham     }
10175a988416SJim Ingham 
10185a988416SJim Ingham protected:
1019b766a73dSGreg Clayton     bool
102013d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
1021b766a73dSGreg Clayton     {
1022ccd6cffbSTamas Berghammer         if (command.GetArgumentCount() != 1)
1023b766a73dSGreg Clayton         {
1024ccd6cffbSTamas Berghammer             result.AppendErrorWithFormat ("'%s' takes exactly one argument:\nUsage: %s\n",
1025ccd6cffbSTamas Berghammer                                           m_cmd_name.c_str(),
1026ccd6cffbSTamas Berghammer                                           m_cmd_syntax.c_str());
1027ccd6cffbSTamas Berghammer             result.SetStatus (eReturnStatusFailed);
1028ccd6cffbSTamas Berghammer             return false;
1029ccd6cffbSTamas Berghammer         }
1030ccd6cffbSTamas Berghammer 
1031ccd6cffbSTamas Berghammer         Process *process = m_exe_ctx.GetProcessPtr();
1032ccd6cffbSTamas Berghammer         if (process && process->IsAlive())
1033b766a73dSGreg Clayton         {
1034d01b2953SDaniel Malea             result.AppendErrorWithFormat ("Process %" PRIu64 " is currently being debugged, kill the process before connecting.\n",
1035b766a73dSGreg Clayton                                           process->GetID());
1036b766a73dSGreg Clayton             result.SetStatus (eReturnStatusFailed);
1037b766a73dSGreg Clayton             return false;
1038b766a73dSGreg Clayton         }
1039b766a73dSGreg Clayton 
1040ccd6cffbSTamas Berghammer         const char *plugin_name = nullptr;
1041b766a73dSGreg Clayton         if (!m_options.plugin_name.empty())
1042b766a73dSGreg Clayton             plugin_name = m_options.plugin_name.c_str();
1043b766a73dSGreg Clayton 
1044ccd6cffbSTamas Berghammer         Error error;
1045ccd6cffbSTamas Berghammer         Debugger& debugger = m_interpreter.GetDebugger();
1046ccd6cffbSTamas Berghammer         PlatformSP platform_sp = m_interpreter.GetPlatform(true);
1047ccd6cffbSTamas Berghammer         ProcessSP process_sp = platform_sp->ConnectProcess(command.GetArgumentAtIndex(0),
1048ccd6cffbSTamas Berghammer                                                            plugin_name,
1049ccd6cffbSTamas Berghammer                                                            debugger,
1050ccd6cffbSTamas Berghammer                                                            debugger.GetSelectedTarget().get(),
1051ccd6cffbSTamas Berghammer                                                            error);
1052ccd6cffbSTamas Berghammer         if (error.Fail() || process_sp == nullptr)
1053b766a73dSGreg Clayton         {
1054ccd6cffbSTamas Berghammer             result.AppendError(error.AsCString("Error connecting to the process"));
1055b766a73dSGreg Clayton             result.SetStatus (eReturnStatusFailed);
1056b766a73dSGreg Clayton             return false;
1057b766a73dSGreg Clayton         }
1058ccd6cffbSTamas Berghammer         return true;
1059b766a73dSGreg Clayton     }
1060b766a73dSGreg Clayton 
1061b766a73dSGreg Clayton     CommandOptions m_options;
1062b766a73dSGreg Clayton };
1063b766a73dSGreg Clayton 
1064e0d378b3SGreg Clayton OptionDefinition
1065b766a73dSGreg Clayton CommandObjectProcessConnect::CommandOptions::g_option_table[] =
1066b766a73dSGreg Clayton {
106749bcfd80SEugene Zelenko     { LLDB_OPT_SET_ALL, false, "plugin", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePlugin, "Name of the process plugin you want to use."},
106849bcfd80SEugene Zelenko     { 0,                false, nullptr,      0 , 0,                 nullptr, nullptr, 0, eArgTypeNone,   nullptr }
1069b766a73dSGreg Clayton };
1070b766a73dSGreg Clayton 
1071b766a73dSGreg Clayton //-------------------------------------------------------------------------
1072998255bfSGreg Clayton // CommandObjectProcessPlugin
1073998255bfSGreg Clayton //-------------------------------------------------------------------------
1074998255bfSGreg Clayton #pragma mark CommandObjectProcessPlugin
1075998255bfSGreg Clayton 
1076998255bfSGreg Clayton class CommandObjectProcessPlugin : public CommandObjectProxy
1077998255bfSGreg Clayton {
1078998255bfSGreg Clayton public:
10797428a18cSKate Stone     CommandObjectProcessPlugin(CommandInterpreter &interpreter)
10807428a18cSKate Stone         : CommandObjectProxy(interpreter, "process plugin",
10817428a18cSKate Stone                              "Send a custom command to the current target process plug-in.", "process plugin <args>", 0)
1082998255bfSGreg Clayton     {
1083998255bfSGreg Clayton     }
1084998255bfSGreg Clayton 
108549bcfd80SEugene Zelenko     ~CommandObjectProcessPlugin() override = default;
1086998255bfSGreg Clayton 
108713d21e9aSBruce Mitchener     CommandObject *
108813d21e9aSBruce Mitchener     GetProxyCommandObject() override
1089998255bfSGreg Clayton     {
1090e05b2efeSGreg Clayton         Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
1091998255bfSGreg Clayton         if (process)
1092998255bfSGreg Clayton             return process->GetPluginCommandObject();
109349bcfd80SEugene Zelenko         return nullptr;
1094998255bfSGreg Clayton     }
1095998255bfSGreg Clayton };
1096998255bfSGreg Clayton 
1097998255bfSGreg Clayton //-------------------------------------------------------------------------
10988f343b09SGreg Clayton // CommandObjectProcessLoad
10998f343b09SGreg Clayton //-------------------------------------------------------------------------
1100bb9caf73SJim Ingham #pragma mark CommandObjectProcessLoad
11018f343b09SGreg Clayton 
11025a988416SJim Ingham class CommandObjectProcessLoad : public CommandObjectParsed
11038f343b09SGreg Clayton {
11048f343b09SGreg Clayton public:
11054fbd67acSTamas Berghammer     class CommandOptions : public Options
11064fbd67acSTamas Berghammer     {
11074fbd67acSTamas Berghammer     public:
1108*e1cfbc79STodd Fiala         CommandOptions() :
1109*e1cfbc79STodd Fiala             Options()
11104fbd67acSTamas Berghammer         {
11114fbd67acSTamas Berghammer             // Keep default values of all options in one place: OptionParsingStarting ()
1112*e1cfbc79STodd Fiala             OptionParsingStarting(nullptr);
11134fbd67acSTamas Berghammer         }
11144fbd67acSTamas Berghammer 
11154fbd67acSTamas Berghammer         ~CommandOptions() override = default;
11164fbd67acSTamas Berghammer 
11174fbd67acSTamas Berghammer         Error
1118*e1cfbc79STodd Fiala         SetOptionValue(uint32_t option_idx, const char *option_arg,
1119*e1cfbc79STodd Fiala                        ExecutionContext *execution_context) override
11204fbd67acSTamas Berghammer         {
11214fbd67acSTamas Berghammer             Error error;
11224fbd67acSTamas Berghammer             const int short_option = m_getopt_table[option_idx].val;
11234fbd67acSTamas Berghammer             switch (short_option)
11244fbd67acSTamas Berghammer             {
11254fbd67acSTamas Berghammer             case 'i':
11264fbd67acSTamas Berghammer                 do_install = true;
11274fbd67acSTamas Berghammer                 if (option_arg && option_arg[0])
11284fbd67acSTamas Berghammer                     install_path.SetFile(option_arg, false);
11294fbd67acSTamas Berghammer                 break;
11304fbd67acSTamas Berghammer             default:
11314fbd67acSTamas Berghammer                 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
11324fbd67acSTamas Berghammer                 break;
11334fbd67acSTamas Berghammer             }
11344fbd67acSTamas Berghammer             return error;
11354fbd67acSTamas Berghammer         }
11364fbd67acSTamas Berghammer 
11374fbd67acSTamas Berghammer         void
1138*e1cfbc79STodd Fiala         OptionParsingStarting(ExecutionContext *execution_context) override
11394fbd67acSTamas Berghammer         {
11404fbd67acSTamas Berghammer             do_install = false;
11414fbd67acSTamas Berghammer             install_path.Clear();
11424fbd67acSTamas Berghammer         }
11434fbd67acSTamas Berghammer 
11444fbd67acSTamas Berghammer         const OptionDefinition*
11454fbd67acSTamas Berghammer         GetDefinitions () override
11464fbd67acSTamas Berghammer         {
11474fbd67acSTamas Berghammer             return g_option_table;
11484fbd67acSTamas Berghammer         }
11494fbd67acSTamas Berghammer 
11504fbd67acSTamas Berghammer         // Options table: Required for subclasses of Options.
11514fbd67acSTamas Berghammer         static OptionDefinition g_option_table[];
11524fbd67acSTamas Berghammer 
11534fbd67acSTamas Berghammer         // Instance variables to hold the values for command options.
11544fbd67acSTamas Berghammer         bool do_install;
11554fbd67acSTamas Berghammer         FileSpec install_path;
11564fbd67acSTamas Berghammer     };
11578f343b09SGreg Clayton 
11588f343b09SGreg Clayton     CommandObjectProcessLoad (CommandInterpreter &interpreter) :
11595a988416SJim Ingham         CommandObjectParsed (interpreter,
11608f343b09SGreg Clayton                              "process load",
11618f343b09SGreg Clayton                              "Load a shared library into the current process.",
11628f343b09SGreg Clayton                              "process load <filename> [<filename> ...]",
1163e87764f2SEnrico Granata                              eCommandRequiresProcess       |
1164e87764f2SEnrico Granata                              eCommandTryTargetAPILock      |
1165e87764f2SEnrico Granata                              eCommandProcessMustBeLaunched |
11664fbd67acSTamas Berghammer                              eCommandProcessMustBePaused   ),
1167*e1cfbc79STodd Fiala         m_options()
11688f343b09SGreg Clayton     {
11698f343b09SGreg Clayton     }
11708f343b09SGreg Clayton 
11714fbd67acSTamas Berghammer     ~CommandObjectProcessLoad() override = default;
11724fbd67acSTamas Berghammer 
11734fbd67acSTamas Berghammer     Options *
11744fbd67acSTamas Berghammer     GetOptions () override
11758f343b09SGreg Clayton     {
11764fbd67acSTamas Berghammer         return &m_options;
11778f343b09SGreg Clayton     }
11788f343b09SGreg Clayton 
11795a988416SJim Ingham protected:
11808f343b09SGreg Clayton     bool
118113d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
11828f343b09SGreg Clayton     {
1183f9fc609fSGreg Clayton         Process *process = m_exe_ctx.GetProcessPtr();
11848f343b09SGreg Clayton 
1185c7bece56SGreg Clayton         const size_t argc = command.GetArgumentCount();
11868f343b09SGreg Clayton         for (uint32_t i = 0; i < argc; ++i)
11878f343b09SGreg Clayton         {
11888f343b09SGreg Clayton             Error error;
11893cb132a0STamas Berghammer             PlatformSP platform = process->GetTarget().GetPlatform();
11904fbd67acSTamas Berghammer             const char *image_path = command.GetArgumentAtIndex(i);
11914fbd67acSTamas Berghammer             uint32_t image_token = LLDB_INVALID_IMAGE_TOKEN;
11924fbd67acSTamas Berghammer 
11934fbd67acSTamas Berghammer             if (!m_options.do_install)
11944fbd67acSTamas Berghammer             {
11954fbd67acSTamas Berghammer                 FileSpec image_spec (image_path, false);
11963cb132a0STamas Berghammer                 platform->ResolveRemotePath(image_spec, image_spec);
11974fbd67acSTamas Berghammer                 image_token = platform->LoadImage(process, FileSpec(), image_spec, error);
11984fbd67acSTamas Berghammer             }
11994fbd67acSTamas Berghammer             else if (m_options.install_path)
12004fbd67acSTamas Berghammer             {
12014fbd67acSTamas Berghammer                 FileSpec image_spec (image_path, true);
12024fbd67acSTamas Berghammer                 platform->ResolveRemotePath(m_options.install_path, m_options.install_path);
12034fbd67acSTamas Berghammer                 image_token = platform->LoadImage(process, image_spec, m_options.install_path, error);
12044fbd67acSTamas Berghammer             }
12054fbd67acSTamas Berghammer             else
12064fbd67acSTamas Berghammer             {
12074fbd67acSTamas Berghammer                 FileSpec image_spec (image_path, true);
12084fbd67acSTamas Berghammer                 image_token = platform->LoadImage(process, image_spec, FileSpec(), error);
12094fbd67acSTamas Berghammer             }
12104fbd67acSTamas Berghammer 
12118f343b09SGreg Clayton             if (image_token != LLDB_INVALID_IMAGE_TOKEN)
12128f343b09SGreg Clayton             {
12138f343b09SGreg Clayton                 result.AppendMessageWithFormat ("Loading \"%s\"...ok\nImage %u loaded.\n", image_path, image_token);
12148f343b09SGreg Clayton                 result.SetStatus (eReturnStatusSuccessFinishResult);
12158f343b09SGreg Clayton             }
12168f343b09SGreg Clayton             else
12178f343b09SGreg Clayton             {
12188f343b09SGreg Clayton                 result.AppendErrorWithFormat ("failed to load '%s': %s", image_path, error.AsCString());
12198f343b09SGreg Clayton                 result.SetStatus (eReturnStatusFailed);
12208f343b09SGreg Clayton             }
12218f343b09SGreg Clayton         }
12228f343b09SGreg Clayton         return result.Succeeded();
12238f343b09SGreg Clayton     }
12244fbd67acSTamas Berghammer 
12254fbd67acSTamas Berghammer     CommandOptions m_options;
12268f343b09SGreg Clayton };
12278f343b09SGreg Clayton 
12284fbd67acSTamas Berghammer OptionDefinition
12294fbd67acSTamas Berghammer CommandObjectProcessLoad::CommandOptions::g_option_table[] =
12304fbd67acSTamas Berghammer {
12314fbd67acSTamas 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."},
12324fbd67acSTamas Berghammer     { 0,                false, nullptr,    0 , 0,                               nullptr, nullptr, 0, eArgTypeNone, nullptr }
12334fbd67acSTamas Berghammer };
12348f343b09SGreg Clayton 
12358f343b09SGreg Clayton //-------------------------------------------------------------------------
12368f343b09SGreg Clayton // CommandObjectProcessUnload
12378f343b09SGreg Clayton //-------------------------------------------------------------------------
1238bb9caf73SJim Ingham #pragma mark CommandObjectProcessUnload
12398f343b09SGreg Clayton 
12405a988416SJim Ingham class CommandObjectProcessUnload : public CommandObjectParsed
12418f343b09SGreg Clayton {
12428f343b09SGreg Clayton public:
12438f343b09SGreg Clayton 
12448f343b09SGreg Clayton     CommandObjectProcessUnload (CommandInterpreter &interpreter) :
12455a988416SJim Ingham         CommandObjectParsed (interpreter,
12468f343b09SGreg Clayton                              "process unload",
12478f343b09SGreg Clayton                              "Unload a shared library from the current process using the index returned by a previous call to \"process load\".",
12488f343b09SGreg Clayton                              "process unload <index>",
1249e87764f2SEnrico Granata                              eCommandRequiresProcess       |
1250e87764f2SEnrico Granata                              eCommandTryTargetAPILock      |
1251e87764f2SEnrico Granata                              eCommandProcessMustBeLaunched |
1252e87764f2SEnrico Granata                              eCommandProcessMustBePaused   )
12538f343b09SGreg Clayton     {
12548f343b09SGreg Clayton     }
12558f343b09SGreg Clayton 
125649bcfd80SEugene Zelenko     ~CommandObjectProcessUnload() override = default;
12578f343b09SGreg Clayton 
12585a988416SJim Ingham protected:
12598f343b09SGreg Clayton     bool
126013d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
12618f343b09SGreg Clayton     {
1262f9fc609fSGreg Clayton         Process *process = m_exe_ctx.GetProcessPtr();
12638f343b09SGreg Clayton 
1264c7bece56SGreg Clayton         const size_t argc = command.GetArgumentCount();
12658f343b09SGreg Clayton 
12668f343b09SGreg Clayton         for (uint32_t i = 0; i < argc; ++i)
12678f343b09SGreg Clayton         {
12688f343b09SGreg Clayton             const char *image_token_cstr = command.GetArgumentAtIndex(i);
12695275aaa0SVince Harron             uint32_t image_token = StringConvert::ToUInt32(image_token_cstr, LLDB_INVALID_IMAGE_TOKEN, 0);
12708f343b09SGreg Clayton             if (image_token == LLDB_INVALID_IMAGE_TOKEN)
12718f343b09SGreg Clayton             {
12728f343b09SGreg Clayton                 result.AppendErrorWithFormat ("invalid image index argument '%s'", image_token_cstr);
12738f343b09SGreg Clayton                 result.SetStatus (eReturnStatusFailed);
12748f343b09SGreg Clayton                 break;
12758f343b09SGreg Clayton             }
12768f343b09SGreg Clayton             else
12778f343b09SGreg Clayton             {
12783cb132a0STamas Berghammer                 Error error (process->GetTarget().GetPlatform()->UnloadImage(process, image_token));
12798f343b09SGreg Clayton                 if (error.Success())
12808f343b09SGreg Clayton                 {
12818f343b09SGreg Clayton                     result.AppendMessageWithFormat ("Unloading shared library with index %u...ok\n", image_token);
12828f343b09SGreg Clayton                     result.SetStatus (eReturnStatusSuccessFinishResult);
12838f343b09SGreg Clayton                 }
12848f343b09SGreg Clayton                 else
12858f343b09SGreg Clayton                 {
12868f343b09SGreg Clayton                     result.AppendErrorWithFormat ("failed to unload image: %s", error.AsCString());
12878f343b09SGreg Clayton                     result.SetStatus (eReturnStatusFailed);
12888f343b09SGreg Clayton                     break;
12898f343b09SGreg Clayton                 }
12908f343b09SGreg Clayton             }
12918f343b09SGreg Clayton         }
12928f343b09SGreg Clayton         return result.Succeeded();
12938f343b09SGreg Clayton     }
12948f343b09SGreg Clayton };
12958f343b09SGreg Clayton 
12968f343b09SGreg Clayton //-------------------------------------------------------------------------
129730fdc8d8SChris Lattner // CommandObjectProcessSignal
129830fdc8d8SChris Lattner //-------------------------------------------------------------------------
1299bb9caf73SJim Ingham #pragma mark CommandObjectProcessSignal
130030fdc8d8SChris Lattner 
13015a988416SJim Ingham class CommandObjectProcessSignal : public CommandObjectParsed
130230fdc8d8SChris Lattner {
130330fdc8d8SChris Lattner public:
13047428a18cSKate Stone     CommandObjectProcessSignal(CommandInterpreter &interpreter)
13057428a18cSKate Stone         : CommandObjectParsed(interpreter, "process signal", "Send a UNIX signal to the current target process.",
13067428a18cSKate Stone                               nullptr, eCommandRequiresProcess | eCommandTryTargetAPILock)
130730fdc8d8SChris Lattner     {
1308405fe67fSCaroline Tice         CommandArgumentEntry arg;
1309405fe67fSCaroline Tice         CommandArgumentData signal_arg;
1310405fe67fSCaroline Tice 
1311405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
1312c0dbdfb6SCaroline Tice         signal_arg.arg_type = eArgTypeUnixSignal;
1313405fe67fSCaroline Tice         signal_arg.arg_repetition = eArgRepeatPlain;
1314405fe67fSCaroline Tice 
1315405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
1316405fe67fSCaroline Tice         arg.push_back (signal_arg);
1317405fe67fSCaroline Tice 
1318405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
1319405fe67fSCaroline Tice         m_arguments.push_back (arg);
132030fdc8d8SChris Lattner     }
132130fdc8d8SChris Lattner 
132249bcfd80SEugene Zelenko     ~CommandObjectProcessSignal() override = default;
132330fdc8d8SChris Lattner 
13245a988416SJim Ingham protected:
132530fdc8d8SChris Lattner     bool
132613d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
132730fdc8d8SChris Lattner     {
1328f9fc609fSGreg Clayton         Process *process = m_exe_ctx.GetProcessPtr();
132930fdc8d8SChris Lattner 
133030fdc8d8SChris Lattner         if (command.GetArgumentCount() == 1)
133130fdc8d8SChris Lattner         {
1332237cd906SGreg Clayton             int signo = LLDB_INVALID_SIGNAL_NUMBER;
1333237cd906SGreg Clayton 
1334237cd906SGreg Clayton             const char *signal_name = command.GetArgumentAtIndex(0);
1335237cd906SGreg Clayton             if (::isxdigit (signal_name[0]))
13365275aaa0SVince Harron                 signo = StringConvert::ToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0);
1337237cd906SGreg Clayton             else
133898d0a4b3SChaoren Lin                 signo = process->GetUnixSignals()->GetSignalNumberFromName(signal_name);
1339237cd906SGreg Clayton 
1340237cd906SGreg Clayton             if (signo == LLDB_INVALID_SIGNAL_NUMBER)
134130fdc8d8SChris Lattner             {
134230fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("Invalid signal argument '%s'.\n", command.GetArgumentAtIndex(0));
134330fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
134430fdc8d8SChris Lattner             }
134530fdc8d8SChris Lattner             else
134630fdc8d8SChris Lattner             {
134730fdc8d8SChris Lattner                 Error error (process->Signal (signo));
134830fdc8d8SChris Lattner                 if (error.Success())
134930fdc8d8SChris Lattner                 {
135030fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusSuccessFinishResult);
135130fdc8d8SChris Lattner                 }
135230fdc8d8SChris Lattner                 else
135330fdc8d8SChris Lattner                 {
135430fdc8d8SChris Lattner                     result.AppendErrorWithFormat ("Failed to send signal %i: %s\n", signo, error.AsCString());
135530fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
135630fdc8d8SChris Lattner                 }
135730fdc8d8SChris Lattner             }
135830fdc8d8SChris Lattner         }
135930fdc8d8SChris Lattner         else
136030fdc8d8SChris Lattner         {
1361fd54b368SJason Molenda             result.AppendErrorWithFormat("'%s' takes exactly one signal number argument:\nUsage: %s\n", m_cmd_name.c_str(),
136230fdc8d8SChris Lattner                                         m_cmd_syntax.c_str());
136330fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
136430fdc8d8SChris Lattner         }
136530fdc8d8SChris Lattner         return result.Succeeded();
136630fdc8d8SChris Lattner     }
136730fdc8d8SChris Lattner };
136830fdc8d8SChris Lattner 
136930fdc8d8SChris Lattner //-------------------------------------------------------------------------
137030fdc8d8SChris Lattner // CommandObjectProcessInterrupt
137130fdc8d8SChris Lattner //-------------------------------------------------------------------------
1372bb9caf73SJim Ingham #pragma mark CommandObjectProcessInterrupt
137330fdc8d8SChris Lattner 
13745a988416SJim Ingham class CommandObjectProcessInterrupt : public CommandObjectParsed
137530fdc8d8SChris Lattner {
137630fdc8d8SChris Lattner public:
13777428a18cSKate Stone     CommandObjectProcessInterrupt(CommandInterpreter &interpreter)
13787428a18cSKate Stone         : CommandObjectParsed(interpreter, "process interrupt", "Interrupt the current target process.",
1379a7015092SGreg Clayton                               "process interrupt",
13807428a18cSKate Stone                               eCommandRequiresProcess | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched)
138130fdc8d8SChris Lattner     {
138230fdc8d8SChris Lattner     }
138330fdc8d8SChris Lattner 
138449bcfd80SEugene Zelenko     ~CommandObjectProcessInterrupt() override = default;
138530fdc8d8SChris Lattner 
13865a988416SJim Ingham protected:
138730fdc8d8SChris Lattner     bool
138813d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
138930fdc8d8SChris Lattner     {
1390f9fc609fSGreg Clayton         Process *process = m_exe_ctx.GetProcessPtr();
139149bcfd80SEugene Zelenko         if (process == nullptr)
139230fdc8d8SChris Lattner         {
139330fdc8d8SChris Lattner             result.AppendError ("no process to halt");
139430fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
139530fdc8d8SChris Lattner             return false;
139630fdc8d8SChris Lattner         }
139730fdc8d8SChris Lattner 
139830fdc8d8SChris Lattner         if (command.GetArgumentCount() == 0)
139930fdc8d8SChris Lattner         {
1400f9b57b9dSGreg Clayton             bool clear_thread_plans = true;
1401f9b57b9dSGreg Clayton             Error error(process->Halt (clear_thread_plans));
140230fdc8d8SChris Lattner             if (error.Success())
140330fdc8d8SChris Lattner             {
140430fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusSuccessFinishResult);
140530fdc8d8SChris Lattner             }
140630fdc8d8SChris Lattner             else
140730fdc8d8SChris Lattner             {
140830fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("Failed to halt process: %s\n", error.AsCString());
140930fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
141030fdc8d8SChris Lattner             }
141130fdc8d8SChris Lattner         }
141230fdc8d8SChris Lattner         else
141330fdc8d8SChris Lattner         {
1414fd54b368SJason Molenda             result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n",
141530fdc8d8SChris Lattner                                         m_cmd_name.c_str(),
141630fdc8d8SChris Lattner                                         m_cmd_syntax.c_str());
141730fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
141830fdc8d8SChris Lattner         }
141930fdc8d8SChris Lattner         return result.Succeeded();
142030fdc8d8SChris Lattner     }
142130fdc8d8SChris Lattner };
142230fdc8d8SChris Lattner 
142330fdc8d8SChris Lattner //-------------------------------------------------------------------------
142430fdc8d8SChris Lattner // CommandObjectProcessKill
142530fdc8d8SChris Lattner //-------------------------------------------------------------------------
1426bb9caf73SJim Ingham #pragma mark CommandObjectProcessKill
142730fdc8d8SChris Lattner 
14285a988416SJim Ingham class CommandObjectProcessKill : public CommandObjectParsed
142930fdc8d8SChris Lattner {
143030fdc8d8SChris Lattner public:
14317428a18cSKate Stone     CommandObjectProcessKill(CommandInterpreter &interpreter)
14327428a18cSKate Stone         : CommandObjectParsed(interpreter, "process kill", "Terminate the current target process.", "process kill",
14337428a18cSKate Stone                               eCommandRequiresProcess | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched)
143430fdc8d8SChris Lattner     {
143530fdc8d8SChris Lattner     }
143630fdc8d8SChris Lattner 
143749bcfd80SEugene Zelenko     ~CommandObjectProcessKill() override = default;
143830fdc8d8SChris Lattner 
14395a988416SJim Ingham protected:
144030fdc8d8SChris Lattner     bool
144113d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
144230fdc8d8SChris Lattner     {
1443f9fc609fSGreg Clayton         Process *process = m_exe_ctx.GetProcessPtr();
144449bcfd80SEugene Zelenko         if (process == nullptr)
144530fdc8d8SChris Lattner         {
144630fdc8d8SChris Lattner             result.AppendError ("no process to kill");
144730fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
144830fdc8d8SChris Lattner             return false;
144930fdc8d8SChris Lattner         }
145030fdc8d8SChris Lattner 
145130fdc8d8SChris Lattner         if (command.GetArgumentCount() == 0)
145230fdc8d8SChris Lattner         {
14538980e6bcSJason Molenda             Error error (process->Destroy(true));
145430fdc8d8SChris Lattner             if (error.Success())
145530fdc8d8SChris Lattner             {
145630fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusSuccessFinishResult);
145730fdc8d8SChris Lattner             }
145830fdc8d8SChris Lattner             else
145930fdc8d8SChris Lattner             {
146030fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString());
146130fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
146230fdc8d8SChris Lattner             }
146330fdc8d8SChris Lattner         }
146430fdc8d8SChris Lattner         else
146530fdc8d8SChris Lattner         {
1466fd54b368SJason Molenda             result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n",
146730fdc8d8SChris Lattner                                         m_cmd_name.c_str(),
146830fdc8d8SChris Lattner                                         m_cmd_syntax.c_str());
146930fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
147030fdc8d8SChris Lattner         }
147130fdc8d8SChris Lattner         return result.Succeeded();
147230fdc8d8SChris Lattner     }
147330fdc8d8SChris Lattner };
147430fdc8d8SChris Lattner 
147530fdc8d8SChris Lattner //-------------------------------------------------------------------------
1476a2715cf1SGreg Clayton // CommandObjectProcessSaveCore
1477a2715cf1SGreg Clayton //-------------------------------------------------------------------------
1478a2715cf1SGreg Clayton #pragma mark CommandObjectProcessSaveCore
1479a2715cf1SGreg Clayton 
1480a2715cf1SGreg Clayton class CommandObjectProcessSaveCore : public CommandObjectParsed
1481a2715cf1SGreg Clayton {
1482a2715cf1SGreg Clayton public:
1483a2715cf1SGreg Clayton     CommandObjectProcessSaveCore (CommandInterpreter &interpreter) :
1484a2715cf1SGreg Clayton     CommandObjectParsed (interpreter,
1485a2715cf1SGreg Clayton                          "process save-core",
1486a2715cf1SGreg Clayton                          "Save the current process as a core file using an appropriate file type.",
1487a2715cf1SGreg Clayton                          "process save-core FILE",
1488e87764f2SEnrico Granata                          eCommandRequiresProcess      |
1489e87764f2SEnrico Granata                          eCommandTryTargetAPILock     |
1490e87764f2SEnrico Granata                          eCommandProcessMustBeLaunched)
1491a2715cf1SGreg Clayton     {
1492a2715cf1SGreg Clayton     }
1493a2715cf1SGreg Clayton 
149449bcfd80SEugene Zelenko     ~CommandObjectProcessSaveCore() override = default;
1495a2715cf1SGreg Clayton 
1496a2715cf1SGreg Clayton protected:
1497a2715cf1SGreg Clayton     bool
1498a2715cf1SGreg Clayton     DoExecute (Args& command,
149913d21e9aSBruce Mitchener                CommandReturnObject &result) override
1500a2715cf1SGreg Clayton     {
1501a2715cf1SGreg Clayton         ProcessSP process_sp = m_exe_ctx.GetProcessSP();
1502a2715cf1SGreg Clayton         if (process_sp)
1503a2715cf1SGreg Clayton         {
1504a2715cf1SGreg Clayton             if (command.GetArgumentCount() == 1)
1505a2715cf1SGreg Clayton             {
1506a2715cf1SGreg Clayton                 FileSpec output_file(command.GetArgumentAtIndex(0), false);
1507a2715cf1SGreg Clayton                 Error error = PluginManager::SaveCore(process_sp, output_file);
1508a2715cf1SGreg Clayton                 if (error.Success())
1509a2715cf1SGreg Clayton                 {
1510a2715cf1SGreg Clayton                     result.SetStatus (eReturnStatusSuccessFinishResult);
1511a2715cf1SGreg Clayton                 }
1512a2715cf1SGreg Clayton                 else
1513a2715cf1SGreg Clayton                 {
1514a2715cf1SGreg Clayton                     result.AppendErrorWithFormat ("Failed to save core file for process: %s\n", error.AsCString());
1515a2715cf1SGreg Clayton                     result.SetStatus (eReturnStatusFailed);
1516a2715cf1SGreg Clayton                 }
1517a2715cf1SGreg Clayton             }
1518a2715cf1SGreg Clayton             else
1519a2715cf1SGreg Clayton             {
1520a2715cf1SGreg Clayton                 result.AppendErrorWithFormat ("'%s' takes one arguments:\nUsage: %s\n",
1521a2715cf1SGreg Clayton                                               m_cmd_name.c_str(),
1522a2715cf1SGreg Clayton                                               m_cmd_syntax.c_str());
1523a2715cf1SGreg Clayton                 result.SetStatus (eReturnStatusFailed);
1524a2715cf1SGreg Clayton             }
1525a2715cf1SGreg Clayton         }
1526a2715cf1SGreg Clayton         else
1527a2715cf1SGreg Clayton         {
1528a2715cf1SGreg Clayton             result.AppendError ("invalid process");
1529a2715cf1SGreg Clayton             result.SetStatus (eReturnStatusFailed);
1530a2715cf1SGreg Clayton             return false;
1531a2715cf1SGreg Clayton         }
1532a2715cf1SGreg Clayton 
1533a2715cf1SGreg Clayton         return result.Succeeded();
1534a2715cf1SGreg Clayton     }
1535a2715cf1SGreg Clayton };
1536a2715cf1SGreg Clayton 
1537a2715cf1SGreg Clayton //-------------------------------------------------------------------------
15384b9bea87SJim Ingham // CommandObjectProcessStatus
15394b9bea87SJim Ingham //-------------------------------------------------------------------------
1540bb9caf73SJim Ingham #pragma mark CommandObjectProcessStatus
1541bb9caf73SJim Ingham 
15425a988416SJim Ingham class CommandObjectProcessStatus : public CommandObjectParsed
15434b9bea87SJim Ingham {
15444b9bea87SJim Ingham public:
15457428a18cSKate Stone     CommandObjectProcessStatus(CommandInterpreter &interpreter)
15467428a18cSKate Stone         : CommandObjectParsed(interpreter, "process status",
15477428a18cSKate Stone                               "Show status and stop location for the current target process.", "process status",
1548e87764f2SEnrico Granata                               eCommandRequiresProcess | eCommandTryTargetAPILock)
15494b9bea87SJim Ingham     {
15504b9bea87SJim Ingham     }
15514b9bea87SJim Ingham 
155249bcfd80SEugene Zelenko     ~CommandObjectProcessStatus() override = default;
15534b9bea87SJim Ingham 
15544b9bea87SJim Ingham     bool
155513d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
15564b9bea87SJim Ingham     {
15577260f620SGreg Clayton         Stream &strm = result.GetOutputStream();
15584b9bea87SJim Ingham         result.SetStatus (eReturnStatusSuccessFinishNoResult);
1559e87764f2SEnrico Granata         // No need to check "process" for validity as eCommandRequiresProcess ensures it is valid
1560f9fc609fSGreg Clayton         Process *process = m_exe_ctx.GetProcessPtr();
15617260f620SGreg Clayton         const bool only_threads_with_stop_reason = true;
15627260f620SGreg Clayton         const uint32_t start_frame = 0;
15637260f620SGreg Clayton         const uint32_t num_frames = 1;
15647260f620SGreg Clayton         const uint32_t num_frames_with_source = 1;
1565c14ee32dSGreg Clayton         process->GetStatus(strm);
1566c14ee32dSGreg Clayton         process->GetThreadStatus (strm,
15677260f620SGreg Clayton                                   only_threads_with_stop_reason,
15687260f620SGreg Clayton                                   start_frame,
15697260f620SGreg Clayton                                   num_frames,
15707260f620SGreg Clayton                                   num_frames_with_source);
15714b9bea87SJim Ingham         return result.Succeeded();
15724b9bea87SJim Ingham     }
15734b9bea87SJim Ingham };
15744b9bea87SJim Ingham 
15754b9bea87SJim Ingham //-------------------------------------------------------------------------
157635731357SCaroline Tice // CommandObjectProcessHandle
157735731357SCaroline Tice //-------------------------------------------------------------------------
1578bb9caf73SJim Ingham #pragma mark CommandObjectProcessHandle
157935731357SCaroline Tice 
15805a988416SJim Ingham class CommandObjectProcessHandle : public CommandObjectParsed
158135731357SCaroline Tice {
158235731357SCaroline Tice public:
158335731357SCaroline Tice     class CommandOptions : public Options
158435731357SCaroline Tice     {
158535731357SCaroline Tice     public:
1586*e1cfbc79STodd Fiala         CommandOptions() :
1587*e1cfbc79STodd Fiala             Options()
158835731357SCaroline Tice         {
1589*e1cfbc79STodd Fiala             OptionParsingStarting(nullptr);
159035731357SCaroline Tice         }
159135731357SCaroline Tice 
159249bcfd80SEugene Zelenko         ~CommandOptions() override = default;
159335731357SCaroline Tice 
159435731357SCaroline Tice         Error
1595*e1cfbc79STodd Fiala         SetOptionValue(uint32_t option_idx, const char *option_arg,
1596*e1cfbc79STodd Fiala                        ExecutionContext *execution_context) override
159735731357SCaroline Tice         {
159835731357SCaroline Tice             Error error;
15993bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
160035731357SCaroline Tice 
160135731357SCaroline Tice             switch (short_option)
160235731357SCaroline Tice             {
160335731357SCaroline Tice                 case 's':
160435731357SCaroline Tice                     stop = option_arg;
160535731357SCaroline Tice                     break;
160635731357SCaroline Tice                 case 'n':
160735731357SCaroline Tice                     notify = option_arg;
160835731357SCaroline Tice                     break;
160935731357SCaroline Tice                 case 'p':
161035731357SCaroline Tice                     pass = option_arg;
161135731357SCaroline Tice                     break;
161235731357SCaroline Tice                 default:
161386edbf41SGreg Clayton                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
161435731357SCaroline Tice                     break;
161535731357SCaroline Tice             }
161635731357SCaroline Tice             return error;
161735731357SCaroline Tice         }
161835731357SCaroline Tice 
161935731357SCaroline Tice         void
1620*e1cfbc79STodd Fiala         OptionParsingStarting(ExecutionContext *execution_context) override
162135731357SCaroline Tice         {
162235731357SCaroline Tice             stop.clear();
162335731357SCaroline Tice             notify.clear();
162435731357SCaroline Tice             pass.clear();
162535731357SCaroline Tice         }
162635731357SCaroline Tice 
1627e0d378b3SGreg Clayton         const OptionDefinition*
162813d21e9aSBruce Mitchener         GetDefinitions () override
162935731357SCaroline Tice         {
163035731357SCaroline Tice             return g_option_table;
163135731357SCaroline Tice         }
163235731357SCaroline Tice 
163335731357SCaroline Tice         // Options table: Required for subclasses of Options.
163435731357SCaroline Tice 
1635e0d378b3SGreg Clayton         static OptionDefinition g_option_table[];
163635731357SCaroline Tice 
163735731357SCaroline Tice         // Instance variables to hold the values for command options.
163835731357SCaroline Tice 
163935731357SCaroline Tice         std::string stop;
164035731357SCaroline Tice         std::string notify;
164135731357SCaroline Tice         std::string pass;
164235731357SCaroline Tice     };
164335731357SCaroline Tice 
16447428a18cSKate Stone     CommandObjectProcessHandle(CommandInterpreter &interpreter)
16457428a18cSKate Stone         : CommandObjectParsed(
16467428a18cSKate Stone               interpreter, "process handle",
16477428a18cSKate Stone               "Manage LLDB handling of OS signals for the current target process.  Defaults to showing current policy.",
164849bcfd80SEugene Zelenko               nullptr),
1649*e1cfbc79STodd Fiala           m_options()
165035731357SCaroline Tice     {
1651ea671fbdSKate Stone         SetHelpLong ("\nIf no signals are specified, update them all.  If no update "
1652ea671fbdSKate Stone                      "option is specified, list the current values.");
165335731357SCaroline Tice         CommandArgumentEntry arg;
1654c0dbdfb6SCaroline Tice         CommandArgumentData signal_arg;
165535731357SCaroline Tice 
1656c0dbdfb6SCaroline Tice         signal_arg.arg_type = eArgTypeUnixSignal;
1657c0dbdfb6SCaroline Tice         signal_arg.arg_repetition = eArgRepeatStar;
165835731357SCaroline Tice 
1659c0dbdfb6SCaroline Tice         arg.push_back (signal_arg);
166035731357SCaroline Tice 
166135731357SCaroline Tice         m_arguments.push_back (arg);
166235731357SCaroline Tice     }
166335731357SCaroline Tice 
166449bcfd80SEugene Zelenko     ~CommandObjectProcessHandle() override = default;
166535731357SCaroline Tice 
166635731357SCaroline Tice     Options *
166713d21e9aSBruce Mitchener     GetOptions () override
166835731357SCaroline Tice     {
166935731357SCaroline Tice         return &m_options;
167035731357SCaroline Tice     }
167135731357SCaroline Tice 
167235731357SCaroline Tice     bool
167310ad7993SCaroline Tice     VerifyCommandOptionValue (const std::string &option, int &real_value)
167435731357SCaroline Tice     {
167535731357SCaroline Tice         bool okay = true;
167610ad7993SCaroline Tice         bool success = false;
167710ad7993SCaroline Tice         bool tmp_value = Args::StringToBoolean (option.c_str(), false, &success);
167810ad7993SCaroline Tice 
167910ad7993SCaroline Tice         if (success && tmp_value)
168010ad7993SCaroline Tice             real_value = 1;
168110ad7993SCaroline Tice         else if (success && !tmp_value)
168210ad7993SCaroline Tice             real_value = 0;
168335731357SCaroline Tice         else
168435731357SCaroline Tice         {
168535731357SCaroline Tice             // If the value isn't 'true' or 'false', it had better be 0 or 1.
16865275aaa0SVince Harron             real_value = StringConvert::ToUInt32 (option.c_str(), 3);
168710ad7993SCaroline Tice             if (real_value != 0 && real_value != 1)
168835731357SCaroline Tice                 okay = false;
168935731357SCaroline Tice         }
169035731357SCaroline Tice 
169135731357SCaroline Tice         return okay;
169235731357SCaroline Tice     }
169335731357SCaroline Tice 
169410ad7993SCaroline Tice     void
169510ad7993SCaroline Tice     PrintSignalHeader (Stream &str)
169610ad7993SCaroline Tice     {
169710ad7993SCaroline Tice         str.Printf ("NAME         PASS   STOP   NOTIFY\n");
1698b84141a6SPavel Labath         str.Printf ("===========  =====  =====  ======\n");
169910ad7993SCaroline Tice     }
170010ad7993SCaroline Tice 
170110ad7993SCaroline Tice     void
170298d0a4b3SChaoren Lin     PrintSignal(Stream &str, int32_t signo, const char *sig_name, const UnixSignalsSP &signals_sp)
170310ad7993SCaroline Tice     {
170410ad7993SCaroline Tice         bool stop;
170510ad7993SCaroline Tice         bool suppress;
170610ad7993SCaroline Tice         bool notify;
170710ad7993SCaroline Tice 
1708b84141a6SPavel Labath         str.Printf ("%-11s  ", sig_name);
170998d0a4b3SChaoren Lin         if (signals_sp->GetSignalInfo(signo, suppress, stop, notify))
171010ad7993SCaroline Tice         {
171110ad7993SCaroline Tice             bool pass = !suppress;
171210ad7993SCaroline Tice             str.Printf ("%s  %s  %s",
171310ad7993SCaroline Tice                         (pass ? "true " : "false"),
171410ad7993SCaroline Tice                         (stop ? "true " : "false"),
171510ad7993SCaroline Tice                         (notify ? "true " : "false"));
171610ad7993SCaroline Tice         }
171710ad7993SCaroline Tice         str.Printf ("\n");
171810ad7993SCaroline Tice     }
171910ad7993SCaroline Tice 
172010ad7993SCaroline Tice     void
172198d0a4b3SChaoren Lin     PrintSignalInformation(Stream &str, Args &signal_args, int num_valid_signals, const UnixSignalsSP &signals_sp)
172210ad7993SCaroline Tice     {
172310ad7993SCaroline Tice         PrintSignalHeader (str);
172410ad7993SCaroline Tice 
172510ad7993SCaroline Tice         if (num_valid_signals > 0)
172610ad7993SCaroline Tice         {
172710ad7993SCaroline Tice             size_t num_args = signal_args.GetArgumentCount();
172810ad7993SCaroline Tice             for (size_t i = 0; i < num_args; ++i)
172910ad7993SCaroline Tice             {
173098d0a4b3SChaoren Lin                 int32_t signo = signals_sp->GetSignalNumberFromName(signal_args.GetArgumentAtIndex(i));
173110ad7993SCaroline Tice                 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
173298d0a4b3SChaoren Lin                     PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals_sp);
173310ad7993SCaroline Tice             }
173410ad7993SCaroline Tice         }
173510ad7993SCaroline Tice         else // Print info for ALL signals
173610ad7993SCaroline Tice         {
173798d0a4b3SChaoren Lin             int32_t signo = signals_sp->GetFirstSignalNumber();
173810ad7993SCaroline Tice             while (signo != LLDB_INVALID_SIGNAL_NUMBER)
173910ad7993SCaroline Tice             {
174098d0a4b3SChaoren Lin                 PrintSignal(str, signo, signals_sp->GetSignalAsCString(signo), signals_sp);
174198d0a4b3SChaoren Lin                 signo = signals_sp->GetNextSignalNumber(signo);
174210ad7993SCaroline Tice             }
174310ad7993SCaroline Tice         }
174410ad7993SCaroline Tice     }
174510ad7993SCaroline Tice 
17465a988416SJim Ingham protected:
174735731357SCaroline Tice     bool
174813d21e9aSBruce Mitchener     DoExecute (Args &signal_args, CommandReturnObject &result) override
174935731357SCaroline Tice     {
175035731357SCaroline Tice         TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
175135731357SCaroline Tice 
175235731357SCaroline Tice         if (!target_sp)
175335731357SCaroline Tice         {
175435731357SCaroline Tice             result.AppendError ("No current target;"
175535731357SCaroline Tice                                 " cannot handle signals until you have a valid target and process.\n");
175635731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
175735731357SCaroline Tice             return false;
175835731357SCaroline Tice         }
175935731357SCaroline Tice 
176035731357SCaroline Tice         ProcessSP process_sp = target_sp->GetProcessSP();
176135731357SCaroline Tice 
176235731357SCaroline Tice         if (!process_sp)
176335731357SCaroline Tice         {
176435731357SCaroline Tice             result.AppendError ("No current process; cannot handle signals until you have a valid process.\n");
176535731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
176635731357SCaroline Tice             return false;
176735731357SCaroline Tice         }
176835731357SCaroline Tice 
176935731357SCaroline Tice         int stop_action = -1;   // -1 means leave the current setting alone
177035731357SCaroline Tice         int pass_action = -1;   // -1 means leave the current setting alone
177135731357SCaroline Tice         int notify_action = -1; // -1 means leave the current setting alone
177235731357SCaroline Tice 
177335731357SCaroline Tice         if (! m_options.stop.empty()
177410ad7993SCaroline Tice             && ! VerifyCommandOptionValue (m_options.stop, stop_action))
177535731357SCaroline Tice         {
177635731357SCaroline Tice             result.AppendError ("Invalid argument for command option --stop; must be true or false.\n");
177735731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
177835731357SCaroline Tice             return false;
177935731357SCaroline Tice         }
178035731357SCaroline Tice 
178135731357SCaroline Tice         if (! m_options.notify.empty()
178210ad7993SCaroline Tice             && ! VerifyCommandOptionValue (m_options.notify, notify_action))
178335731357SCaroline Tice         {
178435731357SCaroline Tice             result.AppendError ("Invalid argument for command option --notify; must be true or false.\n");
178535731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
178635731357SCaroline Tice             return false;
178735731357SCaroline Tice         }
178835731357SCaroline Tice 
178935731357SCaroline Tice         if (! m_options.pass.empty()
179010ad7993SCaroline Tice             && ! VerifyCommandOptionValue (m_options.pass, pass_action))
179135731357SCaroline Tice         {
179235731357SCaroline Tice             result.AppendError ("Invalid argument for command option --pass; must be true or false.\n");
179335731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
179435731357SCaroline Tice             return false;
179535731357SCaroline Tice         }
179635731357SCaroline Tice 
179735731357SCaroline Tice         size_t num_args = signal_args.GetArgumentCount();
179898d0a4b3SChaoren Lin         UnixSignalsSP signals_sp = process_sp->GetUnixSignals();
179935731357SCaroline Tice         int num_signals_set = 0;
180035731357SCaroline Tice 
180110ad7993SCaroline Tice         if (num_args > 0)
180210ad7993SCaroline Tice         {
180335731357SCaroline Tice             for (size_t i = 0; i < num_args; ++i)
180435731357SCaroline Tice             {
180598d0a4b3SChaoren Lin                 int32_t signo = signals_sp->GetSignalNumberFromName(signal_args.GetArgumentAtIndex(i));
180635731357SCaroline Tice                 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
180735731357SCaroline Tice                 {
180810ad7993SCaroline Tice                     // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees
180935731357SCaroline Tice                     // the value is either 0 or 1.
181035731357SCaroline Tice                     if (stop_action != -1)
181198d0a4b3SChaoren Lin                         signals_sp->SetShouldStop(signo, stop_action);
181235731357SCaroline Tice                     if (pass_action != -1)
181335731357SCaroline Tice                     {
181498d0a4b3SChaoren Lin                         bool suppress = !pass_action;
181598d0a4b3SChaoren Lin                         signals_sp->SetShouldSuppress(signo, suppress);
181635731357SCaroline Tice                     }
181735731357SCaroline Tice                     if (notify_action != -1)
181898d0a4b3SChaoren Lin                         signals_sp->SetShouldNotify(signo, notify_action);
181935731357SCaroline Tice                     ++num_signals_set;
182035731357SCaroline Tice                 }
182135731357SCaroline Tice                 else
182235731357SCaroline Tice                 {
182335731357SCaroline Tice                     result.AppendErrorWithFormat ("Invalid signal name '%s'\n", signal_args.GetArgumentAtIndex (i));
182435731357SCaroline Tice                 }
182535731357SCaroline Tice             }
182610ad7993SCaroline Tice         }
182710ad7993SCaroline Tice         else
182810ad7993SCaroline Tice         {
182910ad7993SCaroline Tice             // No signal specified, if any command options were specified, update ALL signals.
183010ad7993SCaroline Tice             if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1))
183110ad7993SCaroline Tice             {
183210ad7993SCaroline Tice                 if (m_interpreter.Confirm ("Do you really want to update all the signals?", false))
183310ad7993SCaroline Tice                 {
183498d0a4b3SChaoren Lin                     int32_t signo = signals_sp->GetFirstSignalNumber();
183510ad7993SCaroline Tice                     while (signo != LLDB_INVALID_SIGNAL_NUMBER)
183610ad7993SCaroline Tice                     {
183710ad7993SCaroline Tice                         if (notify_action != -1)
183898d0a4b3SChaoren Lin                             signals_sp->SetShouldNotify(signo, notify_action);
183910ad7993SCaroline Tice                         if (stop_action != -1)
184098d0a4b3SChaoren Lin                             signals_sp->SetShouldStop(signo, stop_action);
184110ad7993SCaroline Tice                         if (pass_action != -1)
184210ad7993SCaroline Tice                         {
184398d0a4b3SChaoren Lin                             bool suppress = !pass_action;
184498d0a4b3SChaoren Lin                             signals_sp->SetShouldSuppress(signo, suppress);
184510ad7993SCaroline Tice                         }
184698d0a4b3SChaoren Lin                         signo = signals_sp->GetNextSignalNumber(signo);
184710ad7993SCaroline Tice                     }
184810ad7993SCaroline Tice                 }
184910ad7993SCaroline Tice             }
185010ad7993SCaroline Tice         }
185110ad7993SCaroline Tice 
185298d0a4b3SChaoren Lin         PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals_sp);
185335731357SCaroline Tice 
185435731357SCaroline Tice         if (num_signals_set > 0)
185535731357SCaroline Tice             result.SetStatus (eReturnStatusSuccessFinishNoResult);
185635731357SCaroline Tice         else
185735731357SCaroline Tice             result.SetStatus (eReturnStatusFailed);
185835731357SCaroline Tice 
185935731357SCaroline Tice         return result.Succeeded();
186035731357SCaroline Tice     }
186135731357SCaroline Tice 
186235731357SCaroline Tice     CommandOptions m_options;
186335731357SCaroline Tice };
186435731357SCaroline Tice 
1865e0d378b3SGreg Clayton OptionDefinition
186635731357SCaroline Tice CommandObjectProcessHandle::CommandOptions::g_option_table[] =
186735731357SCaroline Tice {
186849bcfd80SEugene 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." },
186949bcfd80SEugene 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." },
187049bcfd80SEugene 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." },
187149bcfd80SEugene Zelenko { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
187235731357SCaroline Tice };
187335731357SCaroline Tice 
187435731357SCaroline Tice //-------------------------------------------------------------------------
187530fdc8d8SChris Lattner // CommandObjectMultiwordProcess
187630fdc8d8SChris Lattner //-------------------------------------------------------------------------
187730fdc8d8SChris Lattner 
18787428a18cSKate Stone CommandObjectMultiwordProcess::CommandObjectMultiwordProcess(CommandInterpreter &interpreter)
18797428a18cSKate Stone     : CommandObjectMultiword(interpreter, "process", "Commands for interacting with processes on the current platform.",
188030fdc8d8SChris Lattner                              "process <subcommand> [<subcommand-options>]")
188130fdc8d8SChris Lattner {
1882a7015092SGreg Clayton     LoadSubCommand ("attach",      CommandObjectSP (new CommandObjectProcessAttach    (interpreter)));
1883a7015092SGreg Clayton     LoadSubCommand ("launch",      CommandObjectSP (new CommandObjectProcessLaunch    (interpreter)));
1884a7015092SGreg Clayton     LoadSubCommand ("continue",    CommandObjectSP (new CommandObjectProcessContinue  (interpreter)));
1885b766a73dSGreg Clayton     LoadSubCommand ("connect",     CommandObjectSP (new CommandObjectProcessConnect   (interpreter)));
1886a7015092SGreg Clayton     LoadSubCommand ("detach",      CommandObjectSP (new CommandObjectProcessDetach    (interpreter)));
18878f343b09SGreg Clayton     LoadSubCommand ("load",        CommandObjectSP (new CommandObjectProcessLoad      (interpreter)));
18888f343b09SGreg Clayton     LoadSubCommand ("unload",      CommandObjectSP (new CommandObjectProcessUnload    (interpreter)));
1889a7015092SGreg Clayton     LoadSubCommand ("signal",      CommandObjectSP (new CommandObjectProcessSignal    (interpreter)));
189035731357SCaroline Tice     LoadSubCommand ("handle",      CommandObjectSP (new CommandObjectProcessHandle    (interpreter)));
1891a7015092SGreg Clayton     LoadSubCommand ("status",      CommandObjectSP (new CommandObjectProcessStatus    (interpreter)));
1892a7015092SGreg Clayton     LoadSubCommand ("interrupt",   CommandObjectSP (new CommandObjectProcessInterrupt (interpreter)));
1893a7015092SGreg Clayton     LoadSubCommand ("kill",        CommandObjectSP (new CommandObjectProcessKill      (interpreter)));
1894998255bfSGreg Clayton     LoadSubCommand ("plugin",      CommandObjectSP (new CommandObjectProcessPlugin    (interpreter)));
1895a2715cf1SGreg Clayton     LoadSubCommand ("save-core",   CommandObjectSP (new CommandObjectProcessSaveCore  (interpreter)));
189630fdc8d8SChris Lattner }
189730fdc8d8SChris Lattner 
189849bcfd80SEugene Zelenko CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess() = default;
1899