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