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