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