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