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