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