blob: c057d71a83008754fe93e064ff684cd2a6ebd1ab [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- 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
Deepak Panickal429222c2013-10-15 15:46:40 +000012#include <stdio.h>
Eli Friedmana382d472010-06-09 09:50:17 +000013#include <string.h>
14#include <stdlib.h>
15#include <limits.h>
Eli Friedman07b16272010-06-09 19:11:30 +000016#include <fcntl.h>
Chris Lattner30fdc8d2010-06-08 16:52:24 +000017
Greg Clayton49668762014-08-01 18:32:07 +000018// Includes for pipe()
19#if defined(_WIN32)
20#include <io.h>
21#include <fcntl.h>
Shawn Best8da0bf32014-11-08 01:41:49 +000022#elif defined(__ANDROID_NDK__)
23#include <errno.h>
Greg Clayton49668762014-08-01 18:32:07 +000024#else
25#include <unistd.h>
26#endif
27
Chris Lattner30fdc8d2010-06-08 16:52:24 +000028#include <string>
29
Jim Inghame6bc6cb2012-02-08 05:23:15 +000030#include "lldb/API/SBBreakpoint.h"
Eli Friedmana382d472010-06-09 09:50:17 +000031#include "lldb/API/SBCommandInterpreter.h"
32#include "lldb/API/SBCommandReturnObject.h"
33#include "lldb/API/SBCommunication.h"
34#include "lldb/API/SBDebugger.h"
35#include "lldb/API/SBEvent.h"
36#include "lldb/API/SBHostOS.h"
Sean Callanan3e7e9152015-10-20 00:23:46 +000037#include "lldb/API/SBLanguageRuntime.h"
Eli Friedmana382d472010-06-09 09:50:17 +000038#include "lldb/API/SBListener.h"
Zachary Turner190fadc2016-03-22 17:58:09 +000039#include "lldb/API/SBProcess.h"
Jim Ingham85e8b812011-02-19 02:53:09 +000040#include "lldb/API/SBStream.h"
Jason Molenda878ae012016-02-19 00:05:17 +000041#include "lldb/API/SBStringList.h"
Eli Friedmana382d472010-06-09 09:50:17 +000042#include "lldb/API/SBTarget.h"
43#include "lldb/API/SBThread.h"
Zachary Turner190fadc2016-03-22 17:58:09 +000044#include "llvm/Support/ConvertUTF.h"
45#include <thread>
Chris Lattner30fdc8d2010-06-08 16:52:24 +000046
Todd Fialab82ad2a2014-09-15 15:17:13 +000047#if !defined(__APPLE__)
Zachary Turner40a069a2014-09-11 20:26:49 +000048#include "llvm/Support/DataTypes.h"
Todd Fialab82ad2a2014-09-15 15:17:13 +000049#endif
Zachary Turner40a069a2014-09-11 20:26:49 +000050
Chris Lattner30fdc8d2010-06-08 16:52:24 +000051using namespace lldb;
52
53static void reset_stdin_termios ();
Greg Claytonf571b892012-02-02 19:28:31 +000054static bool g_old_stdin_termios_is_valid = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000055static struct termios g_old_stdin_termios;
56
Caroline Ticeefed6132010-11-19 20:47:54 +000057static Driver *g_driver = NULL;
Caroline Ticedd759852010-09-09 17:45:09 +000058
Chris Lattner30fdc8d2010-06-08 16:52:24 +000059// In the Driver::MainLoop, we change the terminal settings. This function is
60// added as an atexit handler to make sure we clean them up.
61static void
62reset_stdin_termios ()
63{
Greg Claytonf571b892012-02-02 19:28:31 +000064 if (g_old_stdin_termios_is_valid)
65 {
66 g_old_stdin_termios_is_valid = false;
67 ::tcsetattr (STDIN_FILENO, TCSANOW, &g_old_stdin_termios);
68 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000069}
70
Greg Claytone0d378b2011-03-24 21:19:54 +000071typedef struct
Chris Lattner30fdc8d2010-06-08 16:52:24 +000072{
Greg Claytone0d378b2011-03-24 21:19:54 +000073 uint32_t usage_mask; // Used to mark options that can be used together. If (1 << n & usage_mask) != 0
74 // then this option belongs to option set n.
75 bool required; // This option is required (in the current usage level)
76 const char * long_option; // Full name for this option.
Greg Clayton3bcdfc02012-12-04 00:32:51 +000077 int short_option; // Single character for this option.
Greg Claytone0d378b2011-03-24 21:19:54 +000078 int option_has_arg; // no_argument, required_argument or optional_argument
Greg Claytonab65b342011-04-13 22:47:15 +000079 uint32_t completion_type; // Cookie the option class can use to do define the argument completion.
Greg Claytone0d378b2011-03-24 21:19:54 +000080 lldb::CommandArgumentType argument_type; // Type of argument this option takes
81 const char * usage_text; // Full text explaining what this options does and what (if any) argument to
82 // pass it.
83} OptionDefinition;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000084
Jim Inghame64f0dc2011-09-13 23:25:31 +000085#define LLDB_3_TO_5 LLDB_OPT_SET_3|LLDB_OPT_SET_4|LLDB_OPT_SET_5
86#define LLDB_4_TO_5 LLDB_OPT_SET_4|LLDB_OPT_SET_5
87
Greg Claytone0d378b2011-03-24 21:19:54 +000088static OptionDefinition g_options[] =
89{
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +000090 { LLDB_OPT_SET_1, true , "help" , 'h', no_argument , 0, eArgTypeNone,
Jim Ingham12e9a202011-09-15 21:30:02 +000091 "Prints out the usage information for the LLDB debugger." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +000092 { LLDB_OPT_SET_2, true , "version" , 'v', no_argument , 0, eArgTypeNone,
Jim Ingham12e9a202011-09-15 21:30:02 +000093 "Prints out the current version number of the LLDB debugger." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +000094 { LLDB_OPT_SET_3, true , "arch" , 'a', required_argument, 0, eArgTypeArchitecture,
Jim Ingham12e9a202011-09-15 21:30:02 +000095 "Tells the debugger to use the specified architecture when starting and running the program. <architecture> must "
96 "be one of the architectures for which the program was compiled." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +000097 { LLDB_OPT_SET_3, true , "file" , 'f', required_argument, 0, eArgTypeFilename,
Jim Ingham12e9a202011-09-15 21:30:02 +000098 "Tells the debugger to use the file <filename> as the program to be debugged." },
Jason Molenda67c3cf52012-10-24 03:29:40 +000099 { LLDB_OPT_SET_3, false, "core" , 'c', required_argument, 0, eArgTypeFilename,
Johnny Cheneb46f782012-08-15 22:10:42 +0000100 "Tells the debugger to use the fullpath to <path> as the core file." },
Jim Inghamf0c63b92014-02-05 21:35:09 +0000101 { LLDB_OPT_SET_5, true , "attach-pid" , 'p', required_argument, 0, eArgTypePid,
102 "Tells the debugger to attach to a process with the given pid." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +0000103 { LLDB_OPT_SET_4, true , "attach-name" , 'n', required_argument, 0, eArgTypeProcessName,
Jim Ingham12e9a202011-09-15 21:30:02 +0000104 "Tells the debugger to attach to a process with the given name." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +0000105 { LLDB_OPT_SET_4, true , "wait-for" , 'w', no_argument , 0, eArgTypeNone,
Jim Ingham12e9a202011-09-15 21:30:02 +0000106 "Tells the debugger to wait for a process with the given pid or name to launch before attaching." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +0000107 { LLDB_3_TO_5, false, "source" , 's', required_argument, 0, eArgTypeFilename,
Jim Ingham47ea51f2013-09-17 01:53:35 +0000108 "Tells the debugger to read in and execute the lldb commands in the given file, after any file provided on the command line has been loaded." },
Jim Inghamed3252f2013-09-14 00:20:24 +0000109 { LLDB_3_TO_5, false, "one-line" , 'o', required_argument, 0, eArgTypeNone,
Jim Ingham47ea51f2013-09-17 01:53:35 +0000110 "Tells the debugger to execute this one-line lldb command after any file provided on the command line has been loaded." },
Jim Inghamed3252f2013-09-14 00:20:24 +0000111 { LLDB_3_TO_5, false, "source-before-file" , 'S', required_argument, 0, eArgTypeFilename,
Jim Ingham47ea51f2013-09-17 01:53:35 +0000112 "Tells the debugger to read in and execute the lldb commands in the given file, before any file provided on the command line has been loaded." },
Jim Inghamed3252f2013-09-14 00:20:24 +0000113 { LLDB_3_TO_5, false, "one-line-before-file" , 'O', required_argument, 0, eArgTypeNone,
Jim Ingham47ea51f2013-09-17 01:53:35 +0000114 "Tells the debugger to execute this one-line lldb command before any file provided on the command line has been loaded." },
Jim Ingham4add3b12014-11-19 01:28:13 +0000115 { LLDB_3_TO_5, false, "one-line-on-crash" , 'k', required_argument, 0, eArgTypeNone,
116 "When in batch mode, tells the debugger to execute this one-line lldb command if the target crashes." },
117 { LLDB_3_TO_5, false, "source-on-crash" , 'K', required_argument, 0, eArgTypeFilename,
118 "When in batch mode, tells the debugger to source this file of lldb commands if the target crashes." },
Jim Inghamf0c63b92014-02-05 21:35:09 +0000119 { LLDB_3_TO_5, false, "source-quietly" , 'Q', no_argument , 0, eArgTypeNone,
Jim Inghamffc9f1d2014-10-14 01:20:07 +0000120 "Tells the debugger to execute this one-line lldb command before any file provided on the command line has been loaded." },
121 { LLDB_3_TO_5, false, "batch" , 'b', no_argument , 0, eArgTypeNone,
122 "Tells the debugger to running the commands from -s, -S, -o & -O, and then quit. However if any run command stopped due to a signal or crash, "
123 "the debugger will return to the interactive prompt at the place of the crash." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +0000124 { LLDB_3_TO_5, false, "editor" , 'e', no_argument , 0, eArgTypeNone,
Jim Ingham12e9a202011-09-15 21:30:02 +0000125 "Tells the debugger to open source files using the host's \"external editor\" mechanism." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +0000126 { LLDB_3_TO_5, false, "no-lldbinit" , 'x', no_argument , 0, eArgTypeNone,
Jim Ingham12e9a202011-09-15 21:30:02 +0000127 "Do not automatically parse any '.lldbinit' files." },
Jim Inghamed3252f2013-09-14 00:20:24 +0000128 { LLDB_3_TO_5, false, "no-use-colors" , 'X', no_argument , 0, eArgTypeNone,
Michael Sartainc3ce7f272013-05-23 20:47:45 +0000129 "Do not use colors." },
130 { LLDB_OPT_SET_6, true , "python-path" , 'P', no_argument , 0, eArgTypeNone,
Jim Inghame2231ac2012-12-21 22:22:26 +0000131 "Prints out the path to the lldb.py file for this version of lldb." },
Jim Inghamf0c63b92014-02-05 21:35:09 +0000132 { LLDB_3_TO_5, false, "script-language", 'l', required_argument, 0, eArgTypeScriptLang,
133 "Tells the debugger to use the specified scripting language for user-defined scripts, rather than the default. "
134 "Valid scripting languages that can be specified include Python, Perl, Ruby and Tcl. Currently only the Python "
135 "extensions have been implemented." },
136 { LLDB_3_TO_5, false, "debug" , 'd', no_argument , 0, eArgTypeNone,
137 "Tells the debugger to print out extra information for debugging itself." },
Sean Callanan3e7e9152015-10-20 00:23:46 +0000138 { LLDB_OPT_SET_7, true , "repl" , 'r', optional_argument, 0, eArgTypeNone,
139 "Runs lldb in REPL mode with a stub process." },
140 { LLDB_OPT_SET_7, true , "repl-language" , 'R', required_argument, 0, eArgTypeNone,
141 "Chooses the language for the REPL." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +0000142 { 0, false, NULL , 0 , 0 , 0, eArgTypeNone, NULL }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000143};
144
Jim Inghame64f0dc2011-09-13 23:25:31 +0000145static const uint32_t last_option_set_with_args = 2;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000146
147Driver::Driver () :
148 SBBroadcaster ("Driver"),
Jim Ingham06942692011-08-13 00:22:20 +0000149 m_debugger (SBDebugger::Create(false)),
Greg Clayton44d93782014-01-27 23:43:24 +0000150 m_option_data ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000151{
Greg Claytonfc3f0272011-05-29 04:06:55 +0000152 // We want to be able to handle CTRL+D in the terminal to have it terminate
153 // certain input
154 m_debugger.SetCloseInputOnEOF (false);
Caroline Ticeefed6132010-11-19 20:47:54 +0000155 g_driver = this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000156}
157
158Driver::~Driver ()
159{
Caroline Ticeefed6132010-11-19 20:47:54 +0000160 g_driver = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000161}
162
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000163
Greg Claytonc982c762010-07-09 20:39:50 +0000164// This function takes INDENT, which tells how many spaces to output at the front
165// of each line; TEXT, which is the text that is to be output. It outputs the
166// text, on multiple lines if necessary, to RESULT, with INDENT spaces at the
167// front of each line. It breaks lines on spaces, tabs or newlines, shortening
168// the line if necessary to not break in the middle of a word. It assumes that
169// each output line should contain a maximum of OUTPUT_MAX_COLUMNS characters.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000170
171void
Greg Claytonc982c762010-07-09 20:39:50 +0000172OutputFormattedUsageText (FILE *out, int indent, const char *text, int output_max_columns)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000173{
174 int len = strlen (text);
175 std::string text_string (text);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000176
177 // Force indentation to be reasonable.
178 if (indent >= output_max_columns)
179 indent = 0;
180
181 // Will it all fit on one line?
182
183 if (len + indent < output_max_columns)
184 // Output as a single line
Greg Claytonc982c762010-07-09 20:39:50 +0000185 fprintf (out, "%*s%s\n", indent, "", text);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000186 else
187 {
188 // We need to break it up into multiple lines.
189 int text_width = output_max_columns - indent - 1;
190 int start = 0;
191 int end = start;
192 int final_end = len;
193 int sub_len;
194
195 while (end < final_end)
196 {
197 // Dont start the 'text' on a space, since we're already outputting the indentation.
198 while ((start < final_end) && (text[start] == ' '))
199 start++;
200
201 end = start + text_width;
202 if (end > final_end)
203 end = final_end;
204 else
205 {
206 // If we're not at the end of the text, make sure we break the line on white space.
207 while (end > start
208 && text[end] != ' ' && text[end] != '\t' && text[end] != '\n')
209 end--;
210 }
211 sub_len = end - start;
212 std::string substring = text_string.substr (start, sub_len);
Greg Claytonc982c762010-07-09 20:39:50 +0000213 fprintf (out, "%*s%s\n", indent, "", substring.c_str());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000214 start = end + 1;
215 }
216 }
217}
218
219void
Greg Claytone0d378b2011-03-24 21:19:54 +0000220ShowUsage (FILE *out, OptionDefinition *option_table, Driver::OptionData data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000221{
222 uint32_t screen_width = 80;
223 uint32_t indent_level = 0;
224 const char *name = "lldb";
Jim Ingham86511212010-06-15 18:47:14 +0000225
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000226 fprintf (out, "\nUsage:\n\n");
227
228 indent_level += 2;
229
230
231 // First, show each usage level set of options, e.g. <cmd> [options-for-level-0]
232 // <cmd> [options-for-level-1]
233 // etc.
234
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000235 uint32_t num_options;
Jim Ingham86511212010-06-15 18:47:14 +0000236 uint32_t num_option_sets = 0;
237
238 for (num_options = 0; option_table[num_options].long_option != NULL; ++num_options)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000239 {
Jim Ingham86511212010-06-15 18:47:14 +0000240 uint32_t this_usage_mask = option_table[num_options].usage_mask;
241 if (this_usage_mask == LLDB_OPT_SET_ALL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000242 {
Jim Ingham86511212010-06-15 18:47:14 +0000243 if (num_option_sets == 0)
244 num_option_sets = 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000245 }
246 else
247 {
Greg Claytonc982c762010-07-09 20:39:50 +0000248 for (uint32_t j = 0; j < LLDB_MAX_NUM_OPTION_SETS; j++)
Jim Ingham86511212010-06-15 18:47:14 +0000249 {
250 if (this_usage_mask & 1 << j)
251 {
252 if (num_option_sets <= j)
253 num_option_sets = j + 1;
254 }
255 }
256 }
257 }
258
259 for (uint32_t opt_set = 0; opt_set < num_option_sets; opt_set++)
260 {
261 uint32_t opt_set_mask;
262
263 opt_set_mask = 1 << opt_set;
264
265 if (opt_set > 0)
266 fprintf (out, "\n");
Greg Claytonc982c762010-07-09 20:39:50 +0000267 fprintf (out, "%*s%s", indent_level, "", name);
Jim Ingham556e6532011-08-16 23:15:02 +0000268 bool is_help_line = false;
Jim Ingham86511212010-06-15 18:47:14 +0000269
270 for (uint32_t i = 0; i < num_options; ++i)
271 {
272 if (option_table[i].usage_mask & opt_set_mask)
273 {
Caroline Ticedeaab222010-10-01 19:59:14 +0000274 CommandArgumentType arg_type = option_table[i].argument_type;
Greg Clayton9d0402b2011-02-20 02:15:07 +0000275 const char *arg_name = SBCommandInterpreter::GetArgumentTypeAsCString (arg_type);
Jim Ingham556e6532011-08-16 23:15:02 +0000276 // This is a bit of a hack, but there's no way to say certain options don't have arguments yet...
277 // so we do it by hand here.
278 if (option_table[i].short_option == 'h')
279 is_help_line = true;
280
Jim Ingham86511212010-06-15 18:47:14 +0000281 if (option_table[i].required)
282 {
283 if (option_table[i].option_has_arg == required_argument)
Greg Clayton9d0402b2011-02-20 02:15:07 +0000284 fprintf (out, " -%c <%s>", option_table[i].short_option, arg_name);
Jim Ingham86511212010-06-15 18:47:14 +0000285 else if (option_table[i].option_has_arg == optional_argument)
Greg Clayton9d0402b2011-02-20 02:15:07 +0000286 fprintf (out, " -%c [<%s>]", option_table[i].short_option, arg_name);
Jim Ingham86511212010-06-15 18:47:14 +0000287 else
288 fprintf (out, " -%c", option_table[i].short_option);
289 }
290 else
291 {
292 if (option_table[i].option_has_arg == required_argument)
Greg Clayton9d0402b2011-02-20 02:15:07 +0000293 fprintf (out, " [-%c <%s>]", option_table[i].short_option, arg_name);
Jim Ingham86511212010-06-15 18:47:14 +0000294 else if (option_table[i].option_has_arg == optional_argument)
Greg Clayton9d0402b2011-02-20 02:15:07 +0000295 fprintf (out, " [-%c [<%s>]]", option_table[i].short_option, arg_name);
Jim Ingham86511212010-06-15 18:47:14 +0000296 else
297 fprintf (out, " [-%c]", option_table[i].short_option);
298 }
299 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000300 }
Jim Inghame64f0dc2011-09-13 23:25:31 +0000301 if (!is_help_line && (opt_set <= last_option_set_with_args))
Jim Ingham556e6532011-08-16 23:15:02 +0000302 fprintf (out, " [[--] <PROGRAM-ARG-1> [<PROGRAM_ARG-2> ...]]");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000303 }
304
305 fprintf (out, "\n\n");
306
307 // Now print out all the detailed information about the various options: long form, short form and help text:
308 // -- long_name <argument>
309 // - short <argument>
310 // help text
311
312 // This variable is used to keep track of which options' info we've printed out, because some options can be in
313 // more than one usage level, but we only want to print the long form of its information once.
314
315 Driver::OptionData::OptionSet options_seen;
316 Driver::OptionData::OptionSet::iterator pos;
317
318 indent_level += 5;
319
Jim Ingham86511212010-06-15 18:47:14 +0000320 for (uint32_t i = 0; i < num_options; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000321 {
322 // Only print this option if we haven't already seen it.
323 pos = options_seen.find (option_table[i].short_option);
324 if (pos == options_seen.end())
325 {
Caroline Ticedeaab222010-10-01 19:59:14 +0000326 CommandArgumentType arg_type = option_table[i].argument_type;
Greg Clayton9d0402b2011-02-20 02:15:07 +0000327 const char *arg_name = SBCommandInterpreter::GetArgumentTypeAsCString (arg_type);
Caroline Ticedeaab222010-10-01 19:59:14 +0000328
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000329 options_seen.insert (option_table[i].short_option);
Greg Claytonc982c762010-07-09 20:39:50 +0000330 fprintf (out, "%*s-%c ", indent_level, "", option_table[i].short_option);
Caroline Ticedeaab222010-10-01 19:59:14 +0000331 if (arg_type != eArgTypeNone)
Greg Clayton9d0402b2011-02-20 02:15:07 +0000332 fprintf (out, "<%s>", arg_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000333 fprintf (out, "\n");
Greg Claytonc982c762010-07-09 20:39:50 +0000334 fprintf (out, "%*s--%s ", indent_level, "", option_table[i].long_option);
Caroline Ticedeaab222010-10-01 19:59:14 +0000335 if (arg_type != eArgTypeNone)
Greg Clayton9d0402b2011-02-20 02:15:07 +0000336 fprintf (out, "<%s>", arg_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000337 fprintf (out, "\n");
338 indent_level += 5;
Greg Claytonc982c762010-07-09 20:39:50 +0000339 OutputFormattedUsageText (out, indent_level, option_table[i].usage_text, screen_width);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000340 indent_level -= 5;
341 fprintf (out, "\n");
342 }
343 }
344
345 indent_level -= 5;
Jim Inghamf0c63b92014-02-05 21:35:09 +0000346
347 fprintf (out, "\n%*sNotes:\n",
348 indent_level, "");
349 indent_level += 5;
350
Ed Mastea6b38062015-12-16 15:49:38 +0000351 fprintf (out, "\n%*sMultiple \"-s\" and \"-o\" options can be provided. They will be processed"
352 "\n%*sfrom left to right in order, with the source files and commands"
353 "\n%*sinterleaved. The same is true of the \"-S\" and \"-O\" options. The before"
354 "\n%*sfile and after file sets can intermixed freely, the command parser will"
355 "\n%*ssort them out. The order of the file specifiers (\"-c\", \"-f\", etc.) is"
356 "\n%*snot significant in this regard.\n\n",
Jim Ingham47ea51f2013-09-17 01:53:35 +0000357 indent_level, "",
358 indent_level, "",
359 indent_level, "",
Ed Mastea6b38062015-12-16 15:49:38 +0000360 indent_level, "",
361 indent_level, "",
Jim Ingham47ea51f2013-09-17 01:53:35 +0000362 indent_level, "");
363
Ed Mastea6b38062015-12-16 15:49:38 +0000364 fprintf (out, "\n%*sIf you don't provide -f then the first argument will be the file to be"
365 "\n%*sdebugged which means that '%s -- <filename> [<ARG1> [<ARG2>]]' also"
366 "\n%*sworks. But remember to end the options with \"--\" if any of your"
367 "\n%*sarguments have a \"-\" in them.\n\n",
Jim Inghama9deaf92011-08-16 23:57:58 +0000368 indent_level, "",
369 indent_level, "",
370 name,
Ed Mastea6b38062015-12-16 15:49:38 +0000371 indent_level, "",
Jim Inghama9deaf92011-08-16 23:57:58 +0000372 indent_level, "");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000373}
374
375void
Greg Claytone0d378b2011-03-24 21:19:54 +0000376BuildGetOptTable (OptionDefinition *expanded_option_table, std::vector<struct option> &getopt_table,
Caroline Tice4ab31c92010-10-12 21:57:09 +0000377 uint32_t num_options)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000378{
379 if (num_options == 0)
380 return;
381
382 uint32_t i;
383 uint32_t j;
384 std::bitset<256> option_seen;
385
Caroline Tice4ab31c92010-10-12 21:57:09 +0000386 getopt_table.resize (num_options + 1);
387
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000388 for (i = 0, j = 0; i < num_options; ++i)
Greg Claytonc982c762010-07-09 20:39:50 +0000389 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000390 char short_opt = expanded_option_table[i].short_option;
Greg Claytonc982c762010-07-09 20:39:50 +0000391
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000392 if (option_seen.test(short_opt) == false)
Greg Claytonc982c762010-07-09 20:39:50 +0000393 {
Caroline Tice4ab31c92010-10-12 21:57:09 +0000394 getopt_table[j].name = expanded_option_table[i].long_option;
395 getopt_table[j].has_arg = expanded_option_table[i].option_has_arg;
396 getopt_table[j].flag = NULL;
397 getopt_table[j].val = expanded_option_table[i].short_option;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000398 option_seen.set(short_opt);
399 ++j;
Greg Claytonc982c762010-07-09 20:39:50 +0000400 }
401 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000402
Caroline Tice4ab31c92010-10-12 21:57:09 +0000403 getopt_table[j].name = NULL;
404 getopt_table[j].has_arg = 0;
405 getopt_table[j].flag = NULL;
406 getopt_table[j].val = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000407
408}
409
Greg Clayton66111032010-06-23 01:19:29 +0000410Driver::OptionData::OptionData () :
Greg Clayton8d846da2010-12-08 22:23:24 +0000411 m_args(),
Greg Clayton66111032010-06-23 01:19:29 +0000412 m_script_lang (lldb::eScriptLanguageDefault),
Johnny Cheneb46f782012-08-15 22:10:42 +0000413 m_core_file (),
Greg Claytonc982c762010-07-09 20:39:50 +0000414 m_crash_log (),
Jim Inghamed3252f2013-09-14 00:20:24 +0000415 m_initial_commands (),
416 m_after_file_commands (),
Jim Ingham4add3b12014-11-19 01:28:13 +0000417 m_after_crash_commands(),
Greg Clayton66111032010-06-23 01:19:29 +0000418 m_debug_mode (false),
Jim Inghamed3252f2013-09-14 00:20:24 +0000419 m_source_quietly(false),
Greg Claytonc982c762010-07-09 20:39:50 +0000420 m_print_version (false),
Jim Inghame2231ac2012-12-21 22:22:26 +0000421 m_print_python_path (false),
Greg Clayton66111032010-06-23 01:19:29 +0000422 m_print_help (false),
Jim Inghame64f0dc2011-09-13 23:25:31 +0000423 m_wait_for(false),
Sean Callanan3e7e9152015-10-20 00:23:46 +0000424 m_repl (false),
425 m_repl_lang (eLanguageTypeUnknown),
426 m_repl_options (),
Jim Inghame64f0dc2011-09-13 23:25:31 +0000427 m_process_name(),
428 m_process_pid(LLDB_INVALID_PROCESS_ID),
Daniel Dunbara08823f2011-10-31 22:50:49 +0000429 m_use_external_editor(false),
Jim Inghamffc9f1d2014-10-14 01:20:07 +0000430 m_batch(false),
Stephen Wilson71c21d12011-04-11 19:41:40 +0000431 m_seen_options()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000432{
Greg Clayton66111032010-06-23 01:19:29 +0000433}
434
435Driver::OptionData::~OptionData ()
436{
437}
438
439void
440Driver::OptionData::Clear ()
441{
Greg Clayton8d846da2010-12-08 22:23:24 +0000442 m_args.clear ();
Greg Clayton66111032010-06-23 01:19:29 +0000443 m_script_lang = lldb::eScriptLanguageDefault;
Jim Inghamed3252f2013-09-14 00:20:24 +0000444 m_initial_commands.clear ();
445 m_after_file_commands.clear ();
Jason Molenda878ae012016-02-19 00:05:17 +0000446
447 // If there is a local .lldbinit, add that to the
448 // list of things to be sourced, if the settings
449 // permit it.
450 SBFileSpec local_lldbinit (".lldbinit", true);
451
452 SBFileSpec homedir_dot_lldb = SBHostOS::GetUserHomeDirectory();
453 homedir_dot_lldb.AppendPathComponent (".lldbinit");
454
455 // Only read .lldbinit in the current working directory
456 // if it's not the same as the .lldbinit in the home
457 // directory (which is already being read in).
458 if (local_lldbinit.Exists()
459 && strcmp (local_lldbinit.GetDirectory(), homedir_dot_lldb.GetDirectory()) != 0)
Jim Ingham4add3b12014-11-19 01:28:13 +0000460 {
461 char path[2048];
462 local_lldbinit.GetPath(path, 2047);
Jason Molenda878ae012016-02-19 00:05:17 +0000463 InitialCmdEntry entry(path, true, true, true);
Jim Ingham0f17c552014-11-22 01:33:22 +0000464 m_after_file_commands.push_back (entry);
Jim Ingham4add3b12014-11-19 01:28:13 +0000465 }
466
Greg Clayton66111032010-06-23 01:19:29 +0000467 m_debug_mode = false;
Jim Inghamed3252f2013-09-14 00:20:24 +0000468 m_source_quietly = false;
Greg Clayton66111032010-06-23 01:19:29 +0000469 m_print_help = false;
470 m_print_version = false;
Jim Inghame2231ac2012-12-21 22:22:26 +0000471 m_print_python_path = false;
Jim Inghame40e4212010-08-30 19:44:40 +0000472 m_use_external_editor = false;
Jim Inghame64f0dc2011-09-13 23:25:31 +0000473 m_wait_for = false;
474 m_process_name.erase();
Jim Inghamffc9f1d2014-10-14 01:20:07 +0000475 m_batch = false;
Jim Ingham4add3b12014-11-19 01:28:13 +0000476 m_after_crash_commands.clear();
477
Jim Inghame64f0dc2011-09-13 23:25:31 +0000478 m_process_pid = LLDB_INVALID_PROCESS_ID;
Greg Clayton66111032010-06-23 01:19:29 +0000479}
480
481void
Jim Ingham22302e52015-07-08 00:59:59 +0000482Driver::OptionData::AddInitialCommand (const char *command, CommandPlacement placement, bool is_file, SBError &error)
Jim Inghamed3252f2013-09-14 00:20:24 +0000483{
Jim Ingham0f17c552014-11-22 01:33:22 +0000484 std::vector<InitialCmdEntry> *command_set;
Jim Ingham4add3b12014-11-19 01:28:13 +0000485 switch (placement)
486 {
487 case eCommandPlacementBeforeFile:
Jim Inghamed3252f2013-09-14 00:20:24 +0000488 command_set = &(m_initial_commands);
Jim Ingham4add3b12014-11-19 01:28:13 +0000489 break;
490 case eCommandPlacementAfterFile:
Jim Inghamed3252f2013-09-14 00:20:24 +0000491 command_set = &(m_after_file_commands);
Jim Ingham4add3b12014-11-19 01:28:13 +0000492 break;
493 case eCommandPlacementAfterCrash:
494 command_set = &(m_after_crash_commands);
495 break;
496 }
Jim Inghamed3252f2013-09-14 00:20:24 +0000497
498 if (is_file)
499 {
500 SBFileSpec file(command);
501 if (file.Exists())
Jason Molenda878ae012016-02-19 00:05:17 +0000502 command_set->push_back (InitialCmdEntry(command, is_file, false));
Jim Inghamed3252f2013-09-14 00:20:24 +0000503 else if (file.ResolveExecutableLocation())
504 {
505 char final_path[PATH_MAX];
506 file.GetPath (final_path, sizeof(final_path));
Jason Molenda878ae012016-02-19 00:05:17 +0000507 command_set->push_back (InitialCmdEntry(final_path, is_file, false));
Jim Inghamed3252f2013-09-14 00:20:24 +0000508 }
509 else
510 error.SetErrorStringWithFormat("file specified in --source (-s) option doesn't exist: '%s'", optarg);
511 }
512 else
Jason Molenda878ae012016-02-19 00:05:17 +0000513 command_set->push_back (InitialCmdEntry(command, is_file, false));
Jim Inghamed3252f2013-09-14 00:20:24 +0000514}
515
516void
Greg Clayton66111032010-06-23 01:19:29 +0000517Driver::ResetOptionValues ()
518{
519 m_option_data.Clear ();
520}
521
522const char *
523Driver::GetFilename() const
524{
Greg Clayton8d846da2010-12-08 22:23:24 +0000525 if (m_option_data.m_args.empty())
Greg Clayton66111032010-06-23 01:19:29 +0000526 return NULL;
Greg Clayton8d846da2010-12-08 22:23:24 +0000527 return m_option_data.m_args.front().c_str();
Greg Clayton66111032010-06-23 01:19:29 +0000528}
529
530const char *
531Driver::GetCrashLogFilename() const
532{
533 if (m_option_data.m_crash_log.empty())
534 return NULL;
535 return m_option_data.m_crash_log.c_str();
536}
537
538lldb::ScriptLanguage
539Driver::GetScriptLanguage() const
540{
541 return m_option_data.m_script_lang;
542}
543
Jim Inghamed3252f2013-09-14 00:20:24 +0000544void
Jim Ingham4add3b12014-11-19 01:28:13 +0000545Driver::WriteCommandsForSourcing (CommandPlacement placement, SBStream &strm)
Greg Clayton66111032010-06-23 01:19:29 +0000546{
Jim Ingham0f17c552014-11-22 01:33:22 +0000547 std::vector<OptionData::InitialCmdEntry> *command_set;
Jim Ingham4add3b12014-11-19 01:28:13 +0000548 switch (placement)
549 {
550 case eCommandPlacementBeforeFile:
551 command_set = &m_option_data.m_initial_commands;
552 break;
553 case eCommandPlacementAfterFile:
554 command_set = &m_option_data.m_after_file_commands;
555 break;
556 case eCommandPlacementAfterCrash:
557 command_set = &m_option_data.m_after_crash_commands;
558 break;
559 }
Jim Inghamed3252f2013-09-14 00:20:24 +0000560
Jim Ingham0f17c552014-11-22 01:33:22 +0000561 for (const auto &command_entry : *command_set)
Jim Inghamed3252f2013-09-14 00:20:24 +0000562 {
Jim Ingham0f17c552014-11-22 01:33:22 +0000563 const char *command = command_entry.contents.c_str();
564 if (command_entry.is_file)
565 {
Jason Molenda878ae012016-02-19 00:05:17 +0000566 // If this command_entry is a file to be sourced, and it's the ./.lldbinit file (the .lldbinit
567 // file in the current working directory), only read it if target.load-cwd-lldbinit is 'true'.
568 if (command_entry.is_cwd_lldbinit_file_read)
569 {
570 SBStringList strlist = m_debugger.GetInternalVariableValue ("target.load-cwd-lldbinit",
571 m_debugger.GetInstanceName());
572 if (strlist.GetSize() == 1 && strcmp (strlist.GetStringAtIndex(0), "warn") == 0)
573 {
574 FILE *output = m_debugger.GetOutputFileHandle ();
575 ::fprintf (output,
576 "There is a .lldbinit file in the current directory which is not being read.\n"
577 "To silence this warning without sourcing in the local .lldbinit,\n"
578 "add the following to the lldbinit file in your home directory:\n"
579 " settings set target.load-cwd-lldbinit false\n"
580 "To allow lldb to source .lldbinit files in the current working directory,\n"
581 "set the value of this variable to true. Only do so if you understand and\n"
582 "accept the security risk.\n");
583 return;
584 }
585 if (strlist.GetSize() == 1 && strcmp (strlist.GetStringAtIndex(0), "false") == 0)
586 {
587 return;
588 }
589 }
Jim Ingham0f17c552014-11-22 01:33:22 +0000590 bool source_quietly = m_option_data.m_source_quietly || command_entry.source_quietly;
591 strm.Printf("command source -s %i '%s'\n", source_quietly, command);
592 }
Greg Clayton06357c92014-07-30 17:38:47 +0000593 else
594 strm.Printf("%s\n", command);
Jim Inghamed3252f2013-09-14 00:20:24 +0000595 }
Greg Clayton66111032010-06-23 01:19:29 +0000596}
597
598bool
599Driver::GetDebugMode() const
600{
601 return m_option_data.m_debug_mode;
602}
603
604
605// Check the arguments that were passed to this program to make sure they are valid and to get their
606// argument values (if any). Return a boolean value indicating whether or not to start up the full
607// debugger (i.e. the Command Interpreter) or not. Return FALSE if the arguments were invalid OR
608// if the user only wanted help or version information.
609
610SBError
Deepak Panickal429222c2013-10-15 15:46:40 +0000611Driver::ParseArgs (int argc, const char *argv[], FILE *out_fh, bool &exiting)
Greg Clayton66111032010-06-23 01:19:29 +0000612{
613 ResetOptionValues ();
614
615 SBCommandReturnObject result;
616
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000617 SBError error;
618 std::string option_string;
619 struct option *long_options = NULL;
Caroline Tice4ab31c92010-10-12 21:57:09 +0000620 std::vector<struct option> long_options_vector;
Greg Claytonc982c762010-07-09 20:39:50 +0000621 uint32_t num_options;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000622
Greg Claytonc982c762010-07-09 20:39:50 +0000623 for (num_options = 0; g_options[num_options].long_option != NULL; ++num_options)
624 /* Do Nothing. */;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000625
626 if (num_options == 0)
627 {
628 if (argc > 1)
629 error.SetErrorStringWithFormat ("invalid number of options");
630 return error;
631 }
632
Caroline Tice4ab31c92010-10-12 21:57:09 +0000633 BuildGetOptTable (g_options, long_options_vector, num_options);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000634
Caroline Tice4ab31c92010-10-12 21:57:09 +0000635 if (long_options_vector.empty())
636 long_options = NULL;
637 else
638 long_options = &long_options_vector.front();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000639
640 if (long_options == NULL)
641 {
642 error.SetErrorStringWithFormat ("invalid long options");
643 return error;
644 }
645
Greg Claytonb7ad58a2013-04-04 20:35:24 +0000646 // Build the option_string argument for call to getopt_long_only.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000647
648 for (int i = 0; long_options[i].name != NULL; ++i)
649 {
650 if (long_options[i].flag == NULL)
651 {
652 option_string.push_back ((char) long_options[i].val);
653 switch (long_options[i].has_arg)
654 {
655 default:
656 case no_argument:
657 break;
658 case required_argument:
659 option_string.push_back (':');
660 break;
661 case optional_argument:
662 option_string.append ("::");
663 break;
664 }
665 }
666 }
667
Jim Ingham06942692011-08-13 00:22:20 +0000668 // This is kind of a pain, but since we make the debugger in the Driver's constructor, we can't
669 // know at that point whether we should read in init files yet. So we don't read them in in the
670 // Driver constructor, then set the flags back to "read them in" here, and then if we see the
671 // "-n" flag, we'll turn it off again. Finally we have to read them in by hand later in the
672 // main loop.
673
674 m_debugger.SkipLLDBInitFiles (false);
675 m_debugger.SkipAppInitFiles (false);
676
Greg Claytonb7ad58a2013-04-04 20:35:24 +0000677 // Prepare for & make calls to getopt_long_only.
Eli Friedmanadb35022010-06-13 19:18:49 +0000678#if __GLIBC__
679 optind = 0;
680#else
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000681 optreset = 1;
682 optind = 1;
Eli Friedmanadb35022010-06-13 19:18:49 +0000683#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000684 int val;
685 while (1)
686 {
687 int long_options_index = -1;
Greg Claytonb7ad58a2013-04-04 20:35:24 +0000688 val = ::getopt_long_only (argc, const_cast<char **>(argv), option_string.c_str(), long_options, &long_options_index);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000689
690 if (val == -1)
691 break;
692 else if (val == '?')
693 {
Greg Clayton66111032010-06-23 01:19:29 +0000694 m_option_data.m_print_help = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000695 error.SetErrorStringWithFormat ("unknown or ambiguous option");
696 break;
697 }
698 else if (val == 0)
699 continue;
700 else
701 {
Greg Clayton66111032010-06-23 01:19:29 +0000702 m_option_data.m_seen_options.insert ((char) val);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000703 if (long_options_index == -1)
704 {
705 for (int i = 0;
706 long_options[i].name || long_options[i].has_arg || long_options[i].flag || long_options[i].val;
707 ++i)
708 {
709 if (long_options[i].val == val)
710 {
711 long_options_index = i;
712 break;
713 }
714 }
715 }
716
717 if (long_options_index >= 0)
718 {
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000719 const int short_option = g_options[long_options_index].short_option;
Greg Clayton66111032010-06-23 01:19:29 +0000720
721 switch (short_option)
722 {
723 case 'h':
724 m_option_data.m_print_help = true;
725 break;
726
727 case 'v':
728 m_option_data.m_print_version = true;
729 break;
730
Jim Inghame2231ac2012-12-21 22:22:26 +0000731 case 'P':
732 m_option_data.m_print_python_path = true;
733 break;
734
Jim Inghamffc9f1d2014-10-14 01:20:07 +0000735 case 'b':
736 m_option_data.m_batch = true;
737 break;
738
Greg Clayton66111032010-06-23 01:19:29 +0000739 case 'c':
Johnny Cheneb46f782012-08-15 22:10:42 +0000740 {
741 SBFileSpec file(optarg);
742 if (file.Exists())
743 {
744 m_option_data.m_core_file = optarg;
745 }
746 else
747 error.SetErrorStringWithFormat("file specified in --core (-c) option doesn't exist: '%s'", optarg);
748 }
Greg Clayton66111032010-06-23 01:19:29 +0000749 break;
Johnny Cheneb46f782012-08-15 22:10:42 +0000750
Jim Inghame40e4212010-08-30 19:44:40 +0000751 case 'e':
752 m_option_data.m_use_external_editor = true;
753 break;
Greg Clayton6eee5aa2010-10-11 01:05:37 +0000754
Jim Inghame64f0dc2011-09-13 23:25:31 +0000755 case 'x':
Greg Clayton6eee5aa2010-10-11 01:05:37 +0000756 m_debugger.SkipLLDBInitFiles (true);
Jim Ingham06942692011-08-13 00:22:20 +0000757 m_debugger.SkipAppInitFiles (true);
Greg Clayton6eee5aa2010-10-11 01:05:37 +0000758 break;
759
Jim Inghamed3252f2013-09-14 00:20:24 +0000760 case 'X':
Michael Sartainc3ce7f272013-05-23 20:47:45 +0000761 m_debugger.SetUseColor (false);
762 break;
763
Greg Clayton66111032010-06-23 01:19:29 +0000764 case 'f':
765 {
766 SBFileSpec file(optarg);
767 if (file.Exists())
Greg Clayton8d846da2010-12-08 22:23:24 +0000768 {
769 m_option_data.m_args.push_back (optarg);
770 }
Caroline Tice428a9a52010-09-10 04:48:55 +0000771 else if (file.ResolveExecutableLocation())
772 {
773 char path[PATH_MAX];
Johnny Chen25f3a3c2011-08-10 22:06:24 +0000774 file.GetPath (path, sizeof(path));
Greg Clayton8d846da2010-12-08 22:23:24 +0000775 m_option_data.m_args.push_back (path);
Caroline Tice428a9a52010-09-10 04:48:55 +0000776 }
Greg Clayton66111032010-06-23 01:19:29 +0000777 else
778 error.SetErrorStringWithFormat("file specified in --file (-f) option doesn't exist: '%s'", optarg);
779 }
780 break;
781
782 case 'a':
783 if (!m_debugger.SetDefaultArchitecture (optarg))
784 error.SetErrorStringWithFormat("invalid architecture in the -a or --arch option: '%s'", optarg);
785 break;
786
787 case 'l':
788 m_option_data.m_script_lang = m_debugger.GetScriptingLanguage (optarg);
789 break;
790
791 case 'd':
792 m_option_data.m_debug_mode = true;
793 break;
794
Jim Inghamf0c63b92014-02-05 21:35:09 +0000795 case 'Q':
Jim Inghamed3252f2013-09-14 00:20:24 +0000796 m_option_data.m_source_quietly = true;
797 break;
798
Jim Ingham661f29d2014-11-20 23:37:13 +0000799 case 'K':
Jim Ingham22302e52015-07-08 00:59:59 +0000800 m_option_data.AddInitialCommand(optarg, eCommandPlacementAfterCrash, true, error);
Jim Ingham4add3b12014-11-19 01:28:13 +0000801 break;
Jim Ingham661f29d2014-11-20 23:37:13 +0000802 case 'k':
Jim Ingham22302e52015-07-08 00:59:59 +0000803 m_option_data.AddInitialCommand(optarg, eCommandPlacementAfterCrash, false, error);
Jim Ingham4add3b12014-11-19 01:28:13 +0000804 break;
805
Jim Inghame64f0dc2011-09-13 23:25:31 +0000806 case 'n':
807 m_option_data.m_process_name = optarg;
808 break;
809
810 case 'w':
811 m_option_data.m_wait_for = true;
812 break;
813
814 case 'p':
815 {
816 char *remainder;
817 m_option_data.m_process_pid = strtol (optarg, &remainder, 0);
818 if (remainder == optarg || *remainder != '\0')
819 error.SetErrorStringWithFormat ("Could not convert process PID: \"%s\" into a pid.",
820 optarg);
821 }
822 break;
Sean Callanan3e7e9152015-10-20 00:23:46 +0000823
824 case 'r':
825 m_option_data.m_repl = true;
826 if (optarg && optarg[0])
827 m_option_data.m_repl_options = optarg;
828 else
829 m_option_data.m_repl_options.clear();
830 break;
831
832 case 'R':
833 m_option_data.m_repl_lang = SBLanguageRuntime::GetLanguageTypeFromString (optarg);
834 if (m_option_data.m_repl_lang == eLanguageTypeUnknown)
835 {
836 error.SetErrorStringWithFormat ("Unrecognized language name: \"%s\"", optarg);
837 }
838 break;
839
Greg Clayton66111032010-06-23 01:19:29 +0000840 case 's':
Jim Ingham22302e52015-07-08 00:59:59 +0000841 m_option_data.AddInitialCommand(optarg, eCommandPlacementAfterFile, true, error);
Greg Clayton66111032010-06-23 01:19:29 +0000842 break;
Jim Inghamed3252f2013-09-14 00:20:24 +0000843 case 'o':
Jim Ingham22302e52015-07-08 00:59:59 +0000844 m_option_data.AddInitialCommand(optarg, eCommandPlacementAfterFile, false, error);
Jim Inghamed3252f2013-09-14 00:20:24 +0000845 break;
846 case 'S':
Jim Ingham22302e52015-07-08 00:59:59 +0000847 m_option_data.AddInitialCommand(optarg, eCommandPlacementBeforeFile, true, error);
Jim Inghamed3252f2013-09-14 00:20:24 +0000848 break;
849 case 'O':
Jim Ingham22302e52015-07-08 00:59:59 +0000850 m_option_data.AddInitialCommand(optarg, eCommandPlacementBeforeFile, false, error);
Jim Inghamed3252f2013-09-14 00:20:24 +0000851 break;
Greg Clayton66111032010-06-23 01:19:29 +0000852 default:
853 m_option_data.m_print_help = true;
854 error.SetErrorStringWithFormat ("unrecognized option %c", short_option);
855 break;
856 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000857 }
858 else
859 {
860 error.SetErrorStringWithFormat ("invalid option with value %i", val);
861 }
862 if (error.Fail())
Caroline Tice4ab31c92010-10-12 21:57:09 +0000863 {
Greg Clayton66111032010-06-23 01:19:29 +0000864 return error;
Caroline Tice4ab31c92010-10-12 21:57:09 +0000865 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000866 }
867 }
Jim Ingham86511212010-06-15 18:47:14 +0000868
Greg Clayton66111032010-06-23 01:19:29 +0000869 if (error.Fail() || m_option_data.m_print_help)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000870 {
871 ShowUsage (out_fh, g_options, m_option_data);
Deepak Panickal429222c2013-10-15 15:46:40 +0000872 exiting = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000873 }
874 else if (m_option_data.m_print_version)
875 {
Greg Clayton66111032010-06-23 01:19:29 +0000876 ::fprintf (out_fh, "%s\n", m_debugger.GetVersionString());
Deepak Panickal429222c2013-10-15 15:46:40 +0000877 exiting = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000878 }
Jim Inghame2231ac2012-12-21 22:22:26 +0000879 else if (m_option_data.m_print_python_path)
880 {
881 SBFileSpec python_file_spec = SBHostOS::GetLLDBPythonPath();
882 if (python_file_spec.IsValid())
883 {
884 char python_path[PATH_MAX];
885 size_t num_chars = python_file_spec.GetPath(python_path, PATH_MAX);
886 if (num_chars < PATH_MAX)
887 {
888 ::fprintf (out_fh, "%s\n", python_path);
889 }
890 else
891 ::fprintf (out_fh, "<PATH TOO LONG>\n");
892 }
893 else
894 ::fprintf (out_fh, "<COULD NOT FIND PATH>\n");
Deepak Panickal429222c2013-10-15 15:46:40 +0000895 exiting = true;
Jim Inghame2231ac2012-12-21 22:22:26 +0000896 }
Jim Inghame64f0dc2011-09-13 23:25:31 +0000897 else if (m_option_data.m_process_name.empty() && m_option_data.m_process_pid == LLDB_INVALID_PROCESS_ID)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000898 {
Greg Clayton8d846da2010-12-08 22:23:24 +0000899 // Any arguments that are left over after option parsing are for
900 // the program. If a file was specified with -f then the filename
901 // is already in the m_option_data.m_args array, and any remaining args
902 // are arguments for the inferior program. If no file was specified with
903 // -f, then what is left is the program name followed by any arguments.
904
Greg Claytonb7ad58a2013-04-04 20:35:24 +0000905 // Skip any options we consumed with getopt_long_only
Greg Clayton8d846da2010-12-08 22:23:24 +0000906 argc -= optind;
907 argv += optind;
908
909 if (argc > 0)
910 {
911 for (int arg_idx=0; arg_idx<argc; ++arg_idx)
912 {
913 const char *arg = argv[arg_idx];
914 if (arg)
915 m_option_data.m_args.push_back (arg);
916 }
917 }
918
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000919 }
Jim Inghame64f0dc2011-09-13 23:25:31 +0000920 else
921 {
Greg Claytonb7ad58a2013-04-04 20:35:24 +0000922 // Skip any options we consumed with getopt_long_only
Jim Inghame64f0dc2011-09-13 23:25:31 +0000923 argc -= optind;
Greg Clayton23f59502012-07-17 03:23:13 +0000924 //argv += optind; // Commented out to keep static analyzer happy
Jim Inghame64f0dc2011-09-13 23:25:31 +0000925
926 if (argc > 0)
927 ::fprintf (out_fh, "Warning: program arguments are ignored when attaching.\n");
928 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000929
Greg Clayton66111032010-06-23 01:19:29 +0000930 return error;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000931}
932
Jim Ingham4add3b12014-11-19 01:28:13 +0000933static ::FILE *
934PrepareCommandsForSourcing (const char *commands_data, size_t commands_size, int fds[2])
935{
936 enum PIPES { READ, WRITE }; // Constants 0 and 1 for READ and WRITE
937
Jim Ingham4add3b12014-11-19 01:28:13 +0000938 ::FILE *commands_file = NULL;
939 fds[0] = -1;
940 fds[1] = -1;
941 int err = 0;
942#ifdef _WIN32
943 err = _pipe(fds, commands_size, O_BINARY);
944#else
945 err = pipe(fds);
946#endif
947 if (err == 0)
948 {
949 ssize_t nrwr = write(fds[WRITE], commands_data, commands_size);
950 if (nrwr < 0)
951 {
Adrian McCarthye704c4f2015-03-30 17:46:36 +0000952 fprintf(stderr, "error: write(%i, %p, %" PRIu64 ") failed (errno = %i) "
Jim Ingham4add3b12014-11-19 01:28:13 +0000953 "when trying to open LLDB commands pipe\n",
Saleem Abdulrasool1ee07252016-02-15 21:50:28 +0000954 fds[WRITE], static_cast<const void *>(commands_data),
955 static_cast<uint64_t>(commands_size), errno);
Jim Ingham4add3b12014-11-19 01:28:13 +0000956 }
957 else if (static_cast<size_t>(nrwr) == commands_size)
958 {
959 // Close the write end of the pipe so when we give the read end to
960 // the debugger/command interpreter it will exit when it consumes all
961 // of the data
962#ifdef _WIN32
963 _close(fds[WRITE]); fds[WRITE] = -1;
964#else
965 close(fds[WRITE]); fds[WRITE] = -1;
966#endif
967 // Now open the read file descriptor in a FILE * that we can give to
968 // the debugger as an input handle
969 commands_file = fdopen(fds[READ], "r");
970 if (commands_file)
971 {
972 fds[READ] = -1; // The FILE * 'commands_file' now owns the read descriptor
973 // Hand ownership if the FILE * over to the debugger for "commands_file".
974 }
975 else
976 {
977 fprintf(stderr,
978 "error: fdopen(%i, \"r\") failed (errno = %i) when "
979 "trying to open LLDB commands pipe\n",
980 fds[READ], errno);
Jim Ingham4add3b12014-11-19 01:28:13 +0000981 }
982 }
983 }
984 else
985 {
986 fprintf(stderr, "error: can't create pipe file descriptors for LLDB commands\n");
Jim Ingham4add3b12014-11-19 01:28:13 +0000987 }
988
989 return commands_file;
990}
991
992void
993CleanupAfterCommandSourcing (int fds[2])
994{
995 enum PIPES { READ, WRITE }; // Constants 0 and 1 for READ and WRITE
996
997 // Close any pipes that we still have ownership of
998 if ( fds[WRITE] != -1)
999 {
1000#ifdef _WIN32
1001 _close(fds[WRITE]); fds[WRITE] = -1;
1002#else
1003 close(fds[WRITE]); fds[WRITE] = -1;
1004#endif
1005
1006 }
1007
1008 if ( fds[READ] != -1)
1009 {
1010#ifdef _WIN32
1011 _close(fds[READ]); fds[READ] = -1;
1012#else
1013 close(fds[READ]); fds[READ] = -1;
1014#endif
1015 }
1016
1017}
1018
Pavel Labathaa1ae6f2015-03-05 19:17:56 +00001019std::string
1020EscapeString (std::string arg)
1021{
1022 std::string::size_type pos = 0;
1023 while ((pos = arg.find_first_of("\"\\", pos)) != std::string::npos)
1024 {
1025 arg.insert (pos, 1, '\\');
1026 pos += 2;
1027 }
1028 return '"' + arg + '"';
1029}
1030
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001031void
1032Driver::MainLoop ()
1033{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001034 if (::tcgetattr(STDIN_FILENO, &g_old_stdin_termios) == 0)
Greg Claytonf571b892012-02-02 19:28:31 +00001035 {
1036 g_old_stdin_termios_is_valid = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001037 atexit (reset_stdin_termios);
Greg Claytonf571b892012-02-02 19:28:31 +00001038 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001039
Adrian McCarthyf6034c42016-04-14 23:31:17 +00001040#ifndef _MSC_VER
1041 // Disabling stdin buffering with MSVC's 2015 CRT exposes a bug in fgets
1042 // which causes it to miss newlines depending on whether there have been an
1043 // odd or even number of characters. Bug has been reported to MS via Connect.
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001044 ::setbuf (stdin, NULL);
Adrian McCarthyf6034c42016-04-14 23:31:17 +00001045#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001046 ::setbuf (stdout, NULL);
1047
Greg Clayton66111032010-06-23 01:19:29 +00001048 m_debugger.SetErrorFileHandle (stderr, false);
1049 m_debugger.SetOutputFileHandle (stdout, false);
Greg Clayton06357c92014-07-30 17:38:47 +00001050 m_debugger.SetInputFileHandle (stdin, false); // Don't take ownership of STDIN yet...
1051
Jim Inghame40e4212010-08-30 19:44:40 +00001052 m_debugger.SetUseExternalEditor(m_option_data.m_use_external_editor);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001053
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001054 struct winsize window_size;
1055 if (isatty (STDIN_FILENO)
1056 && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0)
1057 {
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001058 if (window_size.ws_col > 0)
Greg Claytona7015092010-09-18 01:14:36 +00001059 m_debugger.SetTerminalWidth (window_size.ws_col);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001060 }
1061
Greg Clayton44d93782014-01-27 23:43:24 +00001062 SBCommandInterpreter sb_interpreter = m_debugger.GetCommandInterpreter();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001063
Greg Clayton44d93782014-01-27 23:43:24 +00001064 // Before we handle any options from the command line, we parse the
1065 // .lldbinit file in the user's home directory.
1066 SBCommandReturnObject result;
1067 sb_interpreter.SourceInitFileInHomeDirectory(result);
1068 if (GetDebugMode())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001069 {
Greg Clayton44d93782014-01-27 23:43:24 +00001070 result.PutError (m_debugger.GetErrorFileHandle());
1071 result.PutOutput (m_debugger.GetOutputFileHandle());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001072 }
Greg Clayton44d93782014-01-27 23:43:24 +00001073
1074 // Now we handle options we got from the command line
Ed Mastef8314532014-07-30 19:26:11 +00001075 SBStream commands_stream;
Greg Clayton06357c92014-07-30 17:38:47 +00001076
Greg Clayton44d93782014-01-27 23:43:24 +00001077 // First source in the commands specified to be run before the file arguments are processed.
Jason Molenda878ae012016-02-19 00:05:17 +00001078 WriteCommandsForSourcing (eCommandPlacementBeforeFile, commands_stream);
Greg Clayton06357c92014-07-30 17:38:47 +00001079
Greg Clayton44d93782014-01-27 23:43:24 +00001080 const size_t num_args = m_option_data.m_args.size();
1081 if (num_args > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001082 {
Jim Ingham5b1fe952014-08-07 23:01:31 +00001083 char arch_name[64];
1084 if (m_debugger.GetDefaultArchitecture (arch_name, sizeof (arch_name)))
Pavel Labathaa1ae6f2015-03-05 19:17:56 +00001085 commands_stream.Printf("target create --arch=%s %s", arch_name, EscapeString(m_option_data.m_args[0]).c_str());
Jim Ingham5b1fe952014-08-07 23:01:31 +00001086 else
Pavel Labathaa1ae6f2015-03-05 19:17:56 +00001087 commands_stream.Printf("target create %s", EscapeString(m_option_data.m_args[0]).c_str());
Jim Ingham5b1fe952014-08-07 23:01:31 +00001088
Greg Clayton06357c92014-07-30 17:38:47 +00001089 if (!m_option_data.m_core_file.empty())
1090 {
Pavel Labathaa1ae6f2015-03-05 19:17:56 +00001091 commands_stream.Printf(" --core %s", EscapeString(m_option_data.m_core_file).c_str());
Greg Clayton06357c92014-07-30 17:38:47 +00001092 }
1093 commands_stream.Printf("\n");
Greg Clayton44d93782014-01-27 23:43:24 +00001094
1095 if (num_args > 1)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001096 {
Greg Clayton06357c92014-07-30 17:38:47 +00001097 commands_stream.Printf ("settings set -- target.run-args ");
Greg Clayton44d93782014-01-27 23:43:24 +00001098 for (size_t arg_idx = 1; arg_idx < num_args; ++arg_idx)
Pavel Labathaa1ae6f2015-03-05 19:17:56 +00001099 commands_stream.Printf(" %s", EscapeString(m_option_data.m_args[arg_idx]).c_str());
Greg Clayton06357c92014-07-30 17:38:47 +00001100 commands_stream.Printf("\n");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001101 }
1102 }
Greg Clayton06357c92014-07-30 17:38:47 +00001103 else if (!m_option_data.m_core_file.empty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001104 {
Pavel Labathaa1ae6f2015-03-05 19:17:56 +00001105 commands_stream.Printf("target create --core %s\n", EscapeString(m_option_data.m_core_file).c_str());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001106 }
Greg Clayton9c0b64c2014-02-06 18:22:44 +00001107 else if (!m_option_data.m_process_name.empty())
1108 {
Pavel Labathaa1ae6f2015-03-05 19:17:56 +00001109 commands_stream.Printf ("process attach --name %s", EscapeString(m_option_data.m_process_name).c_str());
Greg Clayton06357c92014-07-30 17:38:47 +00001110
1111 if (m_option_data.m_wait_for)
1112 commands_stream.Printf(" --waitfor");
1113
1114 commands_stream.Printf("\n");
1115
Greg Clayton9c0b64c2014-02-06 18:22:44 +00001116 }
1117 else if (LLDB_INVALID_PROCESS_ID != m_option_data.m_process_pid)
1118 {
Greg Clayton06357c92014-07-30 17:38:47 +00001119 commands_stream.Printf ("process attach --pid %" PRIu64 "\n", m_option_data.m_process_pid);
Greg Clayton9c0b64c2014-02-06 18:22:44 +00001120 }
Greg Clayton44d93782014-01-27 23:43:24 +00001121
Jim Ingham4add3b12014-11-19 01:28:13 +00001122 WriteCommandsForSourcing(eCommandPlacementAfterFile, commands_stream);
Greg Clayton06357c92014-07-30 17:38:47 +00001123
Greg Clayton44d93782014-01-27 23:43:24 +00001124 if (GetDebugMode())
1125 {
1126 result.PutError(m_debugger.GetErrorFileHandle());
1127 result.PutOutput(m_debugger.GetOutputFileHandle());
1128 }
1129
1130 bool handle_events = true;
1131 bool spawn_thread = false;
Greg Clayton06357c92014-07-30 17:38:47 +00001132
Sean Callanan3e7e9152015-10-20 00:23:46 +00001133 if (m_option_data.m_repl)
Greg Clayton06357c92014-07-30 17:38:47 +00001134 {
Sean Callanan3e7e9152015-10-20 00:23:46 +00001135 const char *repl_options = NULL;
1136 if (!m_option_data.m_repl_options.empty())
1137 repl_options = m_option_data.m_repl_options.c_str();
1138 SBError error (m_debugger.RunREPL(m_option_data.m_repl_lang, repl_options));
1139 if (error.Fail())
Greg Clayton49668762014-08-01 18:32:07 +00001140 {
Sean Callanan3e7e9152015-10-20 00:23:46 +00001141 const char *error_cstr = error.GetCString();
1142 if (error_cstr && error_cstr[0])
1143 fprintf (stderr, "error: %s\n", error_cstr);
1144 else
1145 fprintf (stderr, "error: %u\n", error.GetError());
Greg Clayton06357c92014-07-30 17:38:47 +00001146 }
1147 }
Sean Callanan3e7e9152015-10-20 00:23:46 +00001148 else
Jim Ingham26c7bf92014-10-11 00:38:27 +00001149 {
Sean Callanan3e7e9152015-10-20 00:23:46 +00001150 // Check if we have any data in the commands stream, and if so, save it to a temp file
1151 // so we can then run the command interpreter using the file contents.
1152 const char *commands_data = commands_stream.GetData();
1153 const size_t commands_size = commands_stream.GetSize();
1154
1155 // The command file might have requested that we quit, this variable will track that.
1156 bool quit_requested = false;
1157 bool stopped_for_crash = false;
1158 if (commands_data && commands_size)
1159 {
1160 int initial_commands_fds[2];
1161 bool success = true;
1162 FILE *commands_file = PrepareCommandsForSourcing (commands_data, commands_size, initial_commands_fds);
1163 if (commands_file)
1164 {
1165 m_debugger.SetInputFileHandle (commands_file, true);
1166
1167 // Set the debugger into Sync mode when running the command file. Otherwise command files
1168 // that run the target won't run in a sensible way.
1169 bool old_async = m_debugger.GetAsync();
1170 m_debugger.SetAsync(false);
1171 int num_errors;
1172
1173 SBCommandInterpreterRunOptions options;
1174 options.SetStopOnError (true);
1175 if (m_option_data.m_batch)
1176 options.SetStopOnCrash (true);
1177
1178 m_debugger.RunCommandInterpreter(handle_events,
1179 spawn_thread,
1180 options,
1181 num_errors,
1182 quit_requested,
1183 stopped_for_crash);
1184
1185 if (m_option_data.m_batch && stopped_for_crash && !m_option_data.m_after_crash_commands.empty())
1186 {
1187 int crash_command_fds[2];
1188 SBStream crash_commands_stream;
1189 WriteCommandsForSourcing (eCommandPlacementAfterCrash, crash_commands_stream);
1190 const char *crash_commands_data = crash_commands_stream.GetData();
1191 const size_t crash_commands_size = crash_commands_stream.GetSize();
1192 commands_file = PrepareCommandsForSourcing (crash_commands_data, crash_commands_size, crash_command_fds);
1193 if (commands_file)
1194 {
1195 bool local_quit_requested;
1196 bool local_stopped_for_crash;
1197 m_debugger.SetInputFileHandle (commands_file, true);
1198
1199 m_debugger.RunCommandInterpreter(handle_events,
1200 spawn_thread,
1201 options,
1202 num_errors,
1203 local_quit_requested,
1204 local_stopped_for_crash);
1205 if (local_quit_requested)
1206 quit_requested = true;
1207
1208 }
1209 }
1210 m_debugger.SetAsync(old_async);
1211 }
1212 else
1213 success = false;
1214
1215 // Close any pipes that we still have ownership of
1216 CleanupAfterCommandSourcing(initial_commands_fds);
1217
1218 // Something went wrong with command pipe
1219 if (!success)
1220 {
1221 exit(1);
1222 }
1223
1224 }
1225
1226 // Now set the input file handle to STDIN and run the command
1227 // interpreter again in interactive mode and let the debugger
1228 // take ownership of stdin
1229
1230 bool go_interactive = true;
1231 if (quit_requested)
1232 go_interactive = false;
1233 else if (m_option_data.m_batch && !stopped_for_crash)
1234 go_interactive = false;
1235
1236 if (go_interactive)
1237 {
1238 m_debugger.SetInputFileHandle (stdin, true);
1239 m_debugger.RunCommandInterpreter(handle_events, spawn_thread);
1240 }
Jim Ingham26c7bf92014-10-11 00:38:27 +00001241 }
Greg Clayton44d93782014-01-27 23:43:24 +00001242
1243 reset_stdin_termios();
1244 fclose (stdin);
1245
1246 SBDebugger::Destroy (m_debugger);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001247}
1248
Greg Clayton44d93782014-01-27 23:43:24 +00001249
Jim Inghamc46fe7c2013-02-22 22:56:55 +00001250void
1251Driver::ResizeWindow (unsigned short col)
1252{
1253 GetDebugger().SetTerminalWidth (col);
Jim Inghamc46fe7c2013-02-22 22:56:55 +00001254}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001255
Caroline Ticedd759852010-09-09 17:45:09 +00001256void
1257sigwinch_handler (int signo)
1258{
1259 struct winsize window_size;
1260 if (isatty (STDIN_FILENO)
1261 && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0)
1262 {
Jim Ingham57190ba2012-04-26 21:39:32 +00001263 if ((window_size.ws_col > 0) && g_driver != NULL)
Caroline Ticedd759852010-09-09 17:45:09 +00001264 {
Jim Inghamc46fe7c2013-02-22 22:56:55 +00001265 g_driver->ResizeWindow (window_size.ws_col);
Caroline Ticedd759852010-09-09 17:45:09 +00001266 }
1267 }
1268}
1269
Caroline Ticeefed6132010-11-19 20:47:54 +00001270void
1271sigint_handler (int signo)
1272{
1273 static bool g_interrupt_sent = false;
1274 if (g_driver)
1275 {
1276 if (!g_interrupt_sent)
1277 {
1278 g_interrupt_sent = true;
1279 g_driver->GetDebugger().DispatchInputInterrupt();
1280 g_interrupt_sent = false;
1281 return;
1282 }
1283 }
1284
1285 exit (signo);
1286}
1287
Jim Inghamc5917d92012-11-30 20:23:19 +00001288void
1289sigtstp_handler (int signo)
1290{
Pavel Labathbb5c39d2016-04-11 16:40:09 +00001291 if (g_driver)
1292 g_driver->GetDebugger().SaveInputTerminalState();
1293
Jim Inghamc5917d92012-11-30 20:23:19 +00001294 signal (signo, SIG_DFL);
1295 kill (getpid(), signo);
1296 signal (signo, sigtstp_handler);
1297}
1298
1299void
1300sigcont_handler (int signo)
1301{
Pavel Labathbb5c39d2016-04-11 16:40:09 +00001302 if (g_driver)
1303 g_driver->GetDebugger().RestoreInputTerminalState();
1304
Jim Inghamc5917d92012-11-30 20:23:19 +00001305 signal (signo, SIG_DFL);
1306 kill (getpid(), signo);
1307 signal (signo, sigcont_handler);
1308}
1309
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001310int
Zachary Turner190fadc2016-03-22 17:58:09 +00001311#ifdef WIN32
1312wmain(int argc, wchar_t const *wargv[])
1313#else
1314main(int argc, char const *argv[])
1315#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001316{
Zachary Turner190fadc2016-03-22 17:58:09 +00001317#ifdef _WIN32
1318 // Convert wide arguments to UTF-8
1319 std::vector<std::string> argvStrings(argc);
1320 std::vector<const char *> argvPointers(argc);
1321 for (int i = 0; i != argc; ++i)
1322 {
1323 llvm::convertWideToUTF8(wargv[i], argvStrings[i]);
1324 argvPointers[i] = argvStrings[i].c_str();
1325 }
1326 const char **argv = argvPointers.data();
Zachary Turner29365da2016-03-18 23:47:48 +00001327#endif
Caroline Ticedd759852010-09-09 17:45:09 +00001328
Zachary Turner190fadc2016-03-22 17:58:09 +00001329 SBDebugger::Initialize();
Greg Clayton66111032010-06-23 01:19:29 +00001330
Zachary Turner190fadc2016-03-22 17:58:09 +00001331 SBHostOS::ThreadCreated("<lldb.driver.main-thread>");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001332
Zachary Turner190fadc2016-03-22 17:58:09 +00001333 signal(SIGINT, sigint_handler);
1334#if !defined(_MSC_VER)
1335 signal(SIGPIPE, SIG_IGN);
1336 signal(SIGWINCH, sigwinch_handler);
1337 signal(SIGTSTP, sigtstp_handler);
1338 signal(SIGCONT, sigcont_handler);
1339#endif
1340
1341 // Create a scope for driver so that the driver object will destroy itself
1342 // before SBDebugger::Terminate() is called.
1343 {
1344 Driver driver;
1345
1346 bool exiting = false;
1347 SBError error(driver.ParseArgs(argc, argv, stdout, exiting));
1348 if (error.Fail())
1349 {
1350 const char *error_cstr = error.GetCString();
1351 if (error_cstr)
1352 ::fprintf(stderr, "error: %s\n", error_cstr);
1353 }
1354 else if (!exiting)
1355 {
1356 driver.MainLoop();
1357 }
1358 }
1359
1360 SBDebugger::Terminate();
1361 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001362}