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