]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Commands/CommandObjectProcess.cpp
MFV r321673:
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Commands / CommandObjectProcess.cpp
1 //===-- CommandObjectProcess.cpp --------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 // C Includes
11 // C++ Includes
12 // Other libraries and framework includes
13 // Project includes
14 #include "CommandObjectProcess.h"
15 #include "lldb/Breakpoint/Breakpoint.h"
16 #include "lldb/Breakpoint/BreakpointLocation.h"
17 #include "lldb/Breakpoint/BreakpointSite.h"
18 #include "lldb/Core/Module.h"
19 #include "lldb/Core/PluginManager.h"
20 #include "lldb/Core/State.h"
21 #include "lldb/Host/Host.h"
22 #include "lldb/Host/OptionParser.h"
23 #include "lldb/Host/StringConvert.h"
24 #include "lldb/Interpreter/Args.h"
25 #include "lldb/Interpreter/CommandInterpreter.h"
26 #include "lldb/Interpreter/CommandReturnObject.h"
27 #include "lldb/Interpreter/Options.h"
28 #include "lldb/Target/Platform.h"
29 #include "lldb/Target/Process.h"
30 #include "lldb/Target/StopInfo.h"
31 #include "lldb/Target/Target.h"
32 #include "lldb/Target/Thread.h"
33 #include "lldb/Target/UnixSignals.h"
34
35 using namespace lldb;
36 using namespace lldb_private;
37
38 class CommandObjectProcessLaunchOrAttach : public CommandObjectParsed {
39 public:
40   CommandObjectProcessLaunchOrAttach(CommandInterpreter &interpreter,
41                                      const char *name, const char *help,
42                                      const char *syntax, uint32_t flags,
43                                      const char *new_process_action)
44       : CommandObjectParsed(interpreter, name, help, syntax, flags),
45         m_new_process_action(new_process_action) {}
46
47   ~CommandObjectProcessLaunchOrAttach() override = default;
48
49 protected:
50   bool StopProcessIfNecessary(Process *process, StateType &state,
51                               CommandReturnObject &result) {
52     state = eStateInvalid;
53     if (process) {
54       state = process->GetState();
55
56       if (process->IsAlive() && state != eStateConnected) {
57         char message[1024];
58         if (process->GetState() == eStateAttaching)
59           ::snprintf(message, sizeof(message),
60                      "There is a pending attach, abort it and %s?",
61                      m_new_process_action.c_str());
62         else if (process->GetShouldDetach())
63           ::snprintf(message, sizeof(message),
64                      "There is a running process, detach from it and %s?",
65                      m_new_process_action.c_str());
66         else
67           ::snprintf(message, sizeof(message),
68                      "There is a running process, kill it and %s?",
69                      m_new_process_action.c_str());
70
71         if (!m_interpreter.Confirm(message, true)) {
72           result.SetStatus(eReturnStatusFailed);
73           return false;
74         } else {
75           if (process->GetShouldDetach()) {
76             bool keep_stopped = false;
77             Status detach_error(process->Detach(keep_stopped));
78             if (detach_error.Success()) {
79               result.SetStatus(eReturnStatusSuccessFinishResult);
80               process = nullptr;
81             } else {
82               result.AppendErrorWithFormat(
83                   "Failed to detach from process: %s\n",
84                   detach_error.AsCString());
85               result.SetStatus(eReturnStatusFailed);
86             }
87           } else {
88             Status destroy_error(process->Destroy(false));
89             if (destroy_error.Success()) {
90               result.SetStatus(eReturnStatusSuccessFinishResult);
91               process = nullptr;
92             } else {
93               result.AppendErrorWithFormat("Failed to kill process: %s\n",
94                                            destroy_error.AsCString());
95               result.SetStatus(eReturnStatusFailed);
96             }
97           }
98         }
99       }
100     }
101     return result.Succeeded();
102   }
103
104   std::string m_new_process_action;
105 };
106
107 //-------------------------------------------------------------------------
108 // CommandObjectProcessLaunch
109 //-------------------------------------------------------------------------
110 #pragma mark CommandObjectProcessLaunch
111 class CommandObjectProcessLaunch : public CommandObjectProcessLaunchOrAttach {
112 public:
113   CommandObjectProcessLaunch(CommandInterpreter &interpreter)
114       : CommandObjectProcessLaunchOrAttach(
115             interpreter, "process launch",
116             "Launch the executable in the debugger.", nullptr,
117             eCommandRequiresTarget, "restart"),
118         m_options() {
119     CommandArgumentEntry arg;
120     CommandArgumentData run_args_arg;
121
122     // Define the first (and only) variant of this arg.
123     run_args_arg.arg_type = eArgTypeRunArgs;
124     run_args_arg.arg_repetition = eArgRepeatOptional;
125
126     // There is only one variant this argument could be; put it into the
127     // argument entry.
128     arg.push_back(run_args_arg);
129
130     // Push the data for the first argument into the m_arguments vector.
131     m_arguments.push_back(arg);
132   }
133
134   ~CommandObjectProcessLaunch() override = default;
135
136   int HandleArgumentCompletion(Args &input, int &cursor_index,
137                                int &cursor_char_position,
138                                OptionElementVector &opt_element_vector,
139                                int match_start_point, int max_return_elements,
140                                bool &word_complete,
141                                StringList &matches) override {
142     std::string completion_str(input.GetArgumentAtIndex(cursor_index));
143     completion_str.erase(cursor_char_position);
144
145     CommandCompletions::InvokeCommonCompletionCallbacks(
146         GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
147         completion_str.c_str(), match_start_point, max_return_elements, nullptr,
148         word_complete, matches);
149     return matches.GetSize();
150   }
151
152   Options *GetOptions() override { return &m_options; }
153
154   const char *GetRepeatCommand(Args &current_command_args,
155                                uint32_t index) override {
156     // No repeat for "process launch"...
157     return "";
158   }
159
160 protected:
161   bool DoExecute(Args &launch_args, CommandReturnObject &result) override {
162     Debugger &debugger = m_interpreter.GetDebugger();
163     Target *target = debugger.GetSelectedTarget().get();
164     // If our listener is nullptr, users aren't allows to launch
165     ModuleSP exe_module_sp = target->GetExecutableModule();
166
167     if (exe_module_sp == nullptr) {
168       result.AppendError("no file in target, create a debug target using the "
169                          "'target create' command");
170       result.SetStatus(eReturnStatusFailed);
171       return false;
172     }
173
174     StateType state = eStateInvalid;
175
176     if (!StopProcessIfNecessary(m_exe_ctx.GetProcessPtr(), state, result))
177       return false;
178
179     llvm::StringRef target_settings_argv0 = target->GetArg0();
180
181     // Determine whether we will disable ASLR or leave it in the default state
182     // (i.e. enabled if the platform supports it).
183     // First check if the process launch options explicitly turn on/off
184     // disabling ASLR.  If so, use that setting;
185     // otherwise, use the 'settings target.disable-aslr' setting.
186     bool disable_aslr = false;
187     if (m_options.disable_aslr != eLazyBoolCalculate) {
188       // The user specified an explicit setting on the process launch line.  Use
189       // it.
190       disable_aslr = (m_options.disable_aslr == eLazyBoolYes);
191     } else {
192       // The user did not explicitly specify whether to disable ASLR.  Fall back
193       // to the target.disable-aslr setting.
194       disable_aslr = target->GetDisableASLR();
195     }
196
197     if (disable_aslr)
198       m_options.launch_info.GetFlags().Set(eLaunchFlagDisableASLR);
199     else
200       m_options.launch_info.GetFlags().Clear(eLaunchFlagDisableASLR);
201
202     if (target->GetDetachOnError())
203       m_options.launch_info.GetFlags().Set(eLaunchFlagDetachOnError);
204
205     if (target->GetDisableSTDIO())
206       m_options.launch_info.GetFlags().Set(eLaunchFlagDisableSTDIO);
207
208     Args environment;
209     target->GetEnvironmentAsArgs(environment);
210     if (environment.GetArgumentCount() > 0)
211       m_options.launch_info.GetEnvironmentEntries().AppendArguments(
212           environment);
213
214     if (!target_settings_argv0.empty()) {
215       m_options.launch_info.GetArguments().AppendArgument(
216           target_settings_argv0);
217       m_options.launch_info.SetExecutableFile(
218           exe_module_sp->GetPlatformFileSpec(), false);
219     } else {
220       m_options.launch_info.SetExecutableFile(
221           exe_module_sp->GetPlatformFileSpec(), true);
222     }
223
224     if (launch_args.GetArgumentCount() == 0) {
225       m_options.launch_info.GetArguments().AppendArguments(
226           target->GetProcessLaunchInfo().GetArguments());
227     } else {
228       m_options.launch_info.GetArguments().AppendArguments(launch_args);
229       // Save the arguments for subsequent runs in the current target.
230       target->SetRunArguments(launch_args);
231     }
232
233     StreamString stream;
234     Status error = target->Launch(m_options.launch_info, &stream);
235
236     if (error.Success()) {
237       ProcessSP process_sp(target->GetProcessSP());
238       if (process_sp) {
239         // There is a race condition where this thread will return up the call
240         // stack to the main command
241         // handler and show an (lldb) prompt before HandlePrivateEvent (from
242         // PrivateStateThread) has
243         // a chance to call PushProcessIOHandler().
244         process_sp->SyncIOHandler(0, 2000);
245
246         llvm::StringRef data = stream.GetString();
247         if (!data.empty())
248           result.AppendMessage(data);
249         const char *archname =
250             exe_module_sp->GetArchitecture().GetArchitectureName();
251         result.AppendMessageWithFormat(
252             "Process %" PRIu64 " launched: '%s' (%s)\n", process_sp->GetID(),
253             exe_module_sp->GetFileSpec().GetPath().c_str(), archname);
254         result.SetStatus(eReturnStatusSuccessFinishResult);
255         result.SetDidChangeProcessState(true);
256       } else {
257         result.AppendError(
258             "no error returned from Target::Launch, and target has no process");
259         result.SetStatus(eReturnStatusFailed);
260       }
261     } else {
262       result.AppendError(error.AsCString());
263       result.SetStatus(eReturnStatusFailed);
264     }
265     return result.Succeeded();
266   }
267
268 protected:
269   ProcessLaunchCommandOptions m_options;
270 };
271
272 //#define SET1 LLDB_OPT_SET_1
273 //#define SET2 LLDB_OPT_SET_2
274 //#define SET3 LLDB_OPT_SET_3
275 //
276 // OptionDefinition
277 // CommandObjectProcessLaunch::CommandOptions::g_option_table[] =
278 //{
279 //  // clang-format off
280 //  {SET1 | SET2 | SET3, false, "stop-at-entry", 's', OptionParser::eNoArgument,
281 //  nullptr, 0, eArgTypeNone,          "Stop at the entry point of the program
282 //  when launching a process."},
283 //  {SET1,               false, "stdin",         'i',
284 //  OptionParser::eRequiredArgument, nullptr, 0, eArgTypeDirectoryName,
285 //  "Redirect stdin for the process to <path>."},
286 //  {SET1,               false, "stdout",        'o',
287 //  OptionParser::eRequiredArgument, nullptr, 0, eArgTypeDirectoryName,
288 //  "Redirect stdout for the process to <path>."},
289 //  {SET1,               false, "stderr",        'e',
290 //  OptionParser::eRequiredArgument, nullptr, 0, eArgTypeDirectoryName,
291 //  "Redirect stderr for the process to <path>."},
292 //  {SET1 | SET2 | SET3, false, "plugin",        'p',
293 //  OptionParser::eRequiredArgument, nullptr, 0, eArgTypePlugin,        "Name of
294 //  the process plugin you want to use."},
295 //  {       SET2,        false, "tty",           't',
296 //  OptionParser::eOptionalArgument, nullptr, 0, eArgTypeDirectoryName, "Start
297 //  the process in a terminal. If <path> is specified, look for a terminal whose
298 //  name contains <path>, else start the process in a new terminal."},
299 //  {              SET3, false, "no-stdio",      'n', OptionParser::eNoArgument,
300 //  nullptr, 0, eArgTypeNone,          "Do not set up for terminal I/O to go to
301 //  running process."},
302 //  {SET1 | SET2 | SET3, false, "working-dir",   'w',
303 //  OptionParser::eRequiredArgument, nullptr, 0, eArgTypeDirectoryName, "Set the
304 //  current working directory to <path> when running the inferior."},
305 //  {0, false, nullptr, 0, 0, nullptr, 0, eArgTypeNone, nullptr}
306 //  // clang-format on
307 //};
308 //
309 //#undef SET1
310 //#undef SET2
311 //#undef SET3
312
313 //-------------------------------------------------------------------------
314 // CommandObjectProcessAttach
315 //-------------------------------------------------------------------------
316
317 static OptionDefinition g_process_attach_options[] = {
318     // clang-format off
319   { LLDB_OPT_SET_ALL, false, "continue",         'c', OptionParser::eNoArgument,       nullptr, nullptr, 0, eArgTypeNone,         "Immediately continue the process once attached." },
320   { LLDB_OPT_SET_ALL, false, "plugin",           'P', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePlugin,       "Name of the process plugin you want to use." },
321   { LLDB_OPT_SET_1,   false, "pid",              'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePid,          "The process ID of an existing process to attach to." },
322   { LLDB_OPT_SET_2,   false, "name",             'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeProcessName,  "The name of the process to attach to." },
323   { LLDB_OPT_SET_2,   false, "include-existing", 'i', OptionParser::eNoArgument,       nullptr, nullptr, 0, eArgTypeNone,         "Include existing processes when doing attach -w." },
324   { LLDB_OPT_SET_2,   false, "waitfor",          'w', OptionParser::eNoArgument,       nullptr, nullptr, 0, eArgTypeNone,         "Wait for the process with <process-name> to launch." },
325     // clang-format on
326 };
327
328 #pragma mark CommandObjectProcessAttach
329 class CommandObjectProcessAttach : public CommandObjectProcessLaunchOrAttach {
330 public:
331   class CommandOptions : public Options {
332   public:
333     CommandOptions() : Options() {
334       // Keep default values of all options in one place: OptionParsingStarting
335       // ()
336       OptionParsingStarting(nullptr);
337     }
338
339     ~CommandOptions() override = default;
340
341     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
342                           ExecutionContext *execution_context) override {
343       Status error;
344       const int short_option = m_getopt_table[option_idx].val;
345       switch (short_option) {
346       case 'c':
347         attach_info.SetContinueOnceAttached(true);
348         break;
349
350       case 'p': {
351         lldb::pid_t pid;
352         if (option_arg.getAsInteger(0, pid)) {
353           error.SetErrorStringWithFormat("invalid process ID '%s'",
354                                          option_arg.str().c_str());
355         } else {
356           attach_info.SetProcessID(pid);
357         }
358       } break;
359
360       case 'P':
361         attach_info.SetProcessPluginName(option_arg);
362         break;
363
364       case 'n':
365         attach_info.GetExecutableFile().SetFile(option_arg, false);
366         break;
367
368       case 'w':
369         attach_info.SetWaitForLaunch(true);
370         break;
371
372       case 'i':
373         attach_info.SetIgnoreExisting(false);
374         break;
375
376       default:
377         error.SetErrorStringWithFormat("invalid short option character '%c'",
378                                        short_option);
379         break;
380       }
381       return error;
382     }
383
384     void OptionParsingStarting(ExecutionContext *execution_context) override {
385       attach_info.Clear();
386     }
387
388     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
389       return llvm::makeArrayRef(g_process_attach_options);
390     }
391
392     bool HandleOptionArgumentCompletion(
393         Args &input, int cursor_index, int char_pos,
394         OptionElementVector &opt_element_vector, int opt_element_index,
395         int match_start_point, int max_return_elements,
396         CommandInterpreter &interpreter, bool &word_complete,
397         StringList &matches) override {
398       int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
399       int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
400
401       // We are only completing the name option for now...
402
403       if (GetDefinitions()[opt_defs_index].short_option == 'n') {
404         // Are we in the name?
405
406         // Look to see if there is a -P argument provided, and if so use that
407         // plugin, otherwise
408         // use the default plugin.
409
410         const char *partial_name = nullptr;
411         partial_name = input.GetArgumentAtIndex(opt_arg_pos);
412
413         PlatformSP platform_sp(interpreter.GetPlatform(true));
414         if (platform_sp) {
415           ProcessInstanceInfoList process_infos;
416           ProcessInstanceInfoMatch match_info;
417           if (partial_name) {
418             match_info.GetProcessInfo().GetExecutableFile().SetFile(
419                 partial_name, false);
420             match_info.SetNameMatchType(NameMatch::StartsWith);
421           }
422           platform_sp->FindProcesses(match_info, process_infos);
423           const size_t num_matches = process_infos.GetSize();
424           if (num_matches > 0) {
425             for (size_t i = 0; i < num_matches; ++i) {
426               matches.AppendString(
427                   process_infos.GetProcessNameAtIndex(i),
428                   process_infos.GetProcessNameLengthAtIndex(i));
429             }
430           }
431         }
432       }
433
434       return false;
435     }
436
437     // Instance variables to hold the values for command options.
438
439     ProcessAttachInfo attach_info;
440   };
441
442   CommandObjectProcessAttach(CommandInterpreter &interpreter)
443       : CommandObjectProcessLaunchOrAttach(
444             interpreter, "process attach", "Attach to a process.",
445             "process attach <cmd-options>", 0, "attach"),
446         m_options() {}
447
448   ~CommandObjectProcessAttach() override = default;
449
450   Options *GetOptions() override { return &m_options; }
451
452 protected:
453   bool DoExecute(Args &command, CommandReturnObject &result) override {
454     PlatformSP platform_sp(
455         m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
456
457     Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
458     // N.B. The attach should be synchronous.  It doesn't help much to get the
459     // prompt back between initiating the attach
460     // and the target actually stopping.  So even if the interpreter is set to
461     // be asynchronous, we wait for the stop
462     // ourselves here.
463
464     StateType state = eStateInvalid;
465     Process *process = m_exe_ctx.GetProcessPtr();
466
467     if (!StopProcessIfNecessary(process, state, result))
468       return false;
469
470     if (target == nullptr) {
471       // If there isn't a current target create one.
472       TargetSP new_target_sp;
473       Status error;
474
475       error = m_interpreter.GetDebugger().GetTargetList().CreateTarget(
476           m_interpreter.GetDebugger(), "", "", false,
477           nullptr, // No platform options
478           new_target_sp);
479       target = new_target_sp.get();
480       if (target == nullptr || error.Fail()) {
481         result.AppendError(error.AsCString("Error creating target"));
482         return false;
483       }
484       m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target);
485     }
486
487     // Record the old executable module, we want to issue a warning if the
488     // process of attaching changed the
489     // current executable (like somebody said "file foo" then attached to a PID
490     // whose executable was bar.)
491
492     ModuleSP old_exec_module_sp = target->GetExecutableModule();
493     ArchSpec old_arch_spec = target->GetArchitecture();
494
495     if (command.GetArgumentCount()) {
496       result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: %s\n",
497                                    m_cmd_name.c_str(), m_cmd_syntax.c_str());
498       result.SetStatus(eReturnStatusFailed);
499       return false;
500     }
501
502     m_interpreter.UpdateExecutionContext(nullptr);
503     StreamString stream;
504     const auto error = target->Attach(m_options.attach_info, &stream);
505     if (error.Success()) {
506       ProcessSP process_sp(target->GetProcessSP());
507       if (process_sp) {
508         result.AppendMessage(stream.GetString());
509         result.SetStatus(eReturnStatusSuccessFinishNoResult);
510         result.SetDidChangeProcessState(true);
511         result.SetAbnormalStopWasExpected(true);
512       } else {
513         result.AppendError(
514             "no error returned from Target::Attach, and target has no process");
515         result.SetStatus(eReturnStatusFailed);
516       }
517     } else {
518       result.AppendErrorWithFormat("attach failed: %s\n", error.AsCString());
519       result.SetStatus(eReturnStatusFailed);
520     }
521
522     if (!result.Succeeded())
523       return false;
524
525     // Okay, we're done.  Last step is to warn if the executable module has
526     // changed:
527     char new_path[PATH_MAX];
528     ModuleSP new_exec_module_sp(target->GetExecutableModule());
529     if (!old_exec_module_sp) {
530       // We might not have a module if we attached to a raw pid...
531       if (new_exec_module_sp) {
532         new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX);
533         result.AppendMessageWithFormat("Executable module set to \"%s\".\n",
534                                        new_path);
535       }
536     } else if (old_exec_module_sp->GetFileSpec() !=
537                new_exec_module_sp->GetFileSpec()) {
538       char old_path[PATH_MAX];
539
540       old_exec_module_sp->GetFileSpec().GetPath(old_path, PATH_MAX);
541       new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX);
542
543       result.AppendWarningWithFormat(
544           "Executable module changed from \"%s\" to \"%s\".\n", old_path,
545           new_path);
546     }
547
548     if (!old_arch_spec.IsValid()) {
549       result.AppendMessageWithFormat(
550           "Architecture set to: %s.\n",
551           target->GetArchitecture().GetTriple().getTriple().c_str());
552     } else if (!old_arch_spec.IsExactMatch(target->GetArchitecture())) {
553       result.AppendWarningWithFormat(
554           "Architecture changed from %s to %s.\n",
555           old_arch_spec.GetTriple().getTriple().c_str(),
556           target->GetArchitecture().GetTriple().getTriple().c_str());
557     }
558
559     // This supports the use-case scenario of immediately continuing the process
560     // once attached.
561     if (m_options.attach_info.GetContinueOnceAttached())
562       m_interpreter.HandleCommand("process continue", eLazyBoolNo, result);
563
564     return result.Succeeded();
565   }
566
567   CommandOptions m_options;
568 };
569
570 //-------------------------------------------------------------------------
571 // CommandObjectProcessContinue
572 //-------------------------------------------------------------------------
573
574 static OptionDefinition g_process_continue_options[] = {
575     // clang-format off
576   { LLDB_OPT_SET_ALL, false, "ignore-count",'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger, "Ignore <N> crossings of the breakpoint (if it exists) for the currently selected thread." }
577     // clang-format on
578 };
579
580 #pragma mark CommandObjectProcessContinue
581
582 class CommandObjectProcessContinue : public CommandObjectParsed {
583 public:
584   CommandObjectProcessContinue(CommandInterpreter &interpreter)
585       : CommandObjectParsed(
586             interpreter, "process continue",
587             "Continue execution of all threads in the current process.",
588             "process continue",
589             eCommandRequiresProcess | eCommandTryTargetAPILock |
590                 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
591         m_options() {}
592
593   ~CommandObjectProcessContinue() override = default;
594
595 protected:
596   class CommandOptions : public Options {
597   public:
598     CommandOptions() : Options() {
599       // Keep default values of all options in one place: OptionParsingStarting
600       // ()
601       OptionParsingStarting(nullptr);
602     }
603
604     ~CommandOptions() override = default;
605
606     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
607                           ExecutionContext *execution_context) override {
608       Status error;
609       const int short_option = m_getopt_table[option_idx].val;
610       switch (short_option) {
611       case 'i':
612         if (option_arg.getAsInteger(0, m_ignore))
613           error.SetErrorStringWithFormat(
614               "invalid value for ignore option: \"%s\", should be a number.",
615               option_arg.str().c_str());
616         break;
617
618       default:
619         error.SetErrorStringWithFormat("invalid short option character '%c'",
620                                        short_option);
621         break;
622       }
623       return error;
624     }
625
626     void OptionParsingStarting(ExecutionContext *execution_context) override {
627       m_ignore = 0;
628     }
629
630     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
631       return llvm::makeArrayRef(g_process_continue_options);
632     }
633
634     uint32_t m_ignore;
635   };
636
637   bool DoExecute(Args &command, CommandReturnObject &result) override {
638     Process *process = m_exe_ctx.GetProcessPtr();
639     bool synchronous_execution = m_interpreter.GetSynchronous();
640     StateType state = process->GetState();
641     if (state == eStateStopped) {
642       if (command.GetArgumentCount() != 0) {
643         result.AppendErrorWithFormat(
644             "The '%s' command does not take any arguments.\n",
645             m_cmd_name.c_str());
646         result.SetStatus(eReturnStatusFailed);
647         return false;
648       }
649
650       if (m_options.m_ignore > 0) {
651         ThreadSP sel_thread_sp(GetDefaultThread()->shared_from_this());
652         if (sel_thread_sp) {
653           StopInfoSP stop_info_sp = sel_thread_sp->GetStopInfo();
654           if (stop_info_sp &&
655               stop_info_sp->GetStopReason() == eStopReasonBreakpoint) {
656             lldb::break_id_t bp_site_id =
657                 (lldb::break_id_t)stop_info_sp->GetValue();
658             BreakpointSiteSP bp_site_sp(
659                 process->GetBreakpointSiteList().FindByID(bp_site_id));
660             if (bp_site_sp) {
661               const size_t num_owners = bp_site_sp->GetNumberOfOwners();
662               for (size_t i = 0; i < num_owners; i++) {
663                 Breakpoint &bp_ref =
664                     bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
665                 if (!bp_ref.IsInternal()) {
666                   bp_ref.SetIgnoreCount(m_options.m_ignore);
667                 }
668               }
669             }
670           }
671         }
672       }
673
674       { // Scope for thread list mutex:
675         std::lock_guard<std::recursive_mutex> guard(
676             process->GetThreadList().GetMutex());
677         const uint32_t num_threads = process->GetThreadList().GetSize();
678
679         // Set the actions that the threads should each take when resuming
680         for (uint32_t idx = 0; idx < num_threads; ++idx) {
681           const bool override_suspend = false;
682           process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState(
683               eStateRunning, override_suspend);
684         }
685       }
686
687       const uint32_t iohandler_id = process->GetIOHandlerID();
688
689       StreamString stream;
690       Status error;
691       if (synchronous_execution)
692         error = process->ResumeSynchronous(&stream);
693       else
694         error = process->Resume();
695
696       if (error.Success()) {
697         // There is a race condition where this thread will return up the call
698         // stack to the main command
699         // handler and show an (lldb) prompt before HandlePrivateEvent (from
700         // PrivateStateThread) has
701         // a chance to call PushProcessIOHandler().
702         process->SyncIOHandler(iohandler_id, 2000);
703
704         result.AppendMessageWithFormat("Process %" PRIu64 " resuming\n",
705                                        process->GetID());
706         if (synchronous_execution) {
707           // If any state changed events had anything to say, add that to the
708           // result
709           result.AppendMessage(stream.GetString());
710
711           result.SetDidChangeProcessState(true);
712           result.SetStatus(eReturnStatusSuccessFinishNoResult);
713         } else {
714           result.SetStatus(eReturnStatusSuccessContinuingNoResult);
715         }
716       } else {
717         result.AppendErrorWithFormat("Failed to resume process: %s.\n",
718                                      error.AsCString());
719         result.SetStatus(eReturnStatusFailed);
720       }
721     } else {
722       result.AppendErrorWithFormat(
723           "Process cannot be continued from its current state (%s).\n",
724           StateAsCString(state));
725       result.SetStatus(eReturnStatusFailed);
726     }
727     return result.Succeeded();
728   }
729
730   Options *GetOptions() override { return &m_options; }
731
732   CommandOptions m_options;
733 };
734
735 //-------------------------------------------------------------------------
736 // CommandObjectProcessDetach
737 //-------------------------------------------------------------------------
738 static OptionDefinition g_process_detach_options[] = {
739     // clang-format off
740   { 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)." },
741     // clang-format on
742 };
743
744 #pragma mark CommandObjectProcessDetach
745
746 class CommandObjectProcessDetach : public CommandObjectParsed {
747 public:
748   class CommandOptions : public Options {
749   public:
750     CommandOptions() : Options() { OptionParsingStarting(nullptr); }
751
752     ~CommandOptions() override = default;
753
754     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
755                           ExecutionContext *execution_context) override {
756       Status error;
757       const int short_option = m_getopt_table[option_idx].val;
758
759       switch (short_option) {
760       case 's':
761         bool tmp_result;
762         bool success;
763         tmp_result = Args::StringToBoolean(option_arg, false, &success);
764         if (!success)
765           error.SetErrorStringWithFormat("invalid boolean option: \"%s\"",
766                                          option_arg.str().c_str());
767         else {
768           if (tmp_result)
769             m_keep_stopped = eLazyBoolYes;
770           else
771             m_keep_stopped = eLazyBoolNo;
772         }
773         break;
774       default:
775         error.SetErrorStringWithFormat("invalid short option character '%c'",
776                                        short_option);
777         break;
778       }
779       return error;
780     }
781
782     void OptionParsingStarting(ExecutionContext *execution_context) override {
783       m_keep_stopped = eLazyBoolCalculate;
784     }
785
786     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
787       return llvm::makeArrayRef(g_process_detach_options);
788     }
789
790     // Instance variables to hold the values for command options.
791     LazyBool m_keep_stopped;
792   };
793
794   CommandObjectProcessDetach(CommandInterpreter &interpreter)
795       : CommandObjectParsed(interpreter, "process detach",
796                             "Detach from the current target process.",
797                             "process detach",
798                             eCommandRequiresProcess | eCommandTryTargetAPILock |
799                                 eCommandProcessMustBeLaunched),
800         m_options() {}
801
802   ~CommandObjectProcessDetach() override = default;
803
804   Options *GetOptions() override { return &m_options; }
805
806 protected:
807   bool DoExecute(Args &command, CommandReturnObject &result) override {
808     Process *process = m_exe_ctx.GetProcessPtr();
809     // FIXME: This will be a Command Option:
810     bool keep_stopped;
811     if (m_options.m_keep_stopped == eLazyBoolCalculate) {
812       // Check the process default:
813       keep_stopped = process->GetDetachKeepsStopped();
814     } else if (m_options.m_keep_stopped == eLazyBoolYes)
815       keep_stopped = true;
816     else
817       keep_stopped = false;
818
819     Status error(process->Detach(keep_stopped));
820     if (error.Success()) {
821       result.SetStatus(eReturnStatusSuccessFinishResult);
822     } else {
823       result.AppendErrorWithFormat("Detach failed: %s\n", error.AsCString());
824       result.SetStatus(eReturnStatusFailed);
825       return false;
826     }
827     return result.Succeeded();
828   }
829
830   CommandOptions m_options;
831 };
832
833 //-------------------------------------------------------------------------
834 // CommandObjectProcessConnect
835 //-------------------------------------------------------------------------
836
837 static OptionDefinition g_process_connect_options[] = {
838     // clang-format off
839   { LLDB_OPT_SET_ALL, false, "plugin", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePlugin, "Name of the process plugin you want to use." },
840     // clang-format on
841 };
842
843 #pragma mark CommandObjectProcessConnect
844
845 class CommandObjectProcessConnect : public CommandObjectParsed {
846 public:
847   class CommandOptions : public Options {
848   public:
849     CommandOptions() : Options() {
850       // Keep default values of all options in one place: OptionParsingStarting
851       // ()
852       OptionParsingStarting(nullptr);
853     }
854
855     ~CommandOptions() override = default;
856
857     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
858                           ExecutionContext *execution_context) override {
859       Status error;
860       const int short_option = m_getopt_table[option_idx].val;
861
862       switch (short_option) {
863       case 'p':
864         plugin_name.assign(option_arg);
865         break;
866
867       default:
868         error.SetErrorStringWithFormat("invalid short option character '%c'",
869                                        short_option);
870         break;
871       }
872       return error;
873     }
874
875     void OptionParsingStarting(ExecutionContext *execution_context) override {
876       plugin_name.clear();
877     }
878
879     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
880       return llvm::makeArrayRef(g_process_connect_options);
881     }
882
883     // Instance variables to hold the values for command options.
884
885     std::string plugin_name;
886   };
887
888   CommandObjectProcessConnect(CommandInterpreter &interpreter)
889       : CommandObjectParsed(interpreter, "process connect",
890                             "Connect to a remote debug service.",
891                             "process connect <remote-url>", 0),
892         m_options() {}
893
894   ~CommandObjectProcessConnect() override = default;
895
896   Options *GetOptions() override { return &m_options; }
897
898 protected:
899   bool DoExecute(Args &command, CommandReturnObject &result) override {
900     if (command.GetArgumentCount() != 1) {
901       result.AppendErrorWithFormat(
902           "'%s' takes exactly one argument:\nUsage: %s\n", m_cmd_name.c_str(),
903           m_cmd_syntax.c_str());
904       result.SetStatus(eReturnStatusFailed);
905       return false;
906     }
907
908     Process *process = m_exe_ctx.GetProcessPtr();
909     if (process && process->IsAlive()) {
910       result.AppendErrorWithFormat(
911           "Process %" PRIu64
912           " is currently being debugged, kill the process before connecting.\n",
913           process->GetID());
914       result.SetStatus(eReturnStatusFailed);
915       return false;
916     }
917
918     const char *plugin_name = nullptr;
919     if (!m_options.plugin_name.empty())
920       plugin_name = m_options.plugin_name.c_str();
921
922     Status error;
923     Debugger &debugger = m_interpreter.GetDebugger();
924     PlatformSP platform_sp = m_interpreter.GetPlatform(true);
925     ProcessSP process_sp = platform_sp->ConnectProcess(
926         command.GetArgumentAtIndex(0), plugin_name, debugger,
927         debugger.GetSelectedTarget().get(), error);
928     if (error.Fail() || process_sp == nullptr) {
929       result.AppendError(error.AsCString("Error connecting to the process"));
930       result.SetStatus(eReturnStatusFailed);
931       return false;
932     }
933     return true;
934   }
935
936   CommandOptions m_options;
937 };
938
939 //-------------------------------------------------------------------------
940 // CommandObjectProcessPlugin
941 //-------------------------------------------------------------------------
942 #pragma mark CommandObjectProcessPlugin
943
944 class CommandObjectProcessPlugin : public CommandObjectProxy {
945 public:
946   CommandObjectProcessPlugin(CommandInterpreter &interpreter)
947       : CommandObjectProxy(
948             interpreter, "process plugin",
949             "Send a custom command to the current target process plug-in.",
950             "process plugin <args>", 0) {}
951
952   ~CommandObjectProcessPlugin() override = default;
953
954   CommandObject *GetProxyCommandObject() override {
955     Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
956     if (process)
957       return process->GetPluginCommandObject();
958     return nullptr;
959   }
960 };
961
962 //-------------------------------------------------------------------------
963 // CommandObjectProcessLoad
964 //-------------------------------------------------------------------------
965
966 static OptionDefinition g_process_load_options[] = {
967     // clang-format off
968   { 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." },
969     // clang-format on
970 };
971
972 #pragma mark CommandObjectProcessLoad
973
974 class CommandObjectProcessLoad : public CommandObjectParsed {
975 public:
976   class CommandOptions : public Options {
977   public:
978     CommandOptions() : Options() {
979       // Keep default values of all options in one place: OptionParsingStarting
980       // ()
981       OptionParsingStarting(nullptr);
982     }
983
984     ~CommandOptions() override = default;
985
986     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
987                           ExecutionContext *execution_context) override {
988       Status error;
989       const int short_option = m_getopt_table[option_idx].val;
990       switch (short_option) {
991       case 'i':
992         do_install = true;
993         if (!option_arg.empty())
994           install_path.SetFile(option_arg, false);
995         break;
996       default:
997         error.SetErrorStringWithFormat("invalid short option character '%c'",
998                                        short_option);
999         break;
1000       }
1001       return error;
1002     }
1003
1004     void OptionParsingStarting(ExecutionContext *execution_context) override {
1005       do_install = false;
1006       install_path.Clear();
1007     }
1008
1009     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1010       return llvm::makeArrayRef(g_process_load_options);
1011     }
1012
1013     // Instance variables to hold the values for command options.
1014     bool do_install;
1015     FileSpec install_path;
1016   };
1017
1018   CommandObjectProcessLoad(CommandInterpreter &interpreter)
1019       : CommandObjectParsed(interpreter, "process load",
1020                             "Load a shared library into the current process.",
1021                             "process load <filename> [<filename> ...]",
1022                             eCommandRequiresProcess | eCommandTryTargetAPILock |
1023                                 eCommandProcessMustBeLaunched |
1024                                 eCommandProcessMustBePaused),
1025         m_options() {}
1026
1027   ~CommandObjectProcessLoad() override = default;
1028
1029   Options *GetOptions() override { return &m_options; }
1030
1031 protected:
1032   bool DoExecute(Args &command, CommandReturnObject &result) override {
1033     Process *process = m_exe_ctx.GetProcessPtr();
1034
1035     for (auto &entry : command.entries()) {
1036       Status error;
1037       PlatformSP platform = process->GetTarget().GetPlatform();
1038       llvm::StringRef image_path = entry.ref;
1039       uint32_t image_token = LLDB_INVALID_IMAGE_TOKEN;
1040
1041       if (!m_options.do_install) {
1042         FileSpec image_spec(image_path, false);
1043         platform->ResolveRemotePath(image_spec, image_spec);
1044         image_token =
1045             platform->LoadImage(process, FileSpec(), image_spec, error);
1046       } else if (m_options.install_path) {
1047         FileSpec image_spec(image_path, true);
1048         platform->ResolveRemotePath(m_options.install_path,
1049                                     m_options.install_path);
1050         image_token = platform->LoadImage(process, image_spec,
1051                                           m_options.install_path, error);
1052       } else {
1053         FileSpec image_spec(image_path, true);
1054         image_token =
1055             platform->LoadImage(process, image_spec, FileSpec(), error);
1056       }
1057
1058       if (image_token != LLDB_INVALID_IMAGE_TOKEN) {
1059         result.AppendMessageWithFormat(
1060             "Loading \"%s\"...ok\nImage %u loaded.\n", image_path.str().c_str(),
1061             image_token);
1062         result.SetStatus(eReturnStatusSuccessFinishResult);
1063       } else {
1064         result.AppendErrorWithFormat("failed to load '%s': %s",
1065                                      image_path.str().c_str(),
1066                                      error.AsCString());
1067         result.SetStatus(eReturnStatusFailed);
1068       }
1069     }
1070     return result.Succeeded();
1071   }
1072
1073   CommandOptions m_options;
1074 };
1075
1076 //-------------------------------------------------------------------------
1077 // CommandObjectProcessUnload
1078 //-------------------------------------------------------------------------
1079 #pragma mark CommandObjectProcessUnload
1080
1081 class CommandObjectProcessUnload : public CommandObjectParsed {
1082 public:
1083   CommandObjectProcessUnload(CommandInterpreter &interpreter)
1084       : CommandObjectParsed(
1085             interpreter, "process unload",
1086             "Unload a shared library from the current process using the index "
1087             "returned by a previous call to \"process load\".",
1088             "process unload <index>",
1089             eCommandRequiresProcess | eCommandTryTargetAPILock |
1090                 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {}
1091
1092   ~CommandObjectProcessUnload() override = default;
1093
1094 protected:
1095   bool DoExecute(Args &command, CommandReturnObject &result) override {
1096     Process *process = m_exe_ctx.GetProcessPtr();
1097
1098     for (auto &entry : command.entries()) {
1099       uint32_t image_token;
1100       if (entry.ref.getAsInteger(0, image_token)) {
1101         result.AppendErrorWithFormat("invalid image index argument '%s'",
1102                                      entry.ref.str().c_str());
1103         result.SetStatus(eReturnStatusFailed);
1104         break;
1105       } else {
1106         Status error(process->GetTarget().GetPlatform()->UnloadImage(
1107             process, image_token));
1108         if (error.Success()) {
1109           result.AppendMessageWithFormat(
1110               "Unloading shared library with index %u...ok\n", image_token);
1111           result.SetStatus(eReturnStatusSuccessFinishResult);
1112         } else {
1113           result.AppendErrorWithFormat("failed to unload image: %s",
1114                                        error.AsCString());
1115           result.SetStatus(eReturnStatusFailed);
1116           break;
1117         }
1118       }
1119     }
1120     return result.Succeeded();
1121   }
1122 };
1123
1124 //-------------------------------------------------------------------------
1125 // CommandObjectProcessSignal
1126 //-------------------------------------------------------------------------
1127 #pragma mark CommandObjectProcessSignal
1128
1129 class CommandObjectProcessSignal : public CommandObjectParsed {
1130 public:
1131   CommandObjectProcessSignal(CommandInterpreter &interpreter)
1132       : CommandObjectParsed(interpreter, "process signal",
1133                             "Send a UNIX signal to the current target process.",
1134                             nullptr, eCommandRequiresProcess |
1135                                          eCommandTryTargetAPILock) {
1136     CommandArgumentEntry arg;
1137     CommandArgumentData signal_arg;
1138
1139     // Define the first (and only) variant of this arg.
1140     signal_arg.arg_type = eArgTypeUnixSignal;
1141     signal_arg.arg_repetition = eArgRepeatPlain;
1142
1143     // There is only one variant this argument could be; put it into the
1144     // argument entry.
1145     arg.push_back(signal_arg);
1146
1147     // Push the data for the first argument into the m_arguments vector.
1148     m_arguments.push_back(arg);
1149   }
1150
1151   ~CommandObjectProcessSignal() override = default;
1152
1153 protected:
1154   bool DoExecute(Args &command, CommandReturnObject &result) override {
1155     Process *process = m_exe_ctx.GetProcessPtr();
1156
1157     if (command.GetArgumentCount() == 1) {
1158       int signo = LLDB_INVALID_SIGNAL_NUMBER;
1159
1160       const char *signal_name = command.GetArgumentAtIndex(0);
1161       if (::isxdigit(signal_name[0]))
1162         signo =
1163             StringConvert::ToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0);
1164       else
1165         signo = process->GetUnixSignals()->GetSignalNumberFromName(signal_name);
1166
1167       if (signo == LLDB_INVALID_SIGNAL_NUMBER) {
1168         result.AppendErrorWithFormat("Invalid signal argument '%s'.\n",
1169                                      command.GetArgumentAtIndex(0));
1170         result.SetStatus(eReturnStatusFailed);
1171       } else {
1172         Status error(process->Signal(signo));
1173         if (error.Success()) {
1174           result.SetStatus(eReturnStatusSuccessFinishResult);
1175         } else {
1176           result.AppendErrorWithFormat("Failed to send signal %i: %s\n", signo,
1177                                        error.AsCString());
1178           result.SetStatus(eReturnStatusFailed);
1179         }
1180       }
1181     } else {
1182       result.AppendErrorWithFormat(
1183           "'%s' takes exactly one signal number argument:\nUsage: %s\n",
1184           m_cmd_name.c_str(), m_cmd_syntax.c_str());
1185       result.SetStatus(eReturnStatusFailed);
1186     }
1187     return result.Succeeded();
1188   }
1189 };
1190
1191 //-------------------------------------------------------------------------
1192 // CommandObjectProcessInterrupt
1193 //-------------------------------------------------------------------------
1194 #pragma mark CommandObjectProcessInterrupt
1195
1196 class CommandObjectProcessInterrupt : public CommandObjectParsed {
1197 public:
1198   CommandObjectProcessInterrupt(CommandInterpreter &interpreter)
1199       : CommandObjectParsed(interpreter, "process interrupt",
1200                             "Interrupt the current target process.",
1201                             "process interrupt",
1202                             eCommandRequiresProcess | eCommandTryTargetAPILock |
1203                                 eCommandProcessMustBeLaunched) {}
1204
1205   ~CommandObjectProcessInterrupt() override = default;
1206
1207 protected:
1208   bool DoExecute(Args &command, CommandReturnObject &result) override {
1209     Process *process = m_exe_ctx.GetProcessPtr();
1210     if (process == nullptr) {
1211       result.AppendError("no process to halt");
1212       result.SetStatus(eReturnStatusFailed);
1213       return false;
1214     }
1215
1216     if (command.GetArgumentCount() == 0) {
1217       bool clear_thread_plans = true;
1218       Status error(process->Halt(clear_thread_plans));
1219       if (error.Success()) {
1220         result.SetStatus(eReturnStatusSuccessFinishResult);
1221       } else {
1222         result.AppendErrorWithFormat("Failed to halt process: %s\n",
1223                                      error.AsCString());
1224         result.SetStatus(eReturnStatusFailed);
1225       }
1226     } else {
1227       result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n",
1228                                    m_cmd_name.c_str(), m_cmd_syntax.c_str());
1229       result.SetStatus(eReturnStatusFailed);
1230     }
1231     return result.Succeeded();
1232   }
1233 };
1234
1235 //-------------------------------------------------------------------------
1236 // CommandObjectProcessKill
1237 //-------------------------------------------------------------------------
1238 #pragma mark CommandObjectProcessKill
1239
1240 class CommandObjectProcessKill : public CommandObjectParsed {
1241 public:
1242   CommandObjectProcessKill(CommandInterpreter &interpreter)
1243       : CommandObjectParsed(interpreter, "process kill",
1244                             "Terminate the current target process.",
1245                             "process kill",
1246                             eCommandRequiresProcess | eCommandTryTargetAPILock |
1247                                 eCommandProcessMustBeLaunched) {}
1248
1249   ~CommandObjectProcessKill() override = default;
1250
1251 protected:
1252   bool DoExecute(Args &command, CommandReturnObject &result) override {
1253     Process *process = m_exe_ctx.GetProcessPtr();
1254     if (process == nullptr) {
1255       result.AppendError("no process to kill");
1256       result.SetStatus(eReturnStatusFailed);
1257       return false;
1258     }
1259
1260     if (command.GetArgumentCount() == 0) {
1261       Status error(process->Destroy(true));
1262       if (error.Success()) {
1263         result.SetStatus(eReturnStatusSuccessFinishResult);
1264       } else {
1265         result.AppendErrorWithFormat("Failed to kill process: %s\n",
1266                                      error.AsCString());
1267         result.SetStatus(eReturnStatusFailed);
1268       }
1269     } else {
1270       result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n",
1271                                    m_cmd_name.c_str(), m_cmd_syntax.c_str());
1272       result.SetStatus(eReturnStatusFailed);
1273     }
1274     return result.Succeeded();
1275   }
1276 };
1277
1278 //-------------------------------------------------------------------------
1279 // CommandObjectProcessSaveCore
1280 //-------------------------------------------------------------------------
1281 #pragma mark CommandObjectProcessSaveCore
1282
1283 class CommandObjectProcessSaveCore : public CommandObjectParsed {
1284 public:
1285   CommandObjectProcessSaveCore(CommandInterpreter &interpreter)
1286       : CommandObjectParsed(interpreter, "process save-core",
1287                             "Save the current process as a core file using an "
1288                             "appropriate file type.",
1289                             "process save-core FILE",
1290                             eCommandRequiresProcess | eCommandTryTargetAPILock |
1291                                 eCommandProcessMustBeLaunched) {}
1292
1293   ~CommandObjectProcessSaveCore() override = default;
1294
1295 protected:
1296   bool DoExecute(Args &command, CommandReturnObject &result) override {
1297     ProcessSP process_sp = m_exe_ctx.GetProcessSP();
1298     if (process_sp) {
1299       if (command.GetArgumentCount() == 1) {
1300         FileSpec output_file(command.GetArgumentAtIndex(0), false);
1301         Status error = PluginManager::SaveCore(process_sp, output_file);
1302         if (error.Success()) {
1303           result.SetStatus(eReturnStatusSuccessFinishResult);
1304         } else {
1305           result.AppendErrorWithFormat(
1306               "Failed to save core file for process: %s\n", error.AsCString());
1307           result.SetStatus(eReturnStatusFailed);
1308         }
1309       } else {
1310         result.AppendErrorWithFormat("'%s' takes one arguments:\nUsage: %s\n",
1311                                      m_cmd_name.c_str(), m_cmd_syntax.c_str());
1312         result.SetStatus(eReturnStatusFailed);
1313       }
1314     } else {
1315       result.AppendError("invalid process");
1316       result.SetStatus(eReturnStatusFailed);
1317       return false;
1318     }
1319
1320     return result.Succeeded();
1321   }
1322 };
1323
1324 //-------------------------------------------------------------------------
1325 // CommandObjectProcessStatus
1326 //-------------------------------------------------------------------------
1327 #pragma mark CommandObjectProcessStatus
1328
1329 class CommandObjectProcessStatus : public CommandObjectParsed {
1330 public:
1331   CommandObjectProcessStatus(CommandInterpreter &interpreter)
1332       : CommandObjectParsed(
1333             interpreter, "process status",
1334             "Show status and stop location for the current target process.",
1335             "process status",
1336             eCommandRequiresProcess | eCommandTryTargetAPILock) {}
1337
1338   ~CommandObjectProcessStatus() override = default;
1339
1340   bool DoExecute(Args &command, CommandReturnObject &result) override {
1341     Stream &strm = result.GetOutputStream();
1342     result.SetStatus(eReturnStatusSuccessFinishNoResult);
1343     // No need to check "process" for validity as eCommandRequiresProcess
1344     // ensures it is valid
1345     Process *process = m_exe_ctx.GetProcessPtr();
1346     const bool only_threads_with_stop_reason = true;
1347     const uint32_t start_frame = 0;
1348     const uint32_t num_frames = 1;
1349     const uint32_t num_frames_with_source = 1;
1350     const bool     stop_format = true;
1351     process->GetStatus(strm);
1352     process->GetThreadStatus(strm, only_threads_with_stop_reason, start_frame,
1353                              num_frames, num_frames_with_source, stop_format);
1354     return result.Succeeded();
1355   }
1356 };
1357
1358 //-------------------------------------------------------------------------
1359 // CommandObjectProcessHandle
1360 //-------------------------------------------------------------------------
1361
1362 static OptionDefinition g_process_handle_options[] = {
1363     // clang-format off
1364   { 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." },
1365   { 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." },
1366   { LLDB_OPT_SET_1, false, "pass",   'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." }
1367     // clang-format on
1368 };
1369
1370 #pragma mark CommandObjectProcessHandle
1371
1372 class CommandObjectProcessHandle : public CommandObjectParsed {
1373 public:
1374   class CommandOptions : public Options {
1375   public:
1376     CommandOptions() : Options() { OptionParsingStarting(nullptr); }
1377
1378     ~CommandOptions() override = default;
1379
1380     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1381                           ExecutionContext *execution_context) override {
1382       Status error;
1383       const int short_option = m_getopt_table[option_idx].val;
1384
1385       switch (short_option) {
1386       case 's':
1387         stop = option_arg;
1388         break;
1389       case 'n':
1390         notify = option_arg;
1391         break;
1392       case 'p':
1393         pass = option_arg;
1394         break;
1395       default:
1396         error.SetErrorStringWithFormat("invalid short option character '%c'",
1397                                        short_option);
1398         break;
1399       }
1400       return error;
1401     }
1402
1403     void OptionParsingStarting(ExecutionContext *execution_context) override {
1404       stop.clear();
1405       notify.clear();
1406       pass.clear();
1407     }
1408
1409     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1410       return llvm::makeArrayRef(g_process_handle_options);
1411     }
1412
1413     // Instance variables to hold the values for command options.
1414
1415     std::string stop;
1416     std::string notify;
1417     std::string pass;
1418   };
1419
1420   CommandObjectProcessHandle(CommandInterpreter &interpreter)
1421       : CommandObjectParsed(interpreter, "process handle",
1422                             "Manage LLDB handling of OS signals for the "
1423                             "current target process.  Defaults to showing "
1424                             "current policy.",
1425                             nullptr),
1426         m_options() {
1427     SetHelpLong("\nIf no signals are specified, update them all.  If no update "
1428                 "option is specified, list the current values.");
1429     CommandArgumentEntry arg;
1430     CommandArgumentData signal_arg;
1431
1432     signal_arg.arg_type = eArgTypeUnixSignal;
1433     signal_arg.arg_repetition = eArgRepeatStar;
1434
1435     arg.push_back(signal_arg);
1436
1437     m_arguments.push_back(arg);
1438   }
1439
1440   ~CommandObjectProcessHandle() override = default;
1441
1442   Options *GetOptions() override { return &m_options; }
1443
1444   bool VerifyCommandOptionValue(const std::string &option, int &real_value) {
1445     bool okay = true;
1446     bool success = false;
1447     bool tmp_value = Args::StringToBoolean(option, false, &success);
1448
1449     if (success && tmp_value)
1450       real_value = 1;
1451     else if (success && !tmp_value)
1452       real_value = 0;
1453     else {
1454       // If the value isn't 'true' or 'false', it had better be 0 or 1.
1455       real_value = StringConvert::ToUInt32(option.c_str(), 3);
1456       if (real_value != 0 && real_value != 1)
1457         okay = false;
1458     }
1459
1460     return okay;
1461   }
1462
1463   void PrintSignalHeader(Stream &str) {
1464     str.Printf("NAME         PASS   STOP   NOTIFY\n");
1465     str.Printf("===========  =====  =====  ======\n");
1466   }
1467
1468   void PrintSignal(Stream &str, int32_t signo, const char *sig_name,
1469                    const UnixSignalsSP &signals_sp) {
1470     bool stop;
1471     bool suppress;
1472     bool notify;
1473
1474     str.Printf("%-11s  ", sig_name);
1475     if (signals_sp->GetSignalInfo(signo, suppress, stop, notify)) {
1476       bool pass = !suppress;
1477       str.Printf("%s  %s  %s", (pass ? "true " : "false"),
1478                  (stop ? "true " : "false"), (notify ? "true " : "false"));
1479     }
1480     str.Printf("\n");
1481   }
1482
1483   void PrintSignalInformation(Stream &str, Args &signal_args,
1484                               int num_valid_signals,
1485                               const UnixSignalsSP &signals_sp) {
1486     PrintSignalHeader(str);
1487
1488     if (num_valid_signals > 0) {
1489       size_t num_args = signal_args.GetArgumentCount();
1490       for (size_t i = 0; i < num_args; ++i) {
1491         int32_t signo = signals_sp->GetSignalNumberFromName(
1492             signal_args.GetArgumentAtIndex(i));
1493         if (signo != LLDB_INVALID_SIGNAL_NUMBER)
1494           PrintSignal(str, signo, signal_args.GetArgumentAtIndex(i),
1495                       signals_sp);
1496       }
1497     } else // Print info for ALL signals
1498     {
1499       int32_t signo = signals_sp->GetFirstSignalNumber();
1500       while (signo != LLDB_INVALID_SIGNAL_NUMBER) {
1501         PrintSignal(str, signo, signals_sp->GetSignalAsCString(signo),
1502                     signals_sp);
1503         signo = signals_sp->GetNextSignalNumber(signo);
1504       }
1505     }
1506   }
1507
1508 protected:
1509   bool DoExecute(Args &signal_args, CommandReturnObject &result) override {
1510     TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
1511
1512     if (!target_sp) {
1513       result.AppendError("No current target;"
1514                          " cannot handle signals until you have a valid target "
1515                          "and process.\n");
1516       result.SetStatus(eReturnStatusFailed);
1517       return false;
1518     }
1519
1520     ProcessSP process_sp = target_sp->GetProcessSP();
1521
1522     if (!process_sp) {
1523       result.AppendError("No current process; cannot handle signals until you "
1524                          "have a valid process.\n");
1525       result.SetStatus(eReturnStatusFailed);
1526       return false;
1527     }
1528
1529     int stop_action = -1;   // -1 means leave the current setting alone
1530     int pass_action = -1;   // -1 means leave the current setting alone
1531     int notify_action = -1; // -1 means leave the current setting alone
1532
1533     if (!m_options.stop.empty() &&
1534         !VerifyCommandOptionValue(m_options.stop, stop_action)) {
1535       result.AppendError("Invalid argument for command option --stop; must be "
1536                          "true or false.\n");
1537       result.SetStatus(eReturnStatusFailed);
1538       return false;
1539     }
1540
1541     if (!m_options.notify.empty() &&
1542         !VerifyCommandOptionValue(m_options.notify, notify_action)) {
1543       result.AppendError("Invalid argument for command option --notify; must "
1544                          "be true or false.\n");
1545       result.SetStatus(eReturnStatusFailed);
1546       return false;
1547     }
1548
1549     if (!m_options.pass.empty() &&
1550         !VerifyCommandOptionValue(m_options.pass, pass_action)) {
1551       result.AppendError("Invalid argument for command option --pass; must be "
1552                          "true or false.\n");
1553       result.SetStatus(eReturnStatusFailed);
1554       return false;
1555     }
1556
1557     size_t num_args = signal_args.GetArgumentCount();
1558     UnixSignalsSP signals_sp = process_sp->GetUnixSignals();
1559     int num_signals_set = 0;
1560
1561     if (num_args > 0) {
1562       for (const auto &arg : signal_args) {
1563         int32_t signo = signals_sp->GetSignalNumberFromName(arg.c_str());
1564         if (signo != LLDB_INVALID_SIGNAL_NUMBER) {
1565           // Casting the actions as bools here should be okay, because
1566           // VerifyCommandOptionValue guarantees
1567           // the value is either 0 or 1.
1568           if (stop_action != -1)
1569             signals_sp->SetShouldStop(signo, stop_action);
1570           if (pass_action != -1) {
1571             bool suppress = !pass_action;
1572             signals_sp->SetShouldSuppress(signo, suppress);
1573           }
1574           if (notify_action != -1)
1575             signals_sp->SetShouldNotify(signo, notify_action);
1576           ++num_signals_set;
1577         } else {
1578           result.AppendErrorWithFormat("Invalid signal name '%s'\n",
1579                                        arg.c_str());
1580         }
1581       }
1582     } else {
1583       // No signal specified, if any command options were specified, update ALL
1584       // signals.
1585       if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1)) {
1586         if (m_interpreter.Confirm(
1587                 "Do you really want to update all the signals?", false)) {
1588           int32_t signo = signals_sp->GetFirstSignalNumber();
1589           while (signo != LLDB_INVALID_SIGNAL_NUMBER) {
1590             if (notify_action != -1)
1591               signals_sp->SetShouldNotify(signo, notify_action);
1592             if (stop_action != -1)
1593               signals_sp->SetShouldStop(signo, stop_action);
1594             if (pass_action != -1) {
1595               bool suppress = !pass_action;
1596               signals_sp->SetShouldSuppress(signo, suppress);
1597             }
1598             signo = signals_sp->GetNextSignalNumber(signo);
1599           }
1600         }
1601       }
1602     }
1603
1604     PrintSignalInformation(result.GetOutputStream(), signal_args,
1605                            num_signals_set, signals_sp);
1606
1607     if (num_signals_set > 0)
1608       result.SetStatus(eReturnStatusSuccessFinishNoResult);
1609     else
1610       result.SetStatus(eReturnStatusFailed);
1611
1612     return result.Succeeded();
1613   }
1614
1615   CommandOptions m_options;
1616 };
1617
1618 //-------------------------------------------------------------------------
1619 // CommandObjectMultiwordProcess
1620 //-------------------------------------------------------------------------
1621
1622 CommandObjectMultiwordProcess::CommandObjectMultiwordProcess(
1623     CommandInterpreter &interpreter)
1624     : CommandObjectMultiword(
1625           interpreter, "process",
1626           "Commands for interacting with processes on the current platform.",
1627           "process <subcommand> [<subcommand-options>]") {
1628   LoadSubCommand("attach",
1629                  CommandObjectSP(new CommandObjectProcessAttach(interpreter)));
1630   LoadSubCommand("launch",
1631                  CommandObjectSP(new CommandObjectProcessLaunch(interpreter)));
1632   LoadSubCommand("continue", CommandObjectSP(new CommandObjectProcessContinue(
1633                                  interpreter)));
1634   LoadSubCommand("connect",
1635                  CommandObjectSP(new CommandObjectProcessConnect(interpreter)));
1636   LoadSubCommand("detach",
1637                  CommandObjectSP(new CommandObjectProcessDetach(interpreter)));
1638   LoadSubCommand("load",
1639                  CommandObjectSP(new CommandObjectProcessLoad(interpreter)));
1640   LoadSubCommand("unload",
1641                  CommandObjectSP(new CommandObjectProcessUnload(interpreter)));
1642   LoadSubCommand("signal",
1643                  CommandObjectSP(new CommandObjectProcessSignal(interpreter)));
1644   LoadSubCommand("handle",
1645                  CommandObjectSP(new CommandObjectProcessHandle(interpreter)));
1646   LoadSubCommand("status",
1647                  CommandObjectSP(new CommandObjectProcessStatus(interpreter)));
1648   LoadSubCommand("interrupt", CommandObjectSP(new CommandObjectProcessInterrupt(
1649                                   interpreter)));
1650   LoadSubCommand("kill",
1651                  CommandObjectSP(new CommandObjectProcessKill(interpreter)));
1652   LoadSubCommand("plugin",
1653                  CommandObjectSP(new CommandObjectProcessPlugin(interpreter)));
1654   LoadSubCommand("save-core", CommandObjectSP(new CommandObjectProcessSaveCore(
1655                                   interpreter)));
1656 }
1657
1658 CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess() = default;