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