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/SBCommandInterpreter.h" 13 #include "lldb/API/SBCommandReturnObject.h" 14 #include "lldb/API/SBDebugger.h" 15 #include "lldb/API/SBHostOS.h" 16 #include "lldb/API/SBLanguageRuntime.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 static 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 = NULL; 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 m_option_data() { 108 // We want to be able to handle CTRL+D in the terminal to have it terminate 109 // certain input 110 m_debugger.SetCloseInputOnEOF(false); 111 g_driver = this; 112 } 113 114 Driver::~Driver() { g_driver = NULL; } 115 116 void Driver::OptionData::AddLocalLLDBInit() { 117 // If there is a local .lldbinit, add that to the list of things to be 118 // sourced, if the settings permit it. 119 SBFileSpec local_lldbinit(".lldbinit", true); 120 SBFileSpec homedir_dot_lldb = SBHostOS::GetUserHomeDirectory(); 121 homedir_dot_lldb.AppendPathComponent(".lldbinit"); 122 123 // Only read .lldbinit in the current working directory if it's not the same 124 // as the .lldbinit in the home directory (which is already being read in). 125 if (local_lldbinit.Exists() && strcmp(local_lldbinit.GetDirectory(), 126 homedir_dot_lldb.GetDirectory()) != 0) { 127 char path[PATH_MAX]; 128 local_lldbinit.GetPath(path, sizeof(path)); 129 InitialCmdEntry entry(path, true, true, true); 130 m_after_file_commands.push_back(entry); 131 } 132 } 133 134 void Driver::OptionData::AddInitialCommand(std::string command, 135 CommandPlacement placement, 136 bool is_file, SBError &error) { 137 std::vector<InitialCmdEntry> *command_set; 138 switch (placement) { 139 case eCommandPlacementBeforeFile: 140 command_set = &(m_initial_commands); 141 break; 142 case eCommandPlacementAfterFile: 143 command_set = &(m_after_file_commands); 144 break; 145 case eCommandPlacementAfterCrash: 146 command_set = &(m_after_crash_commands); 147 break; 148 } 149 150 if (is_file) { 151 SBFileSpec file(command.c_str()); 152 if (file.Exists()) 153 command_set->push_back(InitialCmdEntry(command, is_file, false)); 154 else if (file.ResolveExecutableLocation()) { 155 char final_path[PATH_MAX]; 156 file.GetPath(final_path, sizeof(final_path)); 157 command_set->push_back(InitialCmdEntry(final_path, is_file, false)); 158 } else 159 error.SetErrorStringWithFormat( 160 "file specified in --source (-s) option doesn't exist: '%s'", 161 command.c_str()); 162 } else 163 command_set->push_back(InitialCmdEntry(command, is_file, false)); 164 } 165 166 const char *Driver::GetFilename() const { 167 if (m_option_data.m_args.empty()) 168 return NULL; 169 return m_option_data.m_args.front().c_str(); 170 } 171 172 const char *Driver::GetCrashLogFilename() const { 173 if (m_option_data.m_crash_log.empty()) 174 return NULL; 175 return m_option_data.m_crash_log.c_str(); 176 } 177 178 lldb::ScriptLanguage Driver::GetScriptLanguage() const { 179 return m_option_data.m_script_lang; 180 } 181 182 void Driver::WriteCommandsForSourcing(CommandPlacement placement, 183 SBStream &strm) { 184 std::vector<OptionData::InitialCmdEntry> *command_set; 185 switch (placement) { 186 case eCommandPlacementBeforeFile: 187 command_set = &m_option_data.m_initial_commands; 188 break; 189 case eCommandPlacementAfterFile: 190 command_set = &m_option_data.m_after_file_commands; 191 break; 192 case eCommandPlacementAfterCrash: 193 command_set = &m_option_data.m_after_crash_commands; 194 break; 195 } 196 197 for (const auto &command_entry : *command_set) { 198 const char *command = command_entry.contents.c_str(); 199 if (command_entry.is_file) { 200 // If this command_entry is a file to be sourced, and it's the ./.lldbinit 201 // file (the .lldbinit 202 // file in the current working directory), only read it if 203 // target.load-cwd-lldbinit is 'true'. 204 if (command_entry.is_cwd_lldbinit_file_read) { 205 SBStringList strlist = m_debugger.GetInternalVariableValue( 206 "target.load-cwd-lldbinit", m_debugger.GetInstanceName()); 207 if (strlist.GetSize() == 1 && 208 strcmp(strlist.GetStringAtIndex(0), "warn") == 0) { 209 FILE *output = m_debugger.GetOutputFileHandle(); 210 ::fprintf( 211 output, 212 "There is a .lldbinit file in the current directory which is not " 213 "being read.\n" 214 "To silence this warning without sourcing in the local " 215 ".lldbinit,\n" 216 "add the following to the lldbinit file in your home directory:\n" 217 " settings set target.load-cwd-lldbinit false\n" 218 "To allow lldb to source .lldbinit files in the current working " 219 "directory,\n" 220 "set the value of this variable to true. Only do so if you " 221 "understand and\n" 222 "accept the security risk.\n"); 223 return; 224 } 225 if (strlist.GetSize() == 1 && 226 strcmp(strlist.GetStringAtIndex(0), "false") == 0) { 227 return; 228 } 229 } 230 bool source_quietly = 231 m_option_data.m_source_quietly || command_entry.source_quietly; 232 strm.Printf("command source -s %i '%s'\n", 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.push_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.push_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 (!m_debugger.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.push_back(value); 443 } 444 } else if (args.getLastArgNoClaim()) { 445 WithColor::warning() << "program arguments are ignored when attaching.\n"; 446 } 447 448 if (m_option_data.m_print_version) { 449 llvm::outs() << m_debugger.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 = NULL; 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) { 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, NULL); 573 #endif 574 ::setbuf(stdout, NULL); 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) && 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 (m_debugger.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 = NULL; 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 && error_cstr[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 && commands_size) { 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) { 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) { 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) && 775 ::ioctl(STDIN_FILENO, TIOCGWINSZ, &window_size) == 0) { 776 if ((window_size.ws_col > 0) && g_driver != NULL) { 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) { 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) 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) 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, MAC; 878 ArrayRef<const char *> arg_arr = makeArrayRef(argv + 1, argc - 1); 879 opt::InputArgList input_args = T.ParseArgs(arg_arr, MAI, MAC); 880 881 if (input_args.hasArg(OPT_help)) { 882 printHelp(T, ToolName); 883 return 0; 884 } 885 886 for (auto *arg : input_args.filtered(OPT_UNKNOWN)) { 887 WithColor::warning() << "ignoring unknown option: " << arg->getSpelling() 888 << '\n'; 889 } 890 891 SBInitializerOptions options; 892 893 if (auto *arg = input_args.getLastArg(OPT_capture)) { 894 auto arg_value = arg->getValue(); 895 options.SetReproducerPath(arg_value); 896 options.SetCaptureReproducer(true); 897 } 898 899 if (auto *arg = input_args.getLastArg(OPT_replay)) { 900 auto arg_value = arg->getValue(); 901 options.SetReplayReproducer(true); 902 options.SetReproducerPath(arg_value); 903 } 904 905 SBError error = SBDebugger::Initialize(options); 906 if (error.Fail()) { 907 WithColor::error() << "initialization failed: " << error.GetCString() 908 << '\n'; 909 return 1; 910 } 911 912 SBHostOS::ThreadCreated("<lldb.driver.main-thread>"); 913 914 signal(SIGINT, sigint_handler); 915 #if !defined(_MSC_VER) 916 signal(SIGPIPE, SIG_IGN); 917 signal(SIGWINCH, sigwinch_handler); 918 signal(SIGTSTP, sigtstp_handler); 919 signal(SIGCONT, sigcont_handler); 920 #endif 921 922 int exit_code = 0; 923 // Create a scope for driver so that the driver object will destroy itself 924 // before SBDebugger::Terminate() is called. 925 { 926 Driver driver; 927 928 bool exiting = false; 929 SBError error(driver.ProcessArgs(input_args, exiting)); 930 if (error.Fail()) { 931 exit_code = 1; 932 if (const char *error_cstr = error.GetCString()) 933 WithColor::error() << error_cstr << '\n'; 934 } else if (!exiting) { 935 exit_code = driver.MainLoop(); 936 } 937 } 938 939 SBDebugger::Terminate(); 940 return exit_code; 941 } 942