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