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 const char *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) { 214 m_options.launch_info.GetArguments().AppendArgument( 215 llvm::StringRef(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 const char *data = stream.GetData(); 246 if (data && strlen(data) > 0) 247 result.AppendMessage(stream.GetData()); 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 #pragma mark CommandObjectProcessAttach 316 class CommandObjectProcessAttach : public CommandObjectProcessLaunchOrAttach { 317 public: 318 class CommandOptions : public Options { 319 public: 320 CommandOptions() : Options() { 321 // Keep default values of all options in one place: OptionParsingStarting 322 // () 323 OptionParsingStarting(nullptr); 324 } 325 326 ~CommandOptions() override = default; 327 328 Error SetOptionValue(uint32_t option_idx, const char *option_arg, 329 ExecutionContext *execution_context) override { 330 Error error; 331 const int short_option = m_getopt_table[option_idx].val; 332 bool success = false; 333 switch (short_option) { 334 case 'c': 335 attach_info.SetContinueOnceAttached(true); 336 break; 337 338 case 'p': { 339 lldb::pid_t pid = StringConvert::ToUInt32( 340 option_arg, LLDB_INVALID_PROCESS_ID, 0, &success); 341 if (!success || pid == LLDB_INVALID_PROCESS_ID) { 342 error.SetErrorStringWithFormat("invalid process ID '%s'", option_arg); 343 } else { 344 attach_info.SetProcessID(pid); 345 } 346 } break; 347 348 case 'P': 349 attach_info.SetProcessPluginName(option_arg); 350 break; 351 352 case 'n': 353 attach_info.GetExecutableFile().SetFile(option_arg, false); 354 break; 355 356 case 'w': 357 attach_info.SetWaitForLaunch(true); 358 break; 359 360 case 'i': 361 attach_info.SetIgnoreExisting(false); 362 break; 363 364 default: 365 error.SetErrorStringWithFormat("invalid short option character '%c'", 366 short_option); 367 break; 368 } 369 return error; 370 } 371 372 void OptionParsingStarting(ExecutionContext *execution_context) override { 373 attach_info.Clear(); 374 } 375 376 const OptionDefinition *GetDefinitions() override { return g_option_table; } 377 378 bool HandleOptionArgumentCompletion( 379 Args &input, int cursor_index, int char_pos, 380 OptionElementVector &opt_element_vector, int opt_element_index, 381 int match_start_point, int max_return_elements, 382 CommandInterpreter &interpreter, bool &word_complete, 383 StringList &matches) override { 384 int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos; 385 int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index; 386 387 // We are only completing the name option for now... 388 389 const OptionDefinition *opt_defs = GetDefinitions(); 390 if (opt_defs[opt_defs_index].short_option == 'n') { 391 // Are we in the name? 392 393 // Look to see if there is a -P argument provided, and if so use that 394 // plugin, otherwise 395 // use the default plugin. 396 397 const char *partial_name = nullptr; 398 partial_name = input.GetArgumentAtIndex(opt_arg_pos); 399 400 PlatformSP platform_sp(interpreter.GetPlatform(true)); 401 if (platform_sp) { 402 ProcessInstanceInfoList process_infos; 403 ProcessInstanceInfoMatch match_info; 404 if (partial_name) { 405 match_info.GetProcessInfo().GetExecutableFile().SetFile( 406 partial_name, false); 407 match_info.SetNameMatchType(eNameMatchStartsWith); 408 } 409 platform_sp->FindProcesses(match_info, process_infos); 410 const size_t num_matches = process_infos.GetSize(); 411 if (num_matches > 0) { 412 for (size_t i = 0; i < num_matches; ++i) { 413 matches.AppendString( 414 process_infos.GetProcessNameAtIndex(i), 415 process_infos.GetProcessNameLengthAtIndex(i)); 416 } 417 } 418 } 419 } 420 421 return false; 422 } 423 424 // Options table: Required for subclasses of Options. 425 426 static OptionDefinition g_option_table[]; 427 428 // Instance variables to hold the values for command options. 429 430 ProcessAttachInfo attach_info; 431 }; 432 433 CommandObjectProcessAttach(CommandInterpreter &interpreter) 434 : CommandObjectProcessLaunchOrAttach( 435 interpreter, "process attach", "Attach to a process.", 436 "process attach <cmd-options>", 0, "attach"), 437 m_options() {} 438 439 ~CommandObjectProcessAttach() override = default; 440 441 Options *GetOptions() override { return &m_options; } 442 443 protected: 444 bool DoExecute(Args &command, CommandReturnObject &result) override { 445 PlatformSP platform_sp( 446 m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform()); 447 448 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 449 // N.B. The attach should be synchronous. It doesn't help much to get the 450 // prompt back between initiating the attach 451 // and the target actually stopping. So even if the interpreter is set to 452 // be asynchronous, we wait for the stop 453 // ourselves here. 454 455 StateType state = eStateInvalid; 456 Process *process = m_exe_ctx.GetProcessPtr(); 457 458 if (!StopProcessIfNecessary(process, state, result)) 459 return false; 460 461 if (target == nullptr) { 462 // If there isn't a current target create one. 463 TargetSP new_target_sp; 464 Error error; 465 466 error = m_interpreter.GetDebugger().GetTargetList().CreateTarget( 467 m_interpreter.GetDebugger(), nullptr, nullptr, false, 468 nullptr, // No platform options 469 new_target_sp); 470 target = new_target_sp.get(); 471 if (target == nullptr || error.Fail()) { 472 result.AppendError(error.AsCString("Error creating target")); 473 return false; 474 } 475 m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target); 476 } 477 478 // Record the old executable module, we want to issue a warning if the 479 // process of attaching changed the 480 // current executable (like somebody said "file foo" then attached to a PID 481 // whose executable was bar.) 482 483 ModuleSP old_exec_module_sp = target->GetExecutableModule(); 484 ArchSpec old_arch_spec = target->GetArchitecture(); 485 486 if (command.GetArgumentCount()) { 487 result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: %s\n", 488 m_cmd_name.c_str(), m_cmd_syntax.c_str()); 489 result.SetStatus(eReturnStatusFailed); 490 return false; 491 } 492 493 m_interpreter.UpdateExecutionContext(nullptr); 494 StreamString stream; 495 const auto error = target->Attach(m_options.attach_info, &stream); 496 if (error.Success()) { 497 ProcessSP process_sp(target->GetProcessSP()); 498 if (process_sp) { 499 if (stream.GetData()) 500 result.AppendMessage(stream.GetData()); 501 result.SetStatus(eReturnStatusSuccessFinishNoResult); 502 result.SetDidChangeProcessState(true); 503 result.SetAbnormalStopWasExpected(true); 504 } else { 505 result.AppendError( 506 "no error returned from Target::Attach, and target has no process"); 507 result.SetStatus(eReturnStatusFailed); 508 } 509 } else { 510 result.AppendErrorWithFormat("attach failed: %s\n", error.AsCString()); 511 result.SetStatus(eReturnStatusFailed); 512 } 513 514 if (!result.Succeeded()) 515 return false; 516 517 // Okay, we're done. Last step is to warn if the executable module has 518 // changed: 519 char new_path[PATH_MAX]; 520 ModuleSP new_exec_module_sp(target->GetExecutableModule()); 521 if (!old_exec_module_sp) { 522 // We might not have a module if we attached to a raw pid... 523 if (new_exec_module_sp) { 524 new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX); 525 result.AppendMessageWithFormat("Executable module set to \"%s\".\n", 526 new_path); 527 } 528 } else if (old_exec_module_sp->GetFileSpec() != 529 new_exec_module_sp->GetFileSpec()) { 530 char old_path[PATH_MAX]; 531 532 old_exec_module_sp->GetFileSpec().GetPath(old_path, PATH_MAX); 533 new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX); 534 535 result.AppendWarningWithFormat( 536 "Executable module changed from \"%s\" to \"%s\".\n", old_path, 537 new_path); 538 } 539 540 if (!old_arch_spec.IsValid()) { 541 result.AppendMessageWithFormat( 542 "Architecture set to: %s.\n", 543 target->GetArchitecture().GetTriple().getTriple().c_str()); 544 } else if (!old_arch_spec.IsExactMatch(target->GetArchitecture())) { 545 result.AppendWarningWithFormat( 546 "Architecture changed from %s to %s.\n", 547 old_arch_spec.GetTriple().getTriple().c_str(), 548 target->GetArchitecture().GetTriple().getTriple().c_str()); 549 } 550 551 // This supports the use-case scenario of immediately continuing the process 552 // once attached. 553 if (m_options.attach_info.GetContinueOnceAttached()) 554 m_interpreter.HandleCommand("process continue", eLazyBoolNo, result); 555 556 return result.Succeeded(); 557 } 558 559 CommandOptions m_options; 560 }; 561 562 OptionDefinition CommandObjectProcessAttach::CommandOptions::g_option_table[] = 563 { 564 // clang-format off 565 {LLDB_OPT_SET_ALL, false, "continue", 'c', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Immediately continue the process once attached."}, 566 {LLDB_OPT_SET_ALL, false, "plugin", 'P', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, 567 {LLDB_OPT_SET_1, false, "pid", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePid, "The process ID of an existing process to attach to."}, 568 {LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeProcessName, "The name of the process to attach to."}, 569 {LLDB_OPT_SET_2, false, "include-existing", 'i', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Include existing processes when doing attach -w."}, 570 {LLDB_OPT_SET_2, false, "waitfor", 'w', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Wait for the process with <process-name> to launch."}, 571 {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr} 572 // clang-format on 573 }; 574 575 //------------------------------------------------------------------------- 576 // CommandObjectProcessContinue 577 //------------------------------------------------------------------------- 578 #pragma mark CommandObjectProcessContinue 579 580 class CommandObjectProcessContinue : public CommandObjectParsed { 581 public: 582 CommandObjectProcessContinue(CommandInterpreter &interpreter) 583 : CommandObjectParsed( 584 interpreter, "process continue", 585 "Continue execution of all threads in the current process.", 586 "process continue", 587 eCommandRequiresProcess | eCommandTryTargetAPILock | 588 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused), 589 m_options() {} 590 591 ~CommandObjectProcessContinue() override = default; 592 593 protected: 594 class CommandOptions : public Options { 595 public: 596 CommandOptions() : Options() { 597 // Keep default values of all options in one place: OptionParsingStarting 598 // () 599 OptionParsingStarting(nullptr); 600 } 601 602 ~CommandOptions() override = default; 603 604 Error SetOptionValue(uint32_t option_idx, const char *option_arg, 605 ExecutionContext *execution_context) override { 606 Error error; 607 const int short_option = m_getopt_table[option_idx].val; 608 bool success = false; 609 switch (short_option) { 610 case 'i': 611 m_ignore = StringConvert::ToUInt32(option_arg, 0, 0, &success); 612 if (!success) 613 error.SetErrorStringWithFormat( 614 "invalid value for ignore option: \"%s\", should be a number.", 615 option_arg); 616 break; 617 618 default: 619 error.SetErrorStringWithFormat("invalid short option character '%c'", 620 short_option); 621 break; 622 } 623 return error; 624 } 625 626 void OptionParsingStarting(ExecutionContext *execution_context) override { 627 m_ignore = 0; 628 } 629 630 const OptionDefinition *GetDefinitions() override { return g_option_table; } 631 632 // Options table: Required for subclasses of Options. 633 634 static OptionDefinition g_option_table[]; 635 636 uint32_t m_ignore; 637 }; 638 639 bool DoExecute(Args &command, CommandReturnObject &result) override { 640 Process *process = m_exe_ctx.GetProcessPtr(); 641 bool synchronous_execution = m_interpreter.GetSynchronous(); 642 StateType state = process->GetState(); 643 if (state == eStateStopped) { 644 if (command.GetArgumentCount() != 0) { 645 result.AppendErrorWithFormat( 646 "The '%s' command does not take any arguments.\n", 647 m_cmd_name.c_str()); 648 result.SetStatus(eReturnStatusFailed); 649 return false; 650 } 651 652 if (m_options.m_ignore > 0) { 653 ThreadSP sel_thread_sp(GetDefaultThread()->shared_from_this()); 654 if (sel_thread_sp) { 655 StopInfoSP stop_info_sp = sel_thread_sp->GetStopInfo(); 656 if (stop_info_sp && 657 stop_info_sp->GetStopReason() == eStopReasonBreakpoint) { 658 lldb::break_id_t bp_site_id = 659 (lldb::break_id_t)stop_info_sp->GetValue(); 660 BreakpointSiteSP bp_site_sp( 661 process->GetBreakpointSiteList().FindByID(bp_site_id)); 662 if (bp_site_sp) { 663 const size_t num_owners = bp_site_sp->GetNumberOfOwners(); 664 for (size_t i = 0; i < num_owners; i++) { 665 Breakpoint &bp_ref = 666 bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint(); 667 if (!bp_ref.IsInternal()) { 668 bp_ref.SetIgnoreCount(m_options.m_ignore); 669 } 670 } 671 } 672 } 673 } 674 } 675 676 { // Scope for thread list mutex: 677 std::lock_guard<std::recursive_mutex> guard( 678 process->GetThreadList().GetMutex()); 679 const uint32_t num_threads = process->GetThreadList().GetSize(); 680 681 // Set the actions that the threads should each take when resuming 682 for (uint32_t idx = 0; idx < num_threads; ++idx) { 683 const bool override_suspend = false; 684 process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState( 685 eStateRunning, override_suspend); 686 } 687 } 688 689 const uint32_t iohandler_id = process->GetIOHandlerID(); 690 691 StreamString stream; 692 Error error; 693 if (synchronous_execution) 694 error = process->ResumeSynchronous(&stream); 695 else 696 error = process->Resume(); 697 698 if (error.Success()) { 699 // There is a race condition where this thread will return up the call 700 // stack to the main command 701 // handler and show an (lldb) prompt before HandlePrivateEvent (from 702 // PrivateStateThread) has 703 // a chance to call PushProcessIOHandler(). 704 process->SyncIOHandler(iohandler_id, 2000); 705 706 result.AppendMessageWithFormat("Process %" PRIu64 " resuming\n", 707 process->GetID()); 708 if (synchronous_execution) { 709 // If any state changed events had anything to say, add that to the 710 // result 711 if (stream.GetData()) 712 result.AppendMessage(stream.GetData()); 713 714 result.SetDidChangeProcessState(true); 715 result.SetStatus(eReturnStatusSuccessFinishNoResult); 716 } else { 717 result.SetStatus(eReturnStatusSuccessContinuingNoResult); 718 } 719 } else { 720 result.AppendErrorWithFormat("Failed to resume process: %s.\n", 721 error.AsCString()); 722 result.SetStatus(eReturnStatusFailed); 723 } 724 } else { 725 result.AppendErrorWithFormat( 726 "Process cannot be continued from its current state (%s).\n", 727 StateAsCString(state)); 728 result.SetStatus(eReturnStatusFailed); 729 } 730 return result.Succeeded(); 731 } 732 733 Options *GetOptions() override { return &m_options; } 734 735 CommandOptions m_options; 736 }; 737 738 OptionDefinition 739 CommandObjectProcessContinue::CommandOptions::g_option_table[] = { 740 // clang-format off 741 {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."}, 742 {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr} 743 // clang-format on 744 }; 745 746 //------------------------------------------------------------------------- 747 // CommandObjectProcessDetach 748 //------------------------------------------------------------------------- 749 #pragma mark CommandObjectProcessDetach 750 751 class CommandObjectProcessDetach : public CommandObjectParsed { 752 public: 753 class CommandOptions : public Options { 754 public: 755 CommandOptions() : Options() { OptionParsingStarting(nullptr); } 756 757 ~CommandOptions() override = default; 758 759 Error SetOptionValue(uint32_t option_idx, const char *option_arg, 760 ExecutionContext *execution_context) override { 761 Error error; 762 const int short_option = m_getopt_table[option_idx].val; 763 auto option_strref = llvm::StringRef::withNullAsEmpty(option_arg); 764 765 switch (short_option) { 766 case 's': 767 bool tmp_result; 768 bool success; 769 tmp_result = Args::StringToBoolean(option_strref, false, &success); 770 if (!success) 771 error.SetErrorStringWithFormat("invalid boolean option: \"%s\"", 772 option_arg); 773 else { 774 if (tmp_result) 775 m_keep_stopped = eLazyBoolYes; 776 else 777 m_keep_stopped = eLazyBoolNo; 778 } 779 break; 780 default: 781 error.SetErrorStringWithFormat("invalid short option character '%c'", 782 short_option); 783 break; 784 } 785 return error; 786 } 787 788 void OptionParsingStarting(ExecutionContext *execution_context) override { 789 m_keep_stopped = eLazyBoolCalculate; 790 } 791 792 const OptionDefinition *GetDefinitions() override { return g_option_table; } 793 794 // Options table: Required for subclasses of Options. 795 796 static OptionDefinition g_option_table[]; 797 798 // Instance variables to hold the values for command options. 799 LazyBool m_keep_stopped; 800 }; 801 802 CommandObjectProcessDetach(CommandInterpreter &interpreter) 803 : CommandObjectParsed(interpreter, "process detach", 804 "Detach from the current target process.", 805 "process detach", 806 eCommandRequiresProcess | eCommandTryTargetAPILock | 807 eCommandProcessMustBeLaunched), 808 m_options() {} 809 810 ~CommandObjectProcessDetach() override = default; 811 812 Options *GetOptions() override { return &m_options; } 813 814 protected: 815 bool DoExecute(Args &command, CommandReturnObject &result) override { 816 Process *process = m_exe_ctx.GetProcessPtr(); 817 // FIXME: This will be a Command Option: 818 bool keep_stopped; 819 if (m_options.m_keep_stopped == eLazyBoolCalculate) { 820 // Check the process default: 821 keep_stopped = process->GetDetachKeepsStopped(); 822 } else if (m_options.m_keep_stopped == eLazyBoolYes) 823 keep_stopped = true; 824 else 825 keep_stopped = false; 826 827 Error error(process->Detach(keep_stopped)); 828 if (error.Success()) { 829 result.SetStatus(eReturnStatusSuccessFinishResult); 830 } else { 831 result.AppendErrorWithFormat("Detach failed: %s\n", error.AsCString()); 832 result.SetStatus(eReturnStatusFailed); 833 return false; 834 } 835 return result.Succeeded(); 836 } 837 838 CommandOptions m_options; 839 }; 840 841 OptionDefinition CommandObjectProcessDetach::CommandOptions::g_option_table[] = 842 { 843 // clang-format off 844 {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)."}, 845 {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr} 846 // clang-format on 847 }; 848 849 //------------------------------------------------------------------------- 850 // CommandObjectProcessConnect 851 //------------------------------------------------------------------------- 852 #pragma mark CommandObjectProcessConnect 853 854 class CommandObjectProcessConnect : public CommandObjectParsed { 855 public: 856 class CommandOptions : public Options { 857 public: 858 CommandOptions() : Options() { 859 // Keep default values of all options in one place: OptionParsingStarting 860 // () 861 OptionParsingStarting(nullptr); 862 } 863 864 ~CommandOptions() override = default; 865 866 Error SetOptionValue(uint32_t option_idx, const char *option_arg, 867 ExecutionContext *execution_context) override { 868 Error error; 869 const int short_option = m_getopt_table[option_idx].val; 870 871 switch (short_option) { 872 case 'p': 873 plugin_name.assign(option_arg); 874 break; 875 876 default: 877 error.SetErrorStringWithFormat("invalid short option character '%c'", 878 short_option); 879 break; 880 } 881 return error; 882 } 883 884 void OptionParsingStarting(ExecutionContext *execution_context) override { 885 plugin_name.clear(); 886 } 887 888 const OptionDefinition *GetDefinitions() override { return g_option_table; } 889 890 // Options table: Required for subclasses of Options. 891 892 static OptionDefinition g_option_table[]; 893 894 // Instance variables to hold the values for command options. 895 896 std::string plugin_name; 897 }; 898 899 CommandObjectProcessConnect(CommandInterpreter &interpreter) 900 : CommandObjectParsed(interpreter, "process connect", 901 "Connect to a remote debug service.", 902 "process connect <remote-url>", 0), 903 m_options() {} 904 905 ~CommandObjectProcessConnect() override = default; 906 907 Options *GetOptions() override { return &m_options; } 908 909 protected: 910 bool DoExecute(Args &command, CommandReturnObject &result) override { 911 if (command.GetArgumentCount() != 1) { 912 result.AppendErrorWithFormat( 913 "'%s' takes exactly one argument:\nUsage: %s\n", m_cmd_name.c_str(), 914 m_cmd_syntax.c_str()); 915 result.SetStatus(eReturnStatusFailed); 916 return false; 917 } 918 919 Process *process = m_exe_ctx.GetProcessPtr(); 920 if (process && process->IsAlive()) { 921 result.AppendErrorWithFormat( 922 "Process %" PRIu64 923 " is currently being debugged, kill the process before connecting.\n", 924 process->GetID()); 925 result.SetStatus(eReturnStatusFailed); 926 return false; 927 } 928 929 const char *plugin_name = nullptr; 930 if (!m_options.plugin_name.empty()) 931 plugin_name = m_options.plugin_name.c_str(); 932 933 Error error; 934 Debugger &debugger = m_interpreter.GetDebugger(); 935 PlatformSP platform_sp = m_interpreter.GetPlatform(true); 936 ProcessSP process_sp = platform_sp->ConnectProcess( 937 command.GetArgumentAtIndex(0), plugin_name, debugger, 938 debugger.GetSelectedTarget().get(), error); 939 if (error.Fail() || process_sp == nullptr) { 940 result.AppendError(error.AsCString("Error connecting to the process")); 941 result.SetStatus(eReturnStatusFailed); 942 return false; 943 } 944 return true; 945 } 946 947 CommandOptions m_options; 948 }; 949 950 OptionDefinition CommandObjectProcessConnect::CommandOptions::g_option_table[] = 951 { 952 // clang-format off 953 {LLDB_OPT_SET_ALL, false, "plugin", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, 954 {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr} 955 // clang-format on 956 }; 957 958 //------------------------------------------------------------------------- 959 // CommandObjectProcessPlugin 960 //------------------------------------------------------------------------- 961 #pragma mark CommandObjectProcessPlugin 962 963 class CommandObjectProcessPlugin : public CommandObjectProxy { 964 public: 965 CommandObjectProcessPlugin(CommandInterpreter &interpreter) 966 : CommandObjectProxy( 967 interpreter, "process plugin", 968 "Send a custom command to the current target process plug-in.", 969 "process plugin <args>", 0) {} 970 971 ~CommandObjectProcessPlugin() override = default; 972 973 CommandObject *GetProxyCommandObject() override { 974 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); 975 if (process) 976 return process->GetPluginCommandObject(); 977 return nullptr; 978 } 979 }; 980 981 //------------------------------------------------------------------------- 982 // CommandObjectProcessLoad 983 //------------------------------------------------------------------------- 984 #pragma mark CommandObjectProcessLoad 985 986 class CommandObjectProcessLoad : public CommandObjectParsed { 987 public: 988 class CommandOptions : public Options { 989 public: 990 CommandOptions() : Options() { 991 // Keep default values of all options in one place: OptionParsingStarting 992 // () 993 OptionParsingStarting(nullptr); 994 } 995 996 ~CommandOptions() override = default; 997 998 Error SetOptionValue(uint32_t option_idx, const char *option_arg, 999 ExecutionContext *execution_context) override { 1000 Error error; 1001 const int short_option = m_getopt_table[option_idx].val; 1002 switch (short_option) { 1003 case 'i': 1004 do_install = true; 1005 if (option_arg && option_arg[0]) 1006 install_path.SetFile(option_arg, false); 1007 break; 1008 default: 1009 error.SetErrorStringWithFormat("invalid short option character '%c'", 1010 short_option); 1011 break; 1012 } 1013 return error; 1014 } 1015 1016 void OptionParsingStarting(ExecutionContext *execution_context) override { 1017 do_install = false; 1018 install_path.Clear(); 1019 } 1020 1021 const OptionDefinition *GetDefinitions() override { return g_option_table; } 1022 1023 // Options table: Required for subclasses of Options. 1024 static OptionDefinition g_option_table[]; 1025 1026 // Instance variables to hold the values for command options. 1027 bool do_install; 1028 FileSpec install_path; 1029 }; 1030 1031 CommandObjectProcessLoad(CommandInterpreter &interpreter) 1032 : CommandObjectParsed(interpreter, "process load", 1033 "Load a shared library into the current process.", 1034 "process load <filename> [<filename> ...]", 1035 eCommandRequiresProcess | eCommandTryTargetAPILock | 1036 eCommandProcessMustBeLaunched | 1037 eCommandProcessMustBePaused), 1038 m_options() {} 1039 1040 ~CommandObjectProcessLoad() override = default; 1041 1042 Options *GetOptions() override { return &m_options; } 1043 1044 protected: 1045 bool DoExecute(Args &command, CommandReturnObject &result) override { 1046 Process *process = m_exe_ctx.GetProcessPtr(); 1047 1048 const size_t argc = command.GetArgumentCount(); 1049 for (uint32_t i = 0; i < argc; ++i) { 1050 Error error; 1051 PlatformSP platform = process->GetTarget().GetPlatform(); 1052 const char *image_path = command.GetArgumentAtIndex(i); 1053 uint32_t image_token = LLDB_INVALID_IMAGE_TOKEN; 1054 1055 if (!m_options.do_install) { 1056 FileSpec image_spec(image_path, false); 1057 platform->ResolveRemotePath(image_spec, image_spec); 1058 image_token = 1059 platform->LoadImage(process, FileSpec(), image_spec, error); 1060 } else if (m_options.install_path) { 1061 FileSpec image_spec(image_path, true); 1062 platform->ResolveRemotePath(m_options.install_path, 1063 m_options.install_path); 1064 image_token = platform->LoadImage(process, image_spec, 1065 m_options.install_path, error); 1066 } else { 1067 FileSpec image_spec(image_path, true); 1068 image_token = 1069 platform->LoadImage(process, image_spec, FileSpec(), error); 1070 } 1071 1072 if (image_token != LLDB_INVALID_IMAGE_TOKEN) { 1073 result.AppendMessageWithFormat( 1074 "Loading \"%s\"...ok\nImage %u loaded.\n", image_path, image_token); 1075 result.SetStatus(eReturnStatusSuccessFinishResult); 1076 } else { 1077 result.AppendErrorWithFormat("failed to load '%s': %s", image_path, 1078 error.AsCString()); 1079 result.SetStatus(eReturnStatusFailed); 1080 } 1081 } 1082 return result.Succeeded(); 1083 } 1084 1085 CommandOptions m_options; 1086 }; 1087 1088 OptionDefinition CommandObjectProcessLoad::CommandOptions::g_option_table[] = { 1089 // clang-format off 1090 {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."}, 1091 {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr} 1092 // clang-format on 1093 }; 1094 1095 //------------------------------------------------------------------------- 1096 // CommandObjectProcessUnload 1097 //------------------------------------------------------------------------- 1098 #pragma mark CommandObjectProcessUnload 1099 1100 class CommandObjectProcessUnload : public CommandObjectParsed { 1101 public: 1102 CommandObjectProcessUnload(CommandInterpreter &interpreter) 1103 : CommandObjectParsed( 1104 interpreter, "process unload", 1105 "Unload a shared library from the current process using the index " 1106 "returned by a previous call to \"process load\".", 1107 "process unload <index>", 1108 eCommandRequiresProcess | eCommandTryTargetAPILock | 1109 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {} 1110 1111 ~CommandObjectProcessUnload() override = default; 1112 1113 protected: 1114 bool DoExecute(Args &command, CommandReturnObject &result) override { 1115 Process *process = m_exe_ctx.GetProcessPtr(); 1116 1117 const size_t argc = command.GetArgumentCount(); 1118 1119 for (uint32_t i = 0; i < argc; ++i) { 1120 const char *image_token_cstr = command.GetArgumentAtIndex(i); 1121 uint32_t image_token = StringConvert::ToUInt32( 1122 image_token_cstr, LLDB_INVALID_IMAGE_TOKEN, 0); 1123 if (image_token == LLDB_INVALID_IMAGE_TOKEN) { 1124 result.AppendErrorWithFormat("invalid image index argument '%s'", 1125 image_token_cstr); 1126 result.SetStatus(eReturnStatusFailed); 1127 break; 1128 } else { 1129 Error error(process->GetTarget().GetPlatform()->UnloadImage( 1130 process, image_token)); 1131 if (error.Success()) { 1132 result.AppendMessageWithFormat( 1133 "Unloading shared library with index %u...ok\n", image_token); 1134 result.SetStatus(eReturnStatusSuccessFinishResult); 1135 } else { 1136 result.AppendErrorWithFormat("failed to unload image: %s", 1137 error.AsCString()); 1138 result.SetStatus(eReturnStatusFailed); 1139 break; 1140 } 1141 } 1142 } 1143 return result.Succeeded(); 1144 } 1145 }; 1146 1147 //------------------------------------------------------------------------- 1148 // CommandObjectProcessSignal 1149 //------------------------------------------------------------------------- 1150 #pragma mark CommandObjectProcessSignal 1151 1152 class CommandObjectProcessSignal : public CommandObjectParsed { 1153 public: 1154 CommandObjectProcessSignal(CommandInterpreter &interpreter) 1155 : CommandObjectParsed(interpreter, "process signal", 1156 "Send a UNIX signal to the current target process.", 1157 nullptr, eCommandRequiresProcess | 1158 eCommandTryTargetAPILock) { 1159 CommandArgumentEntry arg; 1160 CommandArgumentData signal_arg; 1161 1162 // Define the first (and only) variant of this arg. 1163 signal_arg.arg_type = eArgTypeUnixSignal; 1164 signal_arg.arg_repetition = eArgRepeatPlain; 1165 1166 // There is only one variant this argument could be; put it into the 1167 // argument entry. 1168 arg.push_back(signal_arg); 1169 1170 // Push the data for the first argument into the m_arguments vector. 1171 m_arguments.push_back(arg); 1172 } 1173 1174 ~CommandObjectProcessSignal() override = default; 1175 1176 protected: 1177 bool DoExecute(Args &command, CommandReturnObject &result) override { 1178 Process *process = m_exe_ctx.GetProcessPtr(); 1179 1180 if (command.GetArgumentCount() == 1) { 1181 int signo = LLDB_INVALID_SIGNAL_NUMBER; 1182 1183 const char *signal_name = command.GetArgumentAtIndex(0); 1184 if (::isxdigit(signal_name[0])) 1185 signo = 1186 StringConvert::ToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0); 1187 else 1188 signo = process->GetUnixSignals()->GetSignalNumberFromName(signal_name); 1189 1190 if (signo == LLDB_INVALID_SIGNAL_NUMBER) { 1191 result.AppendErrorWithFormat("Invalid signal argument '%s'.\n", 1192 command.GetArgumentAtIndex(0)); 1193 result.SetStatus(eReturnStatusFailed); 1194 } else { 1195 Error error(process->Signal(signo)); 1196 if (error.Success()) { 1197 result.SetStatus(eReturnStatusSuccessFinishResult); 1198 } else { 1199 result.AppendErrorWithFormat("Failed to send signal %i: %s\n", signo, 1200 error.AsCString()); 1201 result.SetStatus(eReturnStatusFailed); 1202 } 1203 } 1204 } else { 1205 result.AppendErrorWithFormat( 1206 "'%s' takes exactly one signal number argument:\nUsage: %s\n", 1207 m_cmd_name.c_str(), m_cmd_syntax.c_str()); 1208 result.SetStatus(eReturnStatusFailed); 1209 } 1210 return result.Succeeded(); 1211 } 1212 }; 1213 1214 //------------------------------------------------------------------------- 1215 // CommandObjectProcessInterrupt 1216 //------------------------------------------------------------------------- 1217 #pragma mark CommandObjectProcessInterrupt 1218 1219 class CommandObjectProcessInterrupt : public CommandObjectParsed { 1220 public: 1221 CommandObjectProcessInterrupt(CommandInterpreter &interpreter) 1222 : CommandObjectParsed(interpreter, "process interrupt", 1223 "Interrupt the current target process.", 1224 "process interrupt", 1225 eCommandRequiresProcess | eCommandTryTargetAPILock | 1226 eCommandProcessMustBeLaunched) {} 1227 1228 ~CommandObjectProcessInterrupt() override = default; 1229 1230 protected: 1231 bool DoExecute(Args &command, CommandReturnObject &result) override { 1232 Process *process = m_exe_ctx.GetProcessPtr(); 1233 if (process == nullptr) { 1234 result.AppendError("no process to halt"); 1235 result.SetStatus(eReturnStatusFailed); 1236 return false; 1237 } 1238 1239 if (command.GetArgumentCount() == 0) { 1240 bool clear_thread_plans = true; 1241 Error error(process->Halt(clear_thread_plans)); 1242 if (error.Success()) { 1243 result.SetStatus(eReturnStatusSuccessFinishResult); 1244 } else { 1245 result.AppendErrorWithFormat("Failed to halt process: %s\n", 1246 error.AsCString()); 1247 result.SetStatus(eReturnStatusFailed); 1248 } 1249 } else { 1250 result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n", 1251 m_cmd_name.c_str(), m_cmd_syntax.c_str()); 1252 result.SetStatus(eReturnStatusFailed); 1253 } 1254 return result.Succeeded(); 1255 } 1256 }; 1257 1258 //------------------------------------------------------------------------- 1259 // CommandObjectProcessKill 1260 //------------------------------------------------------------------------- 1261 #pragma mark CommandObjectProcessKill 1262 1263 class CommandObjectProcessKill : public CommandObjectParsed { 1264 public: 1265 CommandObjectProcessKill(CommandInterpreter &interpreter) 1266 : CommandObjectParsed(interpreter, "process kill", 1267 "Terminate the current target process.", 1268 "process kill", 1269 eCommandRequiresProcess | eCommandTryTargetAPILock | 1270 eCommandProcessMustBeLaunched) {} 1271 1272 ~CommandObjectProcessKill() override = default; 1273 1274 protected: 1275 bool DoExecute(Args &command, CommandReturnObject &result) override { 1276 Process *process = m_exe_ctx.GetProcessPtr(); 1277 if (process == nullptr) { 1278 result.AppendError("no process to kill"); 1279 result.SetStatus(eReturnStatusFailed); 1280 return false; 1281 } 1282 1283 if (command.GetArgumentCount() == 0) { 1284 Error error(process->Destroy(true)); 1285 if (error.Success()) { 1286 result.SetStatus(eReturnStatusSuccessFinishResult); 1287 } else { 1288 result.AppendErrorWithFormat("Failed to kill process: %s\n", 1289 error.AsCString()); 1290 result.SetStatus(eReturnStatusFailed); 1291 } 1292 } else { 1293 result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n", 1294 m_cmd_name.c_str(), m_cmd_syntax.c_str()); 1295 result.SetStatus(eReturnStatusFailed); 1296 } 1297 return result.Succeeded(); 1298 } 1299 }; 1300 1301 //------------------------------------------------------------------------- 1302 // CommandObjectProcessSaveCore 1303 //------------------------------------------------------------------------- 1304 #pragma mark CommandObjectProcessSaveCore 1305 1306 class CommandObjectProcessSaveCore : public CommandObjectParsed { 1307 public: 1308 CommandObjectProcessSaveCore(CommandInterpreter &interpreter) 1309 : CommandObjectParsed(interpreter, "process save-core", 1310 "Save the current process as a core file using an " 1311 "appropriate file type.", 1312 "process save-core FILE", 1313 eCommandRequiresProcess | eCommandTryTargetAPILock | 1314 eCommandProcessMustBeLaunched) {} 1315 1316 ~CommandObjectProcessSaveCore() override = default; 1317 1318 protected: 1319 bool DoExecute(Args &command, CommandReturnObject &result) override { 1320 ProcessSP process_sp = m_exe_ctx.GetProcessSP(); 1321 if (process_sp) { 1322 if (command.GetArgumentCount() == 1) { 1323 FileSpec output_file(command.GetArgumentAtIndex(0), false); 1324 Error error = PluginManager::SaveCore(process_sp, output_file); 1325 if (error.Success()) { 1326 result.SetStatus(eReturnStatusSuccessFinishResult); 1327 } else { 1328 result.AppendErrorWithFormat( 1329 "Failed to save core file for process: %s\n", error.AsCString()); 1330 result.SetStatus(eReturnStatusFailed); 1331 } 1332 } else { 1333 result.AppendErrorWithFormat("'%s' takes one arguments:\nUsage: %s\n", 1334 m_cmd_name.c_str(), m_cmd_syntax.c_str()); 1335 result.SetStatus(eReturnStatusFailed); 1336 } 1337 } else { 1338 result.AppendError("invalid process"); 1339 result.SetStatus(eReturnStatusFailed); 1340 return false; 1341 } 1342 1343 return result.Succeeded(); 1344 } 1345 }; 1346 1347 //------------------------------------------------------------------------- 1348 // CommandObjectProcessStatus 1349 //------------------------------------------------------------------------- 1350 #pragma mark CommandObjectProcessStatus 1351 1352 class CommandObjectProcessStatus : public CommandObjectParsed { 1353 public: 1354 CommandObjectProcessStatus(CommandInterpreter &interpreter) 1355 : CommandObjectParsed( 1356 interpreter, "process status", 1357 "Show status and stop location for the current target process.", 1358 "process status", 1359 eCommandRequiresProcess | eCommandTryTargetAPILock) {} 1360 1361 ~CommandObjectProcessStatus() override = default; 1362 1363 bool DoExecute(Args &command, CommandReturnObject &result) override { 1364 Stream &strm = result.GetOutputStream(); 1365 result.SetStatus(eReturnStatusSuccessFinishNoResult); 1366 // No need to check "process" for validity as eCommandRequiresProcess 1367 // ensures it is valid 1368 Process *process = m_exe_ctx.GetProcessPtr(); 1369 const bool only_threads_with_stop_reason = true; 1370 const uint32_t start_frame = 0; 1371 const uint32_t num_frames = 1; 1372 const uint32_t num_frames_with_source = 1; 1373 process->GetStatus(strm); 1374 process->GetThreadStatus(strm, only_threads_with_stop_reason, start_frame, 1375 num_frames, num_frames_with_source); 1376 return result.Succeeded(); 1377 } 1378 }; 1379 1380 //------------------------------------------------------------------------- 1381 // CommandObjectProcessHandle 1382 //------------------------------------------------------------------------- 1383 #pragma mark CommandObjectProcessHandle 1384 1385 class CommandObjectProcessHandle : public CommandObjectParsed { 1386 public: 1387 class CommandOptions : public Options { 1388 public: 1389 CommandOptions() : Options() { OptionParsingStarting(nullptr); } 1390 1391 ~CommandOptions() override = default; 1392 1393 Error SetOptionValue(uint32_t option_idx, const char *option_arg, 1394 ExecutionContext *execution_context) override { 1395 Error error; 1396 const int short_option = m_getopt_table[option_idx].val; 1397 1398 switch (short_option) { 1399 case 's': 1400 stop = option_arg; 1401 break; 1402 case 'n': 1403 notify = option_arg; 1404 break; 1405 case 'p': 1406 pass = option_arg; 1407 break; 1408 default: 1409 error.SetErrorStringWithFormat("invalid short option character '%c'", 1410 short_option); 1411 break; 1412 } 1413 return error; 1414 } 1415 1416 void OptionParsingStarting(ExecutionContext *execution_context) override { 1417 stop.clear(); 1418 notify.clear(); 1419 pass.clear(); 1420 } 1421 1422 const OptionDefinition *GetDefinitions() override { return g_option_table; } 1423 1424 // Options table: Required for subclasses of Options. 1425 1426 static OptionDefinition g_option_table[]; 1427 1428 // Instance variables to hold the values for command options. 1429 1430 std::string stop; 1431 std::string notify; 1432 std::string pass; 1433 }; 1434 1435 CommandObjectProcessHandle(CommandInterpreter &interpreter) 1436 : CommandObjectParsed(interpreter, "process handle", 1437 "Manage LLDB handling of OS signals for the " 1438 "current target process. Defaults to showing " 1439 "current policy.", 1440 nullptr), 1441 m_options() { 1442 SetHelpLong("\nIf no signals are specified, update them all. If no update " 1443 "option is specified, list the current values."); 1444 CommandArgumentEntry arg; 1445 CommandArgumentData signal_arg; 1446 1447 signal_arg.arg_type = eArgTypeUnixSignal; 1448 signal_arg.arg_repetition = eArgRepeatStar; 1449 1450 arg.push_back(signal_arg); 1451 1452 m_arguments.push_back(arg); 1453 } 1454 1455 ~CommandObjectProcessHandle() override = default; 1456 1457 Options *GetOptions() override { return &m_options; } 1458 1459 bool VerifyCommandOptionValue(const std::string &option, int &real_value) { 1460 bool okay = true; 1461 bool success = false; 1462 bool tmp_value = Args::StringToBoolean(option, false, &success); 1463 1464 if (success && tmp_value) 1465 real_value = 1; 1466 else if (success && !tmp_value) 1467 real_value = 0; 1468 else { 1469 // If the value isn't 'true' or 'false', it had better be 0 or 1. 1470 real_value = StringConvert::ToUInt32(option.c_str(), 3); 1471 if (real_value != 0 && real_value != 1) 1472 okay = false; 1473 } 1474 1475 return okay; 1476 } 1477 1478 void PrintSignalHeader(Stream &str) { 1479 str.Printf("NAME PASS STOP NOTIFY\n"); 1480 str.Printf("=========== ===== ===== ======\n"); 1481 } 1482 1483 void PrintSignal(Stream &str, int32_t signo, const char *sig_name, 1484 const UnixSignalsSP &signals_sp) { 1485 bool stop; 1486 bool suppress; 1487 bool notify; 1488 1489 str.Printf("%-11s ", sig_name); 1490 if (signals_sp->GetSignalInfo(signo, suppress, stop, notify)) { 1491 bool pass = !suppress; 1492 str.Printf("%s %s %s", (pass ? "true " : "false"), 1493 (stop ? "true " : "false"), (notify ? "true " : "false")); 1494 } 1495 str.Printf("\n"); 1496 } 1497 1498 void PrintSignalInformation(Stream &str, Args &signal_args, 1499 int num_valid_signals, 1500 const UnixSignalsSP &signals_sp) { 1501 PrintSignalHeader(str); 1502 1503 if (num_valid_signals > 0) { 1504 size_t num_args = signal_args.GetArgumentCount(); 1505 for (size_t i = 0; i < num_args; ++i) { 1506 int32_t signo = signals_sp->GetSignalNumberFromName( 1507 signal_args.GetArgumentAtIndex(i)); 1508 if (signo != LLDB_INVALID_SIGNAL_NUMBER) 1509 PrintSignal(str, signo, signal_args.GetArgumentAtIndex(i), 1510 signals_sp); 1511 } 1512 } else // Print info for ALL signals 1513 { 1514 int32_t signo = signals_sp->GetFirstSignalNumber(); 1515 while (signo != LLDB_INVALID_SIGNAL_NUMBER) { 1516 PrintSignal(str, signo, signals_sp->GetSignalAsCString(signo), 1517 signals_sp); 1518 signo = signals_sp->GetNextSignalNumber(signo); 1519 } 1520 } 1521 } 1522 1523 protected: 1524 bool DoExecute(Args &signal_args, CommandReturnObject &result) override { 1525 TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget(); 1526 1527 if (!target_sp) { 1528 result.AppendError("No current target;" 1529 " cannot handle signals until you have a valid target " 1530 "and process.\n"); 1531 result.SetStatus(eReturnStatusFailed); 1532 return false; 1533 } 1534 1535 ProcessSP process_sp = target_sp->GetProcessSP(); 1536 1537 if (!process_sp) { 1538 result.AppendError("No current process; cannot handle signals until you " 1539 "have a valid process.\n"); 1540 result.SetStatus(eReturnStatusFailed); 1541 return false; 1542 } 1543 1544 int stop_action = -1; // -1 means leave the current setting alone 1545 int pass_action = -1; // -1 means leave the current setting alone 1546 int notify_action = -1; // -1 means leave the current setting alone 1547 1548 if (!m_options.stop.empty() && 1549 !VerifyCommandOptionValue(m_options.stop, stop_action)) { 1550 result.AppendError("Invalid argument for command option --stop; must be " 1551 "true or false.\n"); 1552 result.SetStatus(eReturnStatusFailed); 1553 return false; 1554 } 1555 1556 if (!m_options.notify.empty() && 1557 !VerifyCommandOptionValue(m_options.notify, notify_action)) { 1558 result.AppendError("Invalid argument for command option --notify; must " 1559 "be true or false.\n"); 1560 result.SetStatus(eReturnStatusFailed); 1561 return false; 1562 } 1563 1564 if (!m_options.pass.empty() && 1565 !VerifyCommandOptionValue(m_options.pass, pass_action)) { 1566 result.AppendError("Invalid argument for command option --pass; must be " 1567 "true or false.\n"); 1568 result.SetStatus(eReturnStatusFailed); 1569 return false; 1570 } 1571 1572 size_t num_args = signal_args.GetArgumentCount(); 1573 UnixSignalsSP signals_sp = process_sp->GetUnixSignals(); 1574 int num_signals_set = 0; 1575 1576 if (num_args > 0) { 1577 for (size_t i = 0; i < num_args; ++i) { 1578 int32_t signo = signals_sp->GetSignalNumberFromName( 1579 signal_args.GetArgumentAtIndex(i)); 1580 if (signo != LLDB_INVALID_SIGNAL_NUMBER) { 1581 // Casting the actions as bools here should be okay, because 1582 // VerifyCommandOptionValue guarantees 1583 // the value is either 0 or 1. 1584 if (stop_action != -1) 1585 signals_sp->SetShouldStop(signo, stop_action); 1586 if (pass_action != -1) { 1587 bool suppress = !pass_action; 1588 signals_sp->SetShouldSuppress(signo, suppress); 1589 } 1590 if (notify_action != -1) 1591 signals_sp->SetShouldNotify(signo, notify_action); 1592 ++num_signals_set; 1593 } else { 1594 result.AppendErrorWithFormat("Invalid signal name '%s'\n", 1595 signal_args.GetArgumentAtIndex(i)); 1596 } 1597 } 1598 } else { 1599 // No signal specified, if any command options were specified, update ALL 1600 // signals. 1601 if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1)) { 1602 if (m_interpreter.Confirm( 1603 "Do you really want to update all the signals?", false)) { 1604 int32_t signo = signals_sp->GetFirstSignalNumber(); 1605 while (signo != LLDB_INVALID_SIGNAL_NUMBER) { 1606 if (notify_action != -1) 1607 signals_sp->SetShouldNotify(signo, notify_action); 1608 if (stop_action != -1) 1609 signals_sp->SetShouldStop(signo, stop_action); 1610 if (pass_action != -1) { 1611 bool suppress = !pass_action; 1612 signals_sp->SetShouldSuppress(signo, suppress); 1613 } 1614 signo = signals_sp->GetNextSignalNumber(signo); 1615 } 1616 } 1617 } 1618 } 1619 1620 PrintSignalInformation(result.GetOutputStream(), signal_args, 1621 num_signals_set, signals_sp); 1622 1623 if (num_signals_set > 0) 1624 result.SetStatus(eReturnStatusSuccessFinishNoResult); 1625 else 1626 result.SetStatus(eReturnStatusFailed); 1627 1628 return result.Succeeded(); 1629 } 1630 1631 CommandOptions m_options; 1632 }; 1633 1634 OptionDefinition CommandObjectProcessHandle::CommandOptions::g_option_table[] = 1635 { 1636 // clang-format off 1637 {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."}, 1638 {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."}, 1639 {LLDB_OPT_SET_1, false, "pass", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process."}, 1640 {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr} 1641 // clang-format on 1642 }; 1643 1644 //------------------------------------------------------------------------- 1645 // CommandObjectMultiwordProcess 1646 //------------------------------------------------------------------------- 1647 1648 CommandObjectMultiwordProcess::CommandObjectMultiwordProcess( 1649 CommandInterpreter &interpreter) 1650 : CommandObjectMultiword( 1651 interpreter, "process", 1652 "Commands for interacting with processes on the current platform.", 1653 "process <subcommand> [<subcommand-options>]") { 1654 LoadSubCommand("attach", 1655 CommandObjectSP(new CommandObjectProcessAttach(interpreter))); 1656 LoadSubCommand("launch", 1657 CommandObjectSP(new CommandObjectProcessLaunch(interpreter))); 1658 LoadSubCommand("continue", CommandObjectSP(new CommandObjectProcessContinue( 1659 interpreter))); 1660 LoadSubCommand("connect", 1661 CommandObjectSP(new CommandObjectProcessConnect(interpreter))); 1662 LoadSubCommand("detach", 1663 CommandObjectSP(new CommandObjectProcessDetach(interpreter))); 1664 LoadSubCommand("load", 1665 CommandObjectSP(new CommandObjectProcessLoad(interpreter))); 1666 LoadSubCommand("unload", 1667 CommandObjectSP(new CommandObjectProcessUnload(interpreter))); 1668 LoadSubCommand("signal", 1669 CommandObjectSP(new CommandObjectProcessSignal(interpreter))); 1670 LoadSubCommand("handle", 1671 CommandObjectSP(new CommandObjectProcessHandle(interpreter))); 1672 LoadSubCommand("status", 1673 CommandObjectSP(new CommandObjectProcessStatus(interpreter))); 1674 LoadSubCommand("interrupt", CommandObjectSP(new CommandObjectProcessInterrupt( 1675 interpreter))); 1676 LoadSubCommand("kill", 1677 CommandObjectSP(new CommandObjectProcessKill(interpreter))); 1678 LoadSubCommand("plugin", 1679 CommandObjectSP(new CommandObjectProcessPlugin(interpreter))); 1680 LoadSubCommand("save-core", CommandObjectSP(new CommandObjectProcessSaveCore( 1681 interpreter))); 1682 } 1683 1684 CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess() = default; 1685