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