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