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