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 (args.hasArg(OPT_no_use_colors)) {
371     m_debugger.SetUseColor(false);
372   }
373 
374   if (args.hasArg(OPT_source_quietly)) {
375     m_option_data.m_source_quietly = true;
376   }
377 
378   if (auto *arg = args.getLastArg(OPT_attach_name)) {
379     auto arg_value = arg->getValue();
380     m_option_data.m_process_name = arg_value;
381   }
382 
383   if (args.hasArg(OPT_wait_for)) {
384     m_option_data.m_wait_for = true;
385   }
386 
387   if (auto *arg = args.getLastArg(OPT_attach_pid)) {
388     auto arg_value = arg->getValue();
389     char *remainder;
390     m_option_data.m_process_pid = strtol(arg_value, &remainder, 0);
391     if (remainder == arg_value || *remainder != '\0') {
392       error.SetErrorStringWithFormat(
393           "Could not convert process PID: \"%s\" into a pid.", arg_value);
394       return error;
395     }
396   }
397 
398   if (auto *arg = args.getLastArg(OPT_repl_language)) {
399     auto arg_value = arg->getValue();
400     m_option_data.m_repl_lang =
401         SBLanguageRuntime::GetLanguageTypeFromString(arg_value);
402     if (m_option_data.m_repl_lang == eLanguageTypeUnknown) {
403       error.SetErrorStringWithFormat("Unrecognized language name: \"%s\"",
404                                      arg_value);
405       return error;
406     }
407   }
408 
409   if (auto *arg = args.getLastArg(OPT_repl)) {
410     auto arg_value = arg->getValue();
411     m_option_data.m_repl = true;
412     if (arg_value && arg_value[0])
413       m_option_data.m_repl_options = arg_value;
414     else
415       m_option_data.m_repl_options.clear();
416   }
417 
418   // We need to process the options below together as their relative order
419   // matters.
420   for (auto *arg : args.filtered(OPT_source_on_crash, OPT_one_line_on_crash,
421                                  OPT_source, OPT_source_before_file,
422                                  OPT_one_line, OPT_one_line_before_file)) {
423     auto arg_value = arg->getValue();
424     if (arg->getOption().matches(OPT_source_on_crash)) {
425       m_option_data.AddInitialCommand(arg_value, eCommandPlacementAfterCrash,
426                                       true, error);
427       if (error.Fail())
428         return error;
429     }
430 
431     if (arg->getOption().matches(OPT_one_line_on_crash)) {
432       m_option_data.AddInitialCommand(arg_value, eCommandPlacementAfterCrash,
433                                       false, error);
434       if (error.Fail())
435         return error;
436     }
437 
438     if (arg->getOption().matches(OPT_source)) {
439       m_option_data.AddInitialCommand(arg_value, eCommandPlacementAfterFile,
440                                       true, error);
441       if (error.Fail())
442         return error;
443     }
444 
445     if (arg->getOption().matches(OPT_source_before_file)) {
446       m_option_data.AddInitialCommand(arg_value, eCommandPlacementBeforeFile,
447                                       true, error);
448       if (error.Fail())
449         return error;
450     }
451 
452     if (arg->getOption().matches(OPT_one_line)) {
453       m_option_data.AddInitialCommand(arg_value, eCommandPlacementAfterFile,
454                                       false, error);
455       if (error.Fail())
456         return error;
457     }
458 
459     if (arg->getOption().matches(OPT_one_line_before_file)) {
460       m_option_data.AddInitialCommand(arg_value, eCommandPlacementBeforeFile,
461                                       false, error);
462       if (error.Fail())
463         return error;
464     }
465   }
466 
467   if (m_option_data.m_process_name.empty() &&
468       m_option_data.m_process_pid == LLDB_INVALID_PROCESS_ID) {
469 
470     // If the option data args array is empty that means the file was not
471     // specified with -f and we need to get it from the input args.
472     if (m_option_data.m_args.empty()) {
473       if (auto *arg = args.getLastArgNoClaim(OPT_INPUT)) {
474         m_option_data.m_args.push_back(arg->getAsString((args)));
475       }
476     }
477 
478     // Any argument following -- is an argument for the inferior.
479     if (auto *arg = args.getLastArgNoClaim(OPT_REM)) {
480       for (auto value : arg->getValues())
481         m_option_data.m_args.push_back(value);
482     }
483   } else if (args.getLastArgNoClaim()) {
484     WithColor::warning() << "program arguments are ignored when attaching.\n";
485   }
486 
487   if (m_option_data.m_print_version) {
488     llvm::outs() << m_debugger.GetVersionString() << '\n';
489     exiting = true;
490     return error;
491   }
492 
493   if (m_option_data.m_print_python_path) {
494     SBFileSpec python_file_spec = SBHostOS::GetLLDBPythonPath();
495     if (python_file_spec.IsValid()) {
496       char python_path[PATH_MAX];
497       size_t num_chars = python_file_spec.GetPath(python_path, PATH_MAX);
498       if (num_chars < PATH_MAX) {
499         llvm::outs() << python_path << '\n';
500       } else
501         llvm::outs() << "<PATH TOO LONG>\n";
502     } else
503       llvm::outs() << "<COULD NOT FIND PATH>\n";
504     exiting = true;
505     return error;
506   }
507 
508   return error;
509 }
510 
511 static ::FILE *PrepareCommandsForSourcing(const char *commands_data,
512                                           size_t commands_size, int fds[2]) {
513   enum PIPES { READ, WRITE }; // Constants 0 and 1 for READ and WRITE
514 
515   ::FILE *commands_file = NULL;
516   fds[0] = -1;
517   fds[1] = -1;
518   int err = 0;
519 #ifdef _WIN32
520   err = _pipe(fds, commands_size, O_BINARY);
521 #else
522   err = pipe(fds);
523 #endif
524   if (err == 0) {
525     ssize_t nrwr = write(fds[WRITE], commands_data, commands_size);
526     if (nrwr < 0) {
527       WithColor::error()
528           << format(
529                  "write(%i, %p, %" PRIu64
530                  ") failed (errno = %i) when trying to open LLDB commands pipe",
531                  fds[WRITE], static_cast<const void *>(commands_data),
532                  static_cast<uint64_t>(commands_size), errno)
533           << '\n';
534     } else if (static_cast<size_t>(nrwr) == commands_size) {
535 // Close the write end of the pipe so when we give the read end to
536 // the debugger/command interpreter it will exit when it consumes all
537 // of the data
538 #ifdef _WIN32
539       _close(fds[WRITE]);
540       fds[WRITE] = -1;
541 #else
542       close(fds[WRITE]);
543       fds[WRITE] = -1;
544 #endif
545       // Now open the read file descriptor in a FILE * that we can give to
546       // the debugger as an input handle
547       commands_file = fdopen(fds[READ], "r");
548       if (commands_file) {
549         fds[READ] = -1; // The FILE * 'commands_file' now owns the read
550                         // descriptor Hand ownership if the FILE * over to the
551                         // debugger for "commands_file".
552       } else {
553         WithColor::error() << format("fdopen(%i, \"r\") failed (errno = %i) "
554                                      "when trying to open LLDB commands pipe",
555                                      fds[READ], errno)
556                            << '\n';
557       }
558     }
559   } else {
560     WithColor::error()
561         << "can't create pipe file descriptors for LLDB commands\n";
562   }
563 
564   return commands_file;
565 }
566 
567 void CleanupAfterCommandSourcing(int fds[2]) {
568   enum PIPES { READ, WRITE }; // Constants 0 and 1 for READ and WRITE
569 
570   // Close any pipes that we still have ownership of
571   if (fds[WRITE] != -1) {
572 #ifdef _WIN32
573     _close(fds[WRITE]);
574     fds[WRITE] = -1;
575 #else
576     close(fds[WRITE]);
577     fds[WRITE] = -1;
578 #endif
579   }
580 
581   if (fds[READ] != -1) {
582 #ifdef _WIN32
583     _close(fds[READ]);
584     fds[READ] = -1;
585 #else
586     close(fds[READ]);
587     fds[READ] = -1;
588 #endif
589   }
590 }
591 
592 std::string EscapeString(std::string arg) {
593   std::string::size_type pos = 0;
594   while ((pos = arg.find_first_of("\"\\", pos)) != std::string::npos) {
595     arg.insert(pos, 1, '\\');
596     pos += 2;
597   }
598   return '"' + arg + '"';
599 }
600 
601 int Driver::MainLoop() {
602   if (::tcgetattr(STDIN_FILENO, &g_old_stdin_termios) == 0) {
603     g_old_stdin_termios_is_valid = true;
604     atexit(reset_stdin_termios);
605   }
606 
607 #ifndef _MSC_VER
608   // Disabling stdin buffering with MSVC's 2015 CRT exposes a bug in fgets
609   // which causes it to miss newlines depending on whether there have been an
610   // odd or even number of characters.  Bug has been reported to MS via Connect.
611   ::setbuf(stdin, NULL);
612 #endif
613   ::setbuf(stdout, NULL);
614 
615   m_debugger.SetErrorFileHandle(stderr, false);
616   m_debugger.SetOutputFileHandle(stdout, false);
617   m_debugger.SetInputFileHandle(stdin,
618                                 false); // Don't take ownership of STDIN yet...
619 
620   m_debugger.SetUseExternalEditor(m_option_data.m_use_external_editor);
621 
622   struct winsize window_size;
623   if (isatty(STDIN_FILENO) &&
624       ::ioctl(STDIN_FILENO, TIOCGWINSZ, &window_size) == 0) {
625     if (window_size.ws_col > 0)
626       m_debugger.SetTerminalWidth(window_size.ws_col);
627   }
628 
629   SBCommandInterpreter sb_interpreter = m_debugger.GetCommandInterpreter();
630 
631   // Before we handle any options from the command line, we parse the
632   // .lldbinit file in the user's home directory.
633   SBCommandReturnObject result;
634   sb_interpreter.SourceInitFileInHomeDirectory(result);
635   if (GetDebugMode()) {
636     result.PutError(m_debugger.GetErrorFileHandle());
637     result.PutOutput(m_debugger.GetOutputFileHandle());
638   }
639 
640   // We allow the user to specify an exit code when calling quit which we will
641   // return when exiting.
642   m_debugger.GetCommandInterpreter().AllowExitCodeOnQuit(true);
643 
644   // Now we handle options we got from the command line
645   SBStream commands_stream;
646 
647   // First source in the commands specified to be run before the file arguments
648   // are processed.
649   WriteCommandsForSourcing(eCommandPlacementBeforeFile, commands_stream);
650 
651   const size_t num_args = m_option_data.m_args.size();
652   if (num_args > 0) {
653     char arch_name[64];
654     if (m_debugger.GetDefaultArchitecture(arch_name, sizeof(arch_name)))
655       commands_stream.Printf("target create --arch=%s %s", arch_name,
656                              EscapeString(m_option_data.m_args[0]).c_str());
657     else
658       commands_stream.Printf("target create %s",
659                              EscapeString(m_option_data.m_args[0]).c_str());
660 
661     if (!m_option_data.m_core_file.empty()) {
662       commands_stream.Printf(" --core %s",
663                              EscapeString(m_option_data.m_core_file).c_str());
664     }
665     commands_stream.Printf("\n");
666 
667     if (num_args > 1) {
668       commands_stream.Printf("settings set -- target.run-args ");
669       for (size_t arg_idx = 1; arg_idx < num_args; ++arg_idx)
670         commands_stream.Printf(
671             " %s", EscapeString(m_option_data.m_args[arg_idx]).c_str());
672       commands_stream.Printf("\n");
673     }
674   } else if (!m_option_data.m_core_file.empty()) {
675     commands_stream.Printf("target create --core %s\n",
676                            EscapeString(m_option_data.m_core_file).c_str());
677   } else if (!m_option_data.m_process_name.empty()) {
678     commands_stream.Printf("process attach --name %s",
679                            EscapeString(m_option_data.m_process_name).c_str());
680 
681     if (m_option_data.m_wait_for)
682       commands_stream.Printf(" --waitfor");
683 
684     commands_stream.Printf("\n");
685 
686   } else if (LLDB_INVALID_PROCESS_ID != m_option_data.m_process_pid) {
687     commands_stream.Printf("process attach --pid %" PRIu64 "\n",
688                            m_option_data.m_process_pid);
689   }
690 
691   WriteCommandsForSourcing(eCommandPlacementAfterFile, commands_stream);
692 
693   if (GetDebugMode()) {
694     result.PutError(m_debugger.GetErrorFileHandle());
695     result.PutOutput(m_debugger.GetOutputFileHandle());
696   }
697 
698   bool handle_events = true;
699   bool spawn_thread = false;
700 
701   if (m_option_data.m_repl) {
702     const char *repl_options = NULL;
703     if (!m_option_data.m_repl_options.empty())
704       repl_options = m_option_data.m_repl_options.c_str();
705     SBError error(m_debugger.RunREPL(m_option_data.m_repl_lang, repl_options));
706     if (error.Fail()) {
707       const char *error_cstr = error.GetCString();
708       if (error_cstr && error_cstr[0])
709         WithColor::error() << error_cstr << '\n';
710       else
711         WithColor::error() << error.GetError() << '\n';
712     }
713   } else {
714     // Check if we have any data in the commands stream, and if so, save it to a
715     // temp file
716     // so we can then run the command interpreter using the file contents.
717     const char *commands_data = commands_stream.GetData();
718     const size_t commands_size = commands_stream.GetSize();
719 
720     // The command file might have requested that we quit, this variable will
721     // track that.
722     bool quit_requested = false;
723     bool stopped_for_crash = false;
724     if (commands_data && commands_size) {
725       int initial_commands_fds[2];
726       bool success = true;
727       FILE *commands_file = PrepareCommandsForSourcing(
728           commands_data, commands_size, initial_commands_fds);
729       if (commands_file) {
730         m_debugger.SetInputFileHandle(commands_file, true);
731 
732         // Set the debugger into Sync mode when running the command file.
733         // Otherwise command files
734         // that run the target won't run in a sensible way.
735         bool old_async = m_debugger.GetAsync();
736         m_debugger.SetAsync(false);
737         int num_errors;
738 
739         SBCommandInterpreterRunOptions options;
740         options.SetStopOnError(true);
741         if (m_option_data.m_batch)
742           options.SetStopOnCrash(true);
743 
744         m_debugger.RunCommandInterpreter(handle_events, spawn_thread, options,
745                                          num_errors, quit_requested,
746                                          stopped_for_crash);
747 
748         if (m_option_data.m_batch && stopped_for_crash &&
749             !m_option_data.m_after_crash_commands.empty()) {
750           int crash_command_fds[2];
751           SBStream crash_commands_stream;
752           WriteCommandsForSourcing(eCommandPlacementAfterCrash,
753                                    crash_commands_stream);
754           const char *crash_commands_data = crash_commands_stream.GetData();
755           const size_t crash_commands_size = crash_commands_stream.GetSize();
756           commands_file = PrepareCommandsForSourcing(
757               crash_commands_data, crash_commands_size, crash_command_fds);
758           if (commands_file) {
759             bool local_quit_requested;
760             bool local_stopped_for_crash;
761             m_debugger.SetInputFileHandle(commands_file, true);
762 
763             m_debugger.RunCommandInterpreter(
764                 handle_events, spawn_thread, options, num_errors,
765                 local_quit_requested, local_stopped_for_crash);
766             if (local_quit_requested)
767               quit_requested = true;
768           }
769         }
770         m_debugger.SetAsync(old_async);
771       } else
772         success = false;
773 
774       // Close any pipes that we still have ownership of
775       CleanupAfterCommandSourcing(initial_commands_fds);
776 
777       // Something went wrong with command pipe
778       if (!success) {
779         exit(1);
780       }
781     }
782 
783     // Now set the input file handle to STDIN and run the command
784     // interpreter again in interactive mode and let the debugger
785     // take ownership of stdin
786 
787     bool go_interactive = true;
788     if (quit_requested)
789       go_interactive = false;
790     else if (m_option_data.m_batch && !stopped_for_crash)
791       go_interactive = false;
792 
793     if (go_interactive) {
794       m_debugger.SetInputFileHandle(stdin, true);
795       m_debugger.RunCommandInterpreter(handle_events, spawn_thread);
796     }
797   }
798 
799   reset_stdin_termios();
800   fclose(stdin);
801 
802   int exit_code = sb_interpreter.GetQuitStatus();
803   SBDebugger::Destroy(m_debugger);
804   return exit_code;
805 }
806 
807 void Driver::ResizeWindow(unsigned short col) {
808   GetDebugger().SetTerminalWidth(col);
809 }
810 
811 void sigwinch_handler(int signo) {
812   struct winsize window_size;
813   if (isatty(STDIN_FILENO) &&
814       ::ioctl(STDIN_FILENO, TIOCGWINSZ, &window_size) == 0) {
815     if ((window_size.ws_col > 0) && g_driver != NULL) {
816       g_driver->ResizeWindow(window_size.ws_col);
817     }
818   }
819 }
820 
821 void sigint_handler(int signo) {
822   static std::atomic_flag g_interrupt_sent = ATOMIC_FLAG_INIT;
823   if (g_driver) {
824     if (!g_interrupt_sent.test_and_set()) {
825       g_driver->GetDebugger().DispatchInputInterrupt();
826       g_interrupt_sent.clear();
827       return;
828     }
829   }
830 
831   _exit(signo);
832 }
833 
834 void sigtstp_handler(int signo) {
835   if (g_driver)
836     g_driver->GetDebugger().SaveInputTerminalState();
837 
838   signal(signo, SIG_DFL);
839   kill(getpid(), signo);
840   signal(signo, sigtstp_handler);
841 }
842 
843 void sigcont_handler(int signo) {
844   if (g_driver)
845     g_driver->GetDebugger().RestoreInputTerminalState();
846 
847   signal(signo, SIG_DFL);
848   kill(getpid(), signo);
849   signal(signo, sigcont_handler);
850 }
851 
852 static void printHelp(LLDBOptTable &table, llvm::StringRef tool_name) {
853   std::string usage_str = tool_name.str() + "options";
854   table.PrintHelp(llvm::outs(), usage_str.c_str(), "LLDB", false);
855 
856   std::string examples = R"___(
857 EXAMPLES:
858   The debugger can be started in several modes.
859 
860   Passing an executable as a positional argument prepares lldb to debug the
861   given executable. Arguments passed after -- are considered arguments to the
862   debugged executable.
863 
864     lldb --arch x86_64 /path/to/program -- --arch arvm7
865 
866   Passing one of the attach options causes lldb to immediately attach to the
867   given process.
868 
869     lldb -p <pid>
870     lldb -n <process-name>
871 
872   Passing --repl starts lldb in REPL mode.
873 
874     lldb -r
875 
876   Passing --core causes lldb to debug the core file.
877 
878     lldb -c /path/to/core
879 
880   Command options can be combined with either mode and cause lldb to run the
881   specified commands before or after events, like loading the file or crashing,
882   in the order provided on the command line.
883 
884     lldb -O 'settings set stop-disassembly-count 20' -o 'run' -o 'bt'
885     lldb -S /source/before/file -s /source/after/file
886     lldb -K /source/before/crash -k /source/after/crash
887   )___";
888   llvm::outs() << examples;
889 }
890 
891 int
892 #ifdef _MSC_VER
893 wmain(int argc, wchar_t const *wargv[])
894 #else
895 main(int argc, char const *argv[])
896 #endif
897 {
898 #ifdef _MSC_VER
899   // Convert wide arguments to UTF-8
900   std::vector<std::string> argvStrings(argc);
901   std::vector<const char *> argvPointers(argc);
902   for (int i = 0; i != argc; ++i) {
903     llvm::convertWideToUTF8(wargv[i], argvStrings[i]);
904     argvPointers[i] = argvStrings[i].c_str();
905   }
906   const char **argv = argvPointers.data();
907 #endif
908 
909   // Print stack trace on crash.
910   llvm::StringRef ToolName = llvm::sys::path::filename(argv[0]);
911   llvm::sys::PrintStackTraceOnErrorSignal(ToolName);
912   llvm::PrettyStackTraceProgram X(argc, argv);
913 
914   // Parse arguments.
915   LLDBOptTable T;
916   unsigned MAI, MAC;
917   ArrayRef<const char *> arg_arr = makeArrayRef(argv + 1, argc - 1);
918   opt::InputArgList input_args = T.ParseArgs(arg_arr, MAI, MAC);
919 
920   if (input_args.hasArg(OPT_help)) {
921     printHelp(T, ToolName);
922     return 0;
923   }
924 
925   for (auto *arg : input_args.filtered(OPT_UNKNOWN)) {
926     WithColor::warning() << "ignoring unknown option: " << arg->getSpelling()
927                          << '\n';
928   }
929 
930   SBInitializerOptions options;
931 
932   if (auto *arg = input_args.getLastArg(OPT_capture)) {
933     auto arg_value = arg->getValue();
934     options.SetReproducerPath(arg_value);
935     options.SetCaptureReproducer(true);
936   }
937 
938   if (auto *arg = input_args.getLastArg(OPT_replay)) {
939     auto arg_value = arg->getValue();
940     options.SetReplayReproducer(true);
941     options.SetReproducerPath(arg_value);
942   }
943 
944   SBError error = SBDebugger::Initialize(options);
945   if (error.Fail()) {
946     WithColor::error() << "initialization failed: " << error.GetCString()
947                        << '\n';
948     return 1;
949   }
950 
951   SBHostOS::ThreadCreated("<lldb.driver.main-thread>");
952 
953   signal(SIGINT, sigint_handler);
954 #if !defined(_MSC_VER)
955   signal(SIGPIPE, SIG_IGN);
956   signal(SIGWINCH, sigwinch_handler);
957   signal(SIGTSTP, sigtstp_handler);
958   signal(SIGCONT, sigcont_handler);
959 #endif
960 
961   int exit_code = 0;
962   // Create a scope for driver so that the driver object will destroy itself
963   // before SBDebugger::Terminate() is called.
964   {
965     Driver driver;
966 
967     bool exiting = false;
968     SBError error(driver.ProcessArgs(input_args, exiting));
969     if (error.Fail()) {
970       exit_code = 1;
971       if (const char *error_cstr = error.GetCString())
972         WithColor::error() << error_cstr << '\n';
973     } else if (!exiting) {
974       exit_code = driver.MainLoop();
975     }
976   }
977 
978   SBDebugger::Terminate();
979   return exit_code;
980 }
981