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