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