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