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