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