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