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