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