1 //===-- Driver.cpp ----------------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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"
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"
43 // Includes for pipe()
51 #if !defined(__APPLE__)
52 #include "llvm/Support/DataTypes.h"
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) \
64 #include "Options.inc"
68 #define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
69 #include "Options.inc"
72 const opt::OptTable::Info InfoTable[] = {
73 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
74 HELPTEXT, METAVAR, VALUES) \
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"
84 class LLDBOptTable : public opt::OptTable {
86 LLDBOptTable() : OptTable(InfoTable) {}
90 static void reset_stdin_termios();
91 static bool g_old_stdin_termios_is_valid = false;
92 static struct termios g_old_stdin_termios;
94 static Driver *g_driver = nullptr;
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);
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
109 m_debugger.SetCloseInputOnEOF(false);
113 Driver::~Driver() { g_driver = nullptr; }
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");
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) {
127 local_lldbinit.GetPath(path, sizeof(path));
128 InitialCmdEntry entry(path, true, true, true);
129 m_after_file_commands.push_back(entry);
133 void Driver::OptionData::AddInitialCommand(std::string command,
134 CommandPlacement placement,
135 bool is_file, SBError &error) {
136 std::vector<InitialCmdEntry> *command_set;
138 case eCommandPlacementBeforeFile:
139 command_set = &(m_initial_commands);
141 case eCommandPlacementAfterFile:
142 command_set = &(m_after_file_commands);
144 case eCommandPlacementAfterCrash:
145 command_set = &(m_after_crash_commands);
150 SBFileSpec file(command.c_str());
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));
158 error.SetErrorStringWithFormat(
159 "file specified in --source (-s) option doesn't exist: '%s'",
162 command_set->push_back(InitialCmdEntry(command, is_file, false));
165 const char *Driver::GetFilename() const {
166 if (m_option_data.m_args.empty())
168 return m_option_data.m_args.front().c_str();
171 const char *Driver::GetCrashLogFilename() const {
172 if (m_option_data.m_crash_log.empty())
174 return m_option_data.m_crash_log.c_str();
177 lldb::ScriptLanguage Driver::GetScriptLanguage() const {
178 return m_option_data.m_script_lang;
181 void Driver::WriteCommandsForSourcing(CommandPlacement placement,
183 std::vector<OptionData::InitialCmdEntry> *command_set;
185 case eCommandPlacementBeforeFile:
186 command_set = &m_option_data.m_initial_commands;
188 case eCommandPlacementAfterFile:
189 command_set = &m_option_data.m_after_file_commands;
191 case eCommandPlacementAfterCrash:
192 command_set = &m_option_data.m_after_crash_commands;
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();
211 "There is a .lldbinit file in the current directory which is not "
213 "To silence this warning without sourcing in the local "
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 "
219 "set the value of this variable to true. Only do so if you "
221 "accept the security risk.\n");
224 if (strlist.GetSize() == 1 &&
225 strcmp(strlist.GetStringAtIndex(0), "false") == 0) {
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);
234 strm.Printf("%s\n", command);
238 bool Driver::GetDebugMode() const { return m_option_data.m_debug_mode; }
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) {
247 m_option_data.AddLocalLLDBInit();
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
255 m_debugger.SkipLLDBInitFiles(false);
256 m_debugger.SkipAppInitFiles(false);
258 if (args.hasArg(OPT_version)) {
259 m_option_data.m_print_version = true;
262 if (args.hasArg(OPT_python_path)) {
263 m_option_data.m_print_python_path = true;
266 if (args.hasArg(OPT_batch)) {
267 m_option_data.m_batch = true;
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'",
279 m_option_data.m_core_file = arg_value;
282 if (args.hasArg(OPT_editor)) {
283 m_option_data.m_use_external_editor = true;
286 if (args.hasArg(OPT_no_lldbinit)) {
287 m_debugger.SkipLLDBInitFiles(true);
288 m_debugger.SkipAppInitFiles(true);
291 if (args.hasArg(OPT_no_use_colors)) {
292 m_debugger.SetUseColor(false);
295 if (auto *arg = args.getLastArg(OPT_file)) {
296 auto arg_value = arg->getValue();
297 SBFileSpec file(arg_value);
299 m_option_data.m_args.emplace_back(arg_value);
300 } else if (file.ResolveExecutableLocation()) {
302 file.GetPath(path, sizeof(path));
303 m_option_data.m_args.emplace_back(path);
305 error.SetErrorStringWithFormat(
306 "file specified in --file (-f) option doesn't exist: '%s'",
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);
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);
326 if (args.hasArg(OPT_no_use_colors)) {
327 m_option_data.m_debug_mode = true;
330 if (args.hasArg(OPT_no_use_colors)) {
331 m_debugger.SetUseColor(false);
334 if (args.hasArg(OPT_source_quietly)) {
335 m_option_data.m_source_quietly = true;
338 if (auto *arg = args.getLastArg(OPT_attach_name)) {
339 auto arg_value = arg->getValue();
340 m_option_data.m_process_name = arg_value;
343 if (args.hasArg(OPT_wait_for)) {
344 m_option_data.m_wait_for = true;
347 if (auto *arg = args.getLastArg(OPT_attach_pid)) {
348 auto arg_value = arg->getValue();
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);
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\"",
369 if (args.hasArg(OPT_repl)) {
370 m_option_data.m_repl = true;
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;
379 // We need to process the options below together as their relative order
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,
392 if (arg->getOption().matches(OPT_one_line_on_crash)) {
393 m_option_data.AddInitialCommand(arg_value, eCommandPlacementAfterCrash,
399 if (arg->getOption().matches(OPT_source)) {
400 m_option_data.AddInitialCommand(arg_value, eCommandPlacementAfterFile,
406 if (arg->getOption().matches(OPT_source_before_file)) {
407 m_option_data.AddInitialCommand(arg_value, eCommandPlacementBeforeFile,
413 if (arg->getOption().matches(OPT_one_line)) {
414 m_option_data.AddInitialCommand(arg_value, eCommandPlacementAfterFile,
420 if (arg->getOption().matches(OPT_one_line_before_file)) {
421 m_option_data.AddInitialCommand(arg_value, eCommandPlacementBeforeFile,
428 if (m_option_data.m_process_name.empty() &&
429 m_option_data.m_process_pid == LLDB_INVALID_PROCESS_ID) {
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)));
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);
444 } else if (args.getLastArgNoClaim() != nullptr) {
445 WithColor::warning() << "program arguments are ignored when attaching.\n";
448 if (m_option_data.m_print_version) {
449 llvm::outs() << lldb::SBDebugger::GetVersionString() << '\n';
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';
462 llvm::outs() << "<PATH TOO LONG>\n";
464 llvm::outs() << "<COULD NOT FIND PATH>\n";
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
476 ::FILE *commands_file = nullptr;
481 err = _pipe(fds, commands_size, O_BINARY);
486 ssize_t nrwr = write(fds[WRITE], commands_data, commands_size);
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)
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
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".
514 WithColor::error() << format("fdopen(%i, \"r\") failed (errno = %i) "
515 "when trying to open LLDB commands pipe",
522 << "can't create pipe file descriptors for LLDB commands\n";
525 return commands_file;
528 void CleanupAfterCommandSourcing(int fds[2]) {
529 enum PIPES { READ, WRITE }; // Constants 0 and 1 for READ and WRITE
531 // Close any pipes that we still have ownership of
532 if (fds[WRITE] != -1) {
542 if (fds[READ] != -1) {
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, '\\');
559 return '"' + arg + '"';
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);
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);
574 ::setbuf(stdout, nullptr);
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...
581 m_debugger.SetUseExternalEditor(m_option_data.m_use_external_editor);
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);
590 SBCommandInterpreter sb_interpreter = m_debugger.GetCommandInterpreter();
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());
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);
605 // Now we handle options we got from the command line
606 SBStream commands_stream;
608 // First source in the commands specified to be run before the file arguments
610 WriteCommandsForSourcing(eCommandPlacementBeforeFile, commands_stream);
612 const size_t num_args = m_option_data.m_args.size();
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());
619 commands_stream.Printf("target create %s",
620 EscapeString(m_option_data.m_args[0]).c_str());
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());
626 commands_stream.Printf("\n");
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");
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());
642 if (m_option_data.m_wait_for)
643 commands_stream.Printf(" --waitfor");
645 commands_stream.Printf("\n");
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);
652 WriteCommandsForSourcing(eCommandPlacementAfterFile, commands_stream);
654 if (GetDebugMode()) {
655 result.PutError(m_debugger.GetErrorFileHandle());
656 result.PutOutput(m_debugger.GetOutputFileHandle());
659 bool handle_events = true;
660 bool spawn_thread = false;
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));
668 const char *error_cstr = error.GetCString();
669 if ((error_cstr != nullptr) && (error_cstr[0] != 0))
670 WithColor::error() << error_cstr << '\n';
672 WithColor::error() << error.GetError() << '\n';
675 // Check if we have any data in the commands stream, and if so, save it to a
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();
681 // The command file might have requested that we quit, this variable will
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];
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);
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);
700 SBCommandInterpreterRunOptions options;
701 options.SetStopOnError(true);
702 if (m_option_data.m_batch)
703 options.SetStopOnCrash(true);
705 m_debugger.RunCommandInterpreter(handle_events, spawn_thread, options,
706 num_errors, quit_requested,
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);
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;
731 m_debugger.SetAsync(old_async);
735 // Close any pipes that we still have ownership of
736 CleanupAfterCommandSourcing(initial_commands_fds);
738 // Something went wrong with command pipe
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
748 bool go_interactive = true;
750 go_interactive = false;
751 else if (m_option_data.m_batch && !stopped_for_crash)
752 go_interactive = false;
754 if (go_interactive) {
755 m_debugger.SetInputFileHandle(stdin, true);
756 m_debugger.RunCommandInterpreter(handle_events, spawn_thread);
760 reset_stdin_termios();
763 int exit_code = sb_interpreter.GetQuitStatus();
764 SBDebugger::Destroy(m_debugger);
768 void Driver::ResizeWindow(unsigned short col) {
769 GetDebugger().SetTerminalWidth(col);
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);
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();
795 void sigtstp_handler(int signo) {
796 if (g_driver != nullptr)
797 g_driver->GetDebugger().SaveInputTerminalState();
799 signal(signo, SIG_DFL);
800 kill(getpid(), signo);
801 signal(signo, sigtstp_handler);
804 void sigcont_handler(int signo) {
805 if (g_driver != nullptr)
806 g_driver->GetDebugger().RestoreInputTerminalState();
808 signal(signo, SIG_DFL);
809 kill(getpid(), signo);
810 signal(signo, sigcont_handler);
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);
817 std::string examples = R"___(
819 The debugger can be started in several modes.
821 Passing an executable as a positional argument prepares lldb to debug the
822 given executable. Arguments passed after -- are considered arguments to the
825 lldb --arch x86_64 /path/to/program -- --arch arvm7
827 Passing one of the attach options causes lldb to immediately attach to the
831 lldb -n <process-name>
833 Passing --repl starts lldb in REPL mode.
837 Passing --core causes lldb to debug the core file.
839 lldb -c /path/to/core
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.
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
849 llvm::outs() << examples;
854 wmain(int argc, wchar_t const *wargv[])
856 main(int argc, char const *argv[])
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();
867 const char **argv = argvPointers.data();
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);
879 ArrayRef<const char *> arg_arr = makeArrayRef(argv + 1, argc - 1);
880 opt::InputArgList input_args = T.ParseArgs(arg_arr, MAI, MAC);
882 if (input_args.hasArg(OPT_help)) {
883 printHelp(T, ToolName);
887 for (auto *arg : input_args.filtered(OPT_UNKNOWN)) {
888 WithColor::warning() << "ignoring unknown option: " << arg->getSpelling()
892 SBInitializerOptions options;
894 if (auto *arg = input_args.getLastArg(OPT_capture)) {
895 auto arg_value = arg->getValue();
896 options.SetReproducerPath(arg_value);
897 options.SetCaptureReproducer(true);
900 if (auto *arg = input_args.getLastArg(OPT_replay)) {
901 auto arg_value = arg->getValue();
902 options.SetReplayReproducer(true);
903 options.SetReproducerPath(arg_value);
906 SBError error = SBDebugger::Initialize(options);
908 WithColor::error() << "initialization failed: " << error.GetCString()
913 SBHostOS::ThreadCreated("<lldb.driver.main-thread>");
915 signal(SIGINT, sigint_handler);
916 #if !defined(_MSC_VER)
917 signal(SIGPIPE, SIG_IGN);
918 signal(SIGWINCH, sigwinch_handler);
919 signal(SIGTSTP, sigtstp_handler);
920 signal(SIGCONT, sigcont_handler);
924 // Create a scope for driver so that the driver object will destroy itself
925 // before SBDebugger::Terminate() is called.
929 bool exiting = false;
930 SBError error(driver.ProcessArgs(input_args, exiting));
933 if (const char *error_cstr = error.GetCString())
934 WithColor::error() << error_cstr << '\n';
935 } else if (!exiting) {
936 exit_code = driver.MainLoop();
940 SBDebugger::Terminate();