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