1 //===-- Driver.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 "Driver.h" 11 12 #include "lldb/API/SBBreakpoint.h" 13 #include "lldb/API/SBCommandInterpreter.h" 14 #include "lldb/API/SBCommandReturnObject.h" 15 #include "lldb/API/SBCommunication.h" 16 #include "lldb/API/SBDebugger.h" 17 #include "lldb/API/SBEvent.h" 18 #include "lldb/API/SBHostOS.h" 19 #include "lldb/API/SBLanguageRuntime.h" 20 #include "lldb/API/SBListener.h" 21 #include "lldb/API/SBProcess.h" 22 #include "lldb/API/SBStream.h" 23 #include "lldb/API/SBStringList.h" 24 #include "lldb/API/SBTarget.h" 25 #include "lldb/API/SBThread.h" 26 27 #include "llvm/ADT/StringRef.h" 28 #include "llvm/Support/ConvertUTF.h" 29 #include "llvm/Support/Format.h" 30 #include "llvm/Support/Path.h" 31 #include "llvm/Support/PrettyStackTrace.h" 32 #include "llvm/Support/Signals.h" 33 #include "llvm/Support/WithColor.h" 34 #include "llvm/Support/raw_ostream.h" 35 36 #include <algorithm> 37 #include <atomic> 38 #include <bitset> 39 #include <csignal> 40 #include <string> 41 #include <thread> 42 #include <utility> 43 44 #include <fcntl.h> 45 #include <limits.h> 46 #include <stdio.h> 47 #include <stdlib.h> 48 #include <string.h> 49 50 // Includes for pipe() 51 #if defined(_WIN32) 52 #include <fcntl.h> 53 #include <io.h> 54 #else 55 #include <unistd.h> 56 #endif 57 58 #if !defined(__APPLE__) 59 #include "llvm/Support/DataTypes.h" 60 #endif 61 62 using namespace lldb; 63 using namespace llvm; 64 65 namespace { 66 enum ID { 67 OPT_INVALID = 0, // This is not an option ID. 68 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ 69 HELPTEXT, METAVAR, VALUES) \ 70 OPT_##ID, 71 #include "Options.inc" 72 #undef OPTION 73 }; 74 75 #define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE; 76 #include "Options.inc" 77 #undef PREFIX 78 79 static const opt::OptTable::Info InfoTable[] = { 80 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ 81 HELPTEXT, METAVAR, VALUES) \ 82 { \ 83 PREFIX, NAME, HELPTEXT, \ 84 METAVAR, OPT_##ID, opt::Option::KIND##Class, \ 85 PARAM, FLAGS, OPT_##GROUP, \ 86 OPT_##ALIAS, ALIASARGS, VALUES}, 87 #include "Options.inc" 88 #undef OPTION 89 }; 90 91 class LLDBOptTable : public opt::OptTable { 92 public: 93 LLDBOptTable() : OptTable(InfoTable) {} 94 }; 95 } // namespace 96 97 static void reset_stdin_termios(); 98 static bool g_old_stdin_termios_is_valid = false; 99 static struct termios g_old_stdin_termios; 100 101 static Driver *g_driver = NULL; 102 103 // In the Driver::MainLoop, we change the terminal settings. This function is 104 // added as an atexit handler to make sure we clean them up. 105 static void reset_stdin_termios() { 106 if (g_old_stdin_termios_is_valid) { 107 g_old_stdin_termios_is_valid = false; 108 ::tcsetattr(STDIN_FILENO, TCSANOW, &g_old_stdin_termios); 109 } 110 } 111 112 Driver::Driver() 113 : SBBroadcaster("Driver"), m_debugger(SBDebugger::Create(false)), 114 m_option_data() { 115 // We want to be able to handle CTRL+D in the terminal to have it terminate 116 // certain input 117 m_debugger.SetCloseInputOnEOF(false); 118 g_driver = this; 119 } 120 121 Driver::~Driver() { g_driver = NULL; } 122 123 void Driver::OptionData::AddLocalLLDBInit() { 124 // If there is a local .lldbinit, add that to the list of things to be 125 // sourced, if the settings permit it. 126 SBFileSpec local_lldbinit(".lldbinit", true); 127 SBFileSpec homedir_dot_lldb = SBHostOS::GetUserHomeDirectory(); 128 homedir_dot_lldb.AppendPathComponent(".lldbinit"); 129 130 // Only read .lldbinit in the current working directory if it's not the same 131 // as the .lldbinit in the home directory (which is already being read in). 132 if (local_lldbinit.Exists() && strcmp(local_lldbinit.GetDirectory(), 133 homedir_dot_lldb.GetDirectory()) != 0) { 134 char path[PATH_MAX]; 135 local_lldbinit.GetPath(path, sizeof(path)); 136 InitialCmdEntry entry(path, true, true, true); 137 m_after_file_commands.push_back(entry); 138 } 139 } 140 141 void Driver::OptionData::AddInitialCommand(std::string command, 142 CommandPlacement placement, 143 bool is_file, SBError &error) { 144 std::vector<InitialCmdEntry> *command_set; 145 switch (placement) { 146 case eCommandPlacementBeforeFile: 147 command_set = &(m_initial_commands); 148 break; 149 case eCommandPlacementAfterFile: 150 command_set = &(m_after_file_commands); 151 break; 152 case eCommandPlacementAfterCrash: 153 command_set = &(m_after_crash_commands); 154 break; 155 } 156 157 if (is_file) { 158 SBFileSpec file(command.c_str()); 159 if (file.Exists()) 160 command_set->push_back(InitialCmdEntry(command, is_file, false)); 161 else if (file.ResolveExecutableLocation()) { 162 char final_path[PATH_MAX]; 163 file.GetPath(final_path, sizeof(final_path)); 164 command_set->push_back(InitialCmdEntry(final_path, is_file, false)); 165 } else 166 error.SetErrorStringWithFormat( 167 "file specified in --source (-s) option doesn't exist: '%s'", 168 command.c_str()); 169 } else 170 command_set->push_back(InitialCmdEntry(command, is_file, false)); 171 } 172 173 const char *Driver::GetFilename() const { 174 if (m_option_data.m_args.empty()) 175 return NULL; 176 return m_option_data.m_args.front().c_str(); 177 } 178 179 const char *Driver::GetCrashLogFilename() const { 180 if (m_option_data.m_crash_log.empty()) 181 return NULL; 182 return m_option_data.m_crash_log.c_str(); 183 } 184 185 lldb::ScriptLanguage Driver::GetScriptLanguage() const { 186 return m_option_data.m_script_lang; 187 } 188 189 void Driver::WriteCommandsForSourcing(CommandPlacement placement, 190 SBStream &strm) { 191 std::vector<OptionData::InitialCmdEntry> *command_set; 192 switch (placement) { 193 case eCommandPlacementBeforeFile: 194 command_set = &m_option_data.m_initial_commands; 195 break; 196 case eCommandPlacementAfterFile: 197 command_set = &m_option_data.m_after_file_commands; 198 break; 199 case eCommandPlacementAfterCrash: 200 command_set = &m_option_data.m_after_crash_commands; 201 break; 202 } 203 204 for (const auto &command_entry : *command_set) { 205 const char *command = command_entry.contents.c_str(); 206 if (command_entry.is_file) { 207 // If this command_entry is a file to be sourced, and it's the ./.lldbinit 208 // file (the .lldbinit 209 // file in the current working directory), only read it if 210 // target.load-cwd-lldbinit is 'true'. 211 if (command_entry.is_cwd_lldbinit_file_read) { 212 SBStringList strlist = m_debugger.GetInternalVariableValue( 213 "target.load-cwd-lldbinit", m_debugger.GetInstanceName()); 214 if (strlist.GetSize() == 1 && 215 strcmp(strlist.GetStringAtIndex(0), "warn") == 0) { 216 FILE *output = m_debugger.GetOutputFileHandle(); 217 ::fprintf( 218 output, 219 "There is a .lldbinit file in the current directory which is not " 220 "being read.\n" 221 "To silence this warning without sourcing in the local " 222 ".lldbinit,\n" 223 "add the following to the lldbinit file in your home directory:\n" 224 " settings set target.load-cwd-lldbinit false\n" 225 "To allow lldb to source .lldbinit files in the current working " 226 "directory,\n" 227 "set the value of this variable to true. Only do so if you " 228 "understand and\n" 229 "accept the security risk.\n"); 230 return; 231 } 232 if (strlist.GetSize() == 1 && 233 strcmp(strlist.GetStringAtIndex(0), "false") == 0) { 234 return; 235 } 236 } 237 bool source_quietly = 238 m_option_data.m_source_quietly || command_entry.source_quietly; 239 strm.Printf("command source -s %i '%s'\n", source_quietly, command); 240 } else 241 strm.Printf("%s\n", command); 242 } 243 } 244 245 bool Driver::GetDebugMode() const { return m_option_data.m_debug_mode; } 246 247 // Check the arguments that were passed to this program to make sure they are 248 // valid and to get their argument values (if any). Return a boolean value 249 // indicating whether or not to start up the full debugger (i.e. the Command 250 // Interpreter) or not. Return FALSE if the arguments were invalid OR if the 251 // user only wanted help or version information. 252 SBError Driver::ProcessArgs(const opt::InputArgList &args, bool &exiting) { 253 SBError error; 254 m_option_data.AddLocalLLDBInit(); 255 256 // This is kind of a pain, but since we make the debugger in the Driver's 257 // constructor, we can't know at that point whether we should read in init 258 // files yet. So we don't read them in in the Driver constructor, then set 259 // the flags back to "read them in" here, and then if we see the "-n" flag, 260 // we'll turn it off again. Finally we have to read them in by hand later in 261 // the main loop. 262 m_debugger.SkipLLDBInitFiles(false); 263 m_debugger.SkipAppInitFiles(false); 264 265 if (args.hasArg(OPT_version)) { 266 m_option_data.m_print_version = true; 267 } 268 269 if (args.hasArg(OPT_python_path)) { 270 m_option_data.m_print_python_path = true; 271 } 272 273 if (args.hasArg(OPT_batch)) { 274 m_option_data.m_batch = true; 275 } 276 277 if (auto *arg = args.getLastArg(OPT_core)) { 278 auto arg_value = arg->getValue(); 279 SBFileSpec file(arg_value); 280 if (!file.Exists()) { 281 error.SetErrorStringWithFormat( 282 "file specified in --core (-c) option doesn't exist: '%s'", 283 arg_value); 284 return error; 285 } 286 m_option_data.m_core_file = arg_value; 287 } 288 289 if (args.hasArg(OPT_editor)) { 290 m_option_data.m_use_external_editor = true; 291 } 292 293 if (args.hasArg(OPT_no_lldbinit)) { 294 m_debugger.SkipLLDBInitFiles(true); 295 m_debugger.SkipAppInitFiles(true); 296 } 297 298 if (args.hasArg(OPT_no_use_colors)) { 299 m_debugger.SetUseColor(false); 300 } 301 302 if (auto *arg = args.getLastArg(OPT_file)) { 303 auto arg_value = arg->getValue(); 304 SBFileSpec file(arg_value); 305 if (file.Exists()) { 306 m_option_data.m_args.push_back(arg_value); 307 } else if (file.ResolveExecutableLocation()) { 308 char path[PATH_MAX]; 309 file.GetPath(path, sizeof(path)); 310 m_option_data.m_args.push_back(path); 311 } else { 312 error.SetErrorStringWithFormat( 313 "file specified in --file (-f) option doesn't exist: '%s'", 314 arg_value); 315 return error; 316 } 317 } 318 319 if (auto *arg = args.getLastArg(OPT_arch)) { 320 auto arg_value = arg->getValue(); 321 if (!m_debugger.SetDefaultArchitecture(arg_value)) { 322 error.SetErrorStringWithFormat( 323 "invalid architecture in the -a or --arch option: '%s'", arg_value); 324 return error; 325 } 326 } 327 328 if (auto *arg = args.getLastArg(OPT_script_language)) { 329 auto arg_value = arg->getValue(); 330 m_option_data.m_script_lang = m_debugger.GetScriptingLanguage(arg_value); 331 } 332 333 if (args.hasArg(OPT_no_use_colors)) { 334 m_option_data.m_debug_mode = true; 335 } 336 337 if (args.hasArg(OPT_no_use_colors)) { 338 m_debugger.SetUseColor(false); 339 } 340 341 if (args.hasArg(OPT_source_quietly)) { 342 m_option_data.m_source_quietly = true; 343 } 344 345 if (auto *arg = args.getLastArg(OPT_attach_name)) { 346 auto arg_value = arg->getValue(); 347 m_option_data.m_process_name = arg_value; 348 } 349 350 if (args.hasArg(OPT_wait_for)) { 351 m_option_data.m_wait_for = true; 352 } 353 354 if (auto *arg = args.getLastArg(OPT_attach_pid)) { 355 auto arg_value = arg->getValue(); 356 char *remainder; 357 m_option_data.m_process_pid = strtol(arg_value, &remainder, 0); 358 if (remainder == arg_value || *remainder != '\0') { 359 error.SetErrorStringWithFormat( 360 "Could not convert process PID: \"%s\" into a pid.", arg_value); 361 return error; 362 } 363 } 364 365 if (auto *arg = args.getLastArg(OPT_repl_language)) { 366 auto arg_value = arg->getValue(); 367 m_option_data.m_repl_lang = 368 SBLanguageRuntime::GetLanguageTypeFromString(arg_value); 369 if (m_option_data.m_repl_lang == eLanguageTypeUnknown) { 370 error.SetErrorStringWithFormat("Unrecognized language name: \"%s\"", 371 arg_value); 372 return error; 373 } 374 } 375 376 if (args.hasArg(OPT_repl)) { 377 m_option_data.m_repl = true; 378 } 379 380 if (auto *arg = args.getLastArg(OPT_repl_)) { 381 m_option_data.m_repl = true; 382 if (auto arg_value = arg->getValue()) 383 m_option_data.m_repl_options = arg_value; 384 } 385 386 // We need to process the options below together as their relative order 387 // matters. 388 for (auto *arg : args.filtered(OPT_source_on_crash, OPT_one_line_on_crash, 389 OPT_source, OPT_source_before_file, 390 OPT_one_line, OPT_one_line_before_file)) { 391 auto arg_value = arg->getValue(); 392 if (arg->getOption().matches(OPT_source_on_crash)) { 393 m_option_data.AddInitialCommand(arg_value, eCommandPlacementAfterCrash, 394 true, error); 395 if (error.Fail()) 396 return error; 397 } 398 399 if (arg->getOption().matches(OPT_one_line_on_crash)) { 400 m_option_data.AddInitialCommand(arg_value, eCommandPlacementAfterCrash, 401 false, error); 402 if (error.Fail()) 403 return error; 404 } 405 406 if (arg->getOption().matches(OPT_source)) { 407 m_option_data.AddInitialCommand(arg_value, eCommandPlacementAfterFile, 408 true, error); 409 if (error.Fail()) 410 return error; 411 } 412 413 if (arg->getOption().matches(OPT_source_before_file)) { 414 m_option_data.AddInitialCommand(arg_value, eCommandPlacementBeforeFile, 415 true, error); 416 if (error.Fail()) 417 return error; 418 } 419 420 if (arg->getOption().matches(OPT_one_line)) { 421 m_option_data.AddInitialCommand(arg_value, eCommandPlacementAfterFile, 422 false, error); 423 if (error.Fail()) 424 return error; 425 } 426 427 if (arg->getOption().matches(OPT_one_line_before_file)) { 428 m_option_data.AddInitialCommand(arg_value, eCommandPlacementBeforeFile, 429 false, error); 430 if (error.Fail()) 431 return error; 432 } 433 } 434 435 if (m_option_data.m_process_name.empty() && 436 m_option_data.m_process_pid == LLDB_INVALID_PROCESS_ID) { 437 438 // If the option data args array is empty that means the file was not 439 // specified with -f and we need to get it from the input args. 440 if (m_option_data.m_args.empty()) { 441 if (auto *arg = args.getLastArgNoClaim(OPT_INPUT)) { 442 m_option_data.m_args.push_back(arg->getAsString((args))); 443 } 444 } 445 446 // Any argument following -- is an argument for the inferior. 447 if (auto *arg = args.getLastArgNoClaim(OPT_REM)) { 448 for (auto value : arg->getValues()) 449 m_option_data.m_args.push_back(value); 450 } 451 } else if (args.getLastArgNoClaim()) { 452 WithColor::warning() << "program arguments are ignored when attaching.\n"; 453 } 454 455 if (m_option_data.m_print_version) { 456 llvm::outs() << m_debugger.GetVersionString() << '\n'; 457 exiting = true; 458 return error; 459 } 460 461 if (m_option_data.m_print_python_path) { 462 SBFileSpec python_file_spec = SBHostOS::GetLLDBPythonPath(); 463 if (python_file_spec.IsValid()) { 464 char python_path[PATH_MAX]; 465 size_t num_chars = python_file_spec.GetPath(python_path, PATH_MAX); 466 if (num_chars < PATH_MAX) { 467 llvm::outs() << python_path << '\n'; 468 } else 469 llvm::outs() << "<PATH TOO LONG>\n"; 470 } else 471 llvm::outs() << "<COULD NOT FIND PATH>\n"; 472 exiting = true; 473 return error; 474 } 475 476 return error; 477 } 478 479 static ::FILE *PrepareCommandsForSourcing(const char *commands_data, 480 size_t commands_size, int fds[2]) { 481 enum PIPES { READ, WRITE }; // Constants 0 and 1 for READ and WRITE 482 483 ::FILE *commands_file = NULL; 484 fds[0] = -1; 485 fds[1] = -1; 486 int err = 0; 487 #ifdef _WIN32 488 err = _pipe(fds, commands_size, O_BINARY); 489 #else 490 err = pipe(fds); 491 #endif 492 if (err == 0) { 493 ssize_t nrwr = write(fds[WRITE], commands_data, commands_size); 494 if (nrwr < 0) { 495 WithColor::error() 496 << format( 497 "write(%i, %p, %" PRIu64 498 ") failed (errno = %i) when trying to open LLDB commands pipe", 499 fds[WRITE], static_cast<const void *>(commands_data), 500 static_cast<uint64_t>(commands_size), errno) 501 << '\n'; 502 } else if (static_cast<size_t>(nrwr) == commands_size) { 503 // Close the write end of the pipe so when we give the read end to 504 // the debugger/command interpreter it will exit when it consumes all 505 // of the data 506 #ifdef _WIN32 507 _close(fds[WRITE]); 508 fds[WRITE] = -1; 509 #else 510 close(fds[WRITE]); 511 fds[WRITE] = -1; 512 #endif 513 // Now open the read file descriptor in a FILE * that we can give to 514 // the debugger as an input handle 515 commands_file = fdopen(fds[READ], "r"); 516 if (commands_file) { 517 fds[READ] = -1; // The FILE * 'commands_file' now owns the read 518 // descriptor Hand ownership if the FILE * over to the 519 // debugger for "commands_file". 520 } else { 521 WithColor::error() << format("fdopen(%i, \"r\") failed (errno = %i) " 522 "when trying to open LLDB commands pipe", 523 fds[READ], errno) 524 << '\n'; 525 } 526 } 527 } else { 528 WithColor::error() 529 << "can't create pipe file descriptors for LLDB commands\n"; 530 } 531 532 return commands_file; 533 } 534 535 void CleanupAfterCommandSourcing(int fds[2]) { 536 enum PIPES { READ, WRITE }; // Constants 0 and 1 for READ and WRITE 537 538 // Close any pipes that we still have ownership of 539 if (fds[WRITE] != -1) { 540 #ifdef _WIN32 541 _close(fds[WRITE]); 542 fds[WRITE] = -1; 543 #else 544 close(fds[WRITE]); 545 fds[WRITE] = -1; 546 #endif 547 } 548 549 if (fds[READ] != -1) { 550 #ifdef _WIN32 551 _close(fds[READ]); 552 fds[READ] = -1; 553 #else 554 close(fds[READ]); 555 fds[READ] = -1; 556 #endif 557 } 558 } 559 560 std::string EscapeString(std::string arg) { 561 std::string::size_type pos = 0; 562 while ((pos = arg.find_first_of("\"\\", pos)) != std::string::npos) { 563 arg.insert(pos, 1, '\\'); 564 pos += 2; 565 } 566 return '"' + arg + '"'; 567 } 568 569 int Driver::MainLoop() { 570 if (::tcgetattr(STDIN_FILENO, &g_old_stdin_termios) == 0) { 571 g_old_stdin_termios_is_valid = true; 572 atexit(reset_stdin_termios); 573 } 574 575 #ifndef _MSC_VER 576 // Disabling stdin buffering with MSVC's 2015 CRT exposes a bug in fgets 577 // which causes it to miss newlines depending on whether there have been an 578 // odd or even number of characters. Bug has been reported to MS via Connect. 579 ::setbuf(stdin, NULL); 580 #endif 581 ::setbuf(stdout, NULL); 582 583 m_debugger.SetErrorFileHandle(stderr, false); 584 m_debugger.SetOutputFileHandle(stdout, false); 585 m_debugger.SetInputFileHandle(stdin, 586 false); // Don't take ownership of STDIN yet... 587 588 m_debugger.SetUseExternalEditor(m_option_data.m_use_external_editor); 589 590 struct winsize window_size; 591 if (isatty(STDIN_FILENO) && 592 ::ioctl(STDIN_FILENO, TIOCGWINSZ, &window_size) == 0) { 593 if (window_size.ws_col > 0) 594 m_debugger.SetTerminalWidth(window_size.ws_col); 595 } 596 597 SBCommandInterpreter sb_interpreter = m_debugger.GetCommandInterpreter(); 598 599 // Before we handle any options from the command line, we parse the 600 // .lldbinit file in the user's home directory. 601 SBCommandReturnObject result; 602 sb_interpreter.SourceInitFileInHomeDirectory(result); 603 if (GetDebugMode()) { 604 result.PutError(m_debugger.GetErrorFileHandle()); 605 result.PutOutput(m_debugger.GetOutputFileHandle()); 606 } 607 608 // We allow the user to specify an exit code when calling quit which we will 609 // return when exiting. 610 m_debugger.GetCommandInterpreter().AllowExitCodeOnQuit(true); 611 612 // Now we handle options we got from the command line 613 SBStream commands_stream; 614 615 // First source in the commands specified to be run before the file arguments 616 // are processed. 617 WriteCommandsForSourcing(eCommandPlacementBeforeFile, commands_stream); 618 619 const size_t num_args = m_option_data.m_args.size(); 620 if (num_args > 0) { 621 char arch_name[64]; 622 if (m_debugger.GetDefaultArchitecture(arch_name, sizeof(arch_name))) 623 commands_stream.Printf("target create --arch=%s %s", arch_name, 624 EscapeString(m_option_data.m_args[0]).c_str()); 625 else 626 commands_stream.Printf("target create %s", 627 EscapeString(m_option_data.m_args[0]).c_str()); 628 629 if (!m_option_data.m_core_file.empty()) { 630 commands_stream.Printf(" --core %s", 631 EscapeString(m_option_data.m_core_file).c_str()); 632 } 633 commands_stream.Printf("\n"); 634 635 if (num_args > 1) { 636 commands_stream.Printf("settings set -- target.run-args "); 637 for (size_t arg_idx = 1; arg_idx < num_args; ++arg_idx) 638 commands_stream.Printf( 639 " %s", EscapeString(m_option_data.m_args[arg_idx]).c_str()); 640 commands_stream.Printf("\n"); 641 } 642 } else if (!m_option_data.m_core_file.empty()) { 643 commands_stream.Printf("target create --core %s\n", 644 EscapeString(m_option_data.m_core_file).c_str()); 645 } else if (!m_option_data.m_process_name.empty()) { 646 commands_stream.Printf("process attach --name %s", 647 EscapeString(m_option_data.m_process_name).c_str()); 648 649 if (m_option_data.m_wait_for) 650 commands_stream.Printf(" --waitfor"); 651 652 commands_stream.Printf("\n"); 653 654 } else if (LLDB_INVALID_PROCESS_ID != m_option_data.m_process_pid) { 655 commands_stream.Printf("process attach --pid %" PRIu64 "\n", 656 m_option_data.m_process_pid); 657 } 658 659 WriteCommandsForSourcing(eCommandPlacementAfterFile, commands_stream); 660 661 if (GetDebugMode()) { 662 result.PutError(m_debugger.GetErrorFileHandle()); 663 result.PutOutput(m_debugger.GetOutputFileHandle()); 664 } 665 666 bool handle_events = true; 667 bool spawn_thread = false; 668 669 if (m_option_data.m_repl) { 670 const char *repl_options = NULL; 671 if (!m_option_data.m_repl_options.empty()) 672 repl_options = m_option_data.m_repl_options.c_str(); 673 SBError error(m_debugger.RunREPL(m_option_data.m_repl_lang, repl_options)); 674 if (error.Fail()) { 675 const char *error_cstr = error.GetCString(); 676 if (error_cstr && error_cstr[0]) 677 WithColor::error() << error_cstr << '\n'; 678 else 679 WithColor::error() << error.GetError() << '\n'; 680 } 681 } else { 682 // Check if we have any data in the commands stream, and if so, save it to a 683 // temp file 684 // so we can then run the command interpreter using the file contents. 685 const char *commands_data = commands_stream.GetData(); 686 const size_t commands_size = commands_stream.GetSize(); 687 688 // The command file might have requested that we quit, this variable will 689 // track that. 690 bool quit_requested = false; 691 bool stopped_for_crash = false; 692 if (commands_data && commands_size) { 693 int initial_commands_fds[2]; 694 bool success = true; 695 FILE *commands_file = PrepareCommandsForSourcing( 696 commands_data, commands_size, initial_commands_fds); 697 if (commands_file) { 698 m_debugger.SetInputFileHandle(commands_file, true); 699 700 // Set the debugger into Sync mode when running the command file. 701 // Otherwise command files 702 // that run the target won't run in a sensible way. 703 bool old_async = m_debugger.GetAsync(); 704 m_debugger.SetAsync(false); 705 int num_errors; 706 707 SBCommandInterpreterRunOptions options; 708 options.SetStopOnError(true); 709 if (m_option_data.m_batch) 710 options.SetStopOnCrash(true); 711 712 m_debugger.RunCommandInterpreter(handle_events, spawn_thread, options, 713 num_errors, quit_requested, 714 stopped_for_crash); 715 716 if (m_option_data.m_batch && stopped_for_crash && 717 !m_option_data.m_after_crash_commands.empty()) { 718 int crash_command_fds[2]; 719 SBStream crash_commands_stream; 720 WriteCommandsForSourcing(eCommandPlacementAfterCrash, 721 crash_commands_stream); 722 const char *crash_commands_data = crash_commands_stream.GetData(); 723 const size_t crash_commands_size = crash_commands_stream.GetSize(); 724 commands_file = PrepareCommandsForSourcing( 725 crash_commands_data, crash_commands_size, crash_command_fds); 726 if (commands_file) { 727 bool local_quit_requested; 728 bool local_stopped_for_crash; 729 m_debugger.SetInputFileHandle(commands_file, true); 730 731 m_debugger.RunCommandInterpreter( 732 handle_events, spawn_thread, options, num_errors, 733 local_quit_requested, local_stopped_for_crash); 734 if (local_quit_requested) 735 quit_requested = true; 736 } 737 } 738 m_debugger.SetAsync(old_async); 739 } else 740 success = false; 741 742 // Close any pipes that we still have ownership of 743 CleanupAfterCommandSourcing(initial_commands_fds); 744 745 // Something went wrong with command pipe 746 if (!success) { 747 exit(1); 748 } 749 } 750 751 // Now set the input file handle to STDIN and run the command 752 // interpreter again in interactive mode and let the debugger 753 // take ownership of stdin 754 755 bool go_interactive = true; 756 if (quit_requested) 757 go_interactive = false; 758 else if (m_option_data.m_batch && !stopped_for_crash) 759 go_interactive = false; 760 761 if (go_interactive) { 762 m_debugger.SetInputFileHandle(stdin, true); 763 m_debugger.RunCommandInterpreter(handle_events, spawn_thread); 764 } 765 } 766 767 reset_stdin_termios(); 768 fclose(stdin); 769 770 int exit_code = sb_interpreter.GetQuitStatus(); 771 SBDebugger::Destroy(m_debugger); 772 return exit_code; 773 } 774 775 void Driver::ResizeWindow(unsigned short col) { 776 GetDebugger().SetTerminalWidth(col); 777 } 778 779 void sigwinch_handler(int signo) { 780 struct winsize window_size; 781 if (isatty(STDIN_FILENO) && 782 ::ioctl(STDIN_FILENO, TIOCGWINSZ, &window_size) == 0) { 783 if ((window_size.ws_col > 0) && g_driver != NULL) { 784 g_driver->ResizeWindow(window_size.ws_col); 785 } 786 } 787 } 788 789 void sigint_handler(int signo) { 790 static std::atomic_flag g_interrupt_sent = ATOMIC_FLAG_INIT; 791 if (g_driver) { 792 if (!g_interrupt_sent.test_and_set()) { 793 g_driver->GetDebugger().DispatchInputInterrupt(); 794 g_interrupt_sent.clear(); 795 return; 796 } 797 } 798 799 _exit(signo); 800 } 801 802 void sigtstp_handler(int signo) { 803 if (g_driver) 804 g_driver->GetDebugger().SaveInputTerminalState(); 805 806 signal(signo, SIG_DFL); 807 kill(getpid(), signo); 808 signal(signo, sigtstp_handler); 809 } 810 811 void sigcont_handler(int signo) { 812 if (g_driver) 813 g_driver->GetDebugger().RestoreInputTerminalState(); 814 815 signal(signo, SIG_DFL); 816 kill(getpid(), signo); 817 signal(signo, sigcont_handler); 818 } 819 820 static void printHelp(LLDBOptTable &table, llvm::StringRef tool_name) { 821 std::string usage_str = tool_name.str() + "options"; 822 table.PrintHelp(llvm::outs(), usage_str.c_str(), "LLDB", false); 823 824 std::string examples = R"___( 825 EXAMPLES: 826 The debugger can be started in several modes. 827 828 Passing an executable as a positional argument prepares lldb to debug the 829 given executable. Arguments passed after -- are considered arguments to the 830 debugged executable. 831 832 lldb --arch x86_64 /path/to/program -- --arch arvm7 833 834 Passing one of the attach options causes lldb to immediately attach to the 835 given process. 836 837 lldb -p <pid> 838 lldb -n <process-name> 839 840 Passing --repl starts lldb in REPL mode. 841 842 lldb -r 843 844 Passing --core causes lldb to debug the core file. 845 846 lldb -c /path/to/core 847 848 Command options can be combined with either mode and cause lldb to run the 849 specified commands before or after events, like loading the file or crashing, 850 in the order provided on the command line. 851 852 lldb -O 'settings set stop-disassembly-count 20' -o 'run' -o 'bt' 853 lldb -S /source/before/file -s /source/after/file 854 lldb -K /source/before/crash -k /source/after/crash 855 )___"; 856 llvm::outs() << examples; 857 } 858 859 int 860 #ifdef _MSC_VER 861 wmain(int argc, wchar_t const *wargv[]) 862 #else 863 main(int argc, char const *argv[]) 864 #endif 865 { 866 #ifdef _MSC_VER 867 // Convert wide arguments to UTF-8 868 std::vector<std::string> argvStrings(argc); 869 std::vector<const char *> argvPointers(argc); 870 for (int i = 0; i != argc; ++i) { 871 llvm::convertWideToUTF8(wargv[i], argvStrings[i]); 872 argvPointers[i] = argvStrings[i].c_str(); 873 } 874 const char **argv = argvPointers.data(); 875 #endif 876 877 // Print stack trace on crash. 878 llvm::StringRef ToolName = llvm::sys::path::filename(argv[0]); 879 llvm::sys::PrintStackTraceOnErrorSignal(ToolName); 880 llvm::PrettyStackTraceProgram X(argc, argv); 881 882 // Parse arguments. 883 LLDBOptTable T; 884 unsigned MAI, MAC; 885 ArrayRef<const char *> arg_arr = makeArrayRef(argv + 1, argc - 1); 886 opt::InputArgList input_args = T.ParseArgs(arg_arr, MAI, MAC); 887 888 if (input_args.hasArg(OPT_help)) { 889 printHelp(T, ToolName); 890 return 0; 891 } 892 893 for (auto *arg : input_args.filtered(OPT_UNKNOWN)) { 894 WithColor::warning() << "ignoring unknown option: " << arg->getSpelling() 895 << '\n'; 896 } 897 898 SBInitializerOptions options; 899 900 if (auto *arg = input_args.getLastArg(OPT_capture)) { 901 auto arg_value = arg->getValue(); 902 options.SetReproducerPath(arg_value); 903 options.SetCaptureReproducer(true); 904 } 905 906 if (auto *arg = input_args.getLastArg(OPT_replay)) { 907 auto arg_value = arg->getValue(); 908 options.SetReplayReproducer(true); 909 options.SetReproducerPath(arg_value); 910 } 911 912 SBError error = SBDebugger::Initialize(options); 913 if (error.Fail()) { 914 WithColor::error() << "initialization failed: " << error.GetCString() 915 << '\n'; 916 return 1; 917 } 918 919 SBHostOS::ThreadCreated("<lldb.driver.main-thread>"); 920 921 signal(SIGINT, sigint_handler); 922 #if !defined(_MSC_VER) 923 signal(SIGPIPE, SIG_IGN); 924 signal(SIGWINCH, sigwinch_handler); 925 signal(SIGTSTP, sigtstp_handler); 926 signal(SIGCONT, sigcont_handler); 927 #endif 928 929 int exit_code = 0; 930 // Create a scope for driver so that the driver object will destroy itself 931 // before SBDebugger::Terminate() is called. 932 { 933 Driver driver; 934 935 bool exiting = false; 936 SBError error(driver.ProcessArgs(input_args, exiting)); 937 if (error.Fail()) { 938 exit_code = 1; 939 if (const char *error_cstr = error.GetCString()) 940 WithColor::error() << error_cstr << '\n'; 941 } else if (!exiting) { 942 exit_code = driver.MainLoop(); 943 } 944 } 945 946 SBDebugger::Terminate(); 947 return exit_code; 948 } 949