blob: 71cefbd305b35f042f4b726abcad58a14485d1b8 [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
Deepak Panickal429222c2013-10-15 15:46:40 +000030#include <thread>
Jim Inghame6bc6cb2012-02-08 05:23:15 +000031#include "lldb/API/SBBreakpoint.h"
Eli Friedmana382d472010-06-09 09:50:17 +000032#include "lldb/API/SBCommandInterpreter.h"
33#include "lldb/API/SBCommandReturnObject.h"
34#include "lldb/API/SBCommunication.h"
35#include "lldb/API/SBDebugger.h"
36#include "lldb/API/SBEvent.h"
37#include "lldb/API/SBHostOS.h"
Sean Callanan3e7e9152015-10-20 00:23:46 +000038#include "lldb/API/SBLanguageRuntime.h"
Eli Friedmana382d472010-06-09 09:50:17 +000039#include "lldb/API/SBListener.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"
44#include "lldb/API/SBProcess.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000045
Todd Fialab82ad2a2014-09-15 15:17:13 +000046#if !defined(__APPLE__)
Zachary Turner40a069a2014-09-11 20:26:49 +000047#include "llvm/Support/DataTypes.h"
Todd Fialab82ad2a2014-09-15 15:17:13 +000048#endif
Zachary Turner40a069a2014-09-11 20:26:49 +000049
Chris Lattner30fdc8d2010-06-08 16:52:24 +000050using namespace lldb;
51
52static void reset_stdin_termios ();
Greg Claytonf571b892012-02-02 19:28:31 +000053static bool g_old_stdin_termios_is_valid = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000054static struct termios g_old_stdin_termios;
55
Caroline Ticeefed6132010-11-19 20:47:54 +000056static Driver *g_driver = NULL;
Caroline Ticedd759852010-09-09 17:45:09 +000057
Chris Lattner30fdc8d2010-06-08 16:52:24 +000058// In the Driver::MainLoop, we change the terminal settings. This function is
59// added as an atexit handler to make sure we clean them up.
60static void
61reset_stdin_termios ()
62{
Greg Claytonf571b892012-02-02 19:28:31 +000063 if (g_old_stdin_termios_is_valid)
64 {
65 g_old_stdin_termios_is_valid = false;
66 ::tcsetattr (STDIN_FILENO, TCSANOW, &g_old_stdin_termios);
67 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000068}
69
Greg Claytone0d378b2011-03-24 21:19:54 +000070typedef struct
Chris Lattner30fdc8d2010-06-08 16:52:24 +000071{
Greg Claytone0d378b2011-03-24 21:19:54 +000072 uint32_t usage_mask; // Used to mark options that can be used together. If (1 << n & usage_mask) != 0
73 // then this option belongs to option set n.
74 bool required; // This option is required (in the current usage level)
75 const char * long_option; // Full name for this option.
Greg Clayton3bcdfc02012-12-04 00:32:51 +000076 int short_option; // Single character for this option.
Greg Claytone0d378b2011-03-24 21:19:54 +000077 int option_has_arg; // no_argument, required_argument or optional_argument
Greg Claytonab65b342011-04-13 22:47:15 +000078 uint32_t completion_type; // Cookie the option class can use to do define the argument completion.
Greg Claytone0d378b2011-03-24 21:19:54 +000079 lldb::CommandArgumentType argument_type; // Type of argument this option takes
80 const char * usage_text; // Full text explaining what this options does and what (if any) argument to
81 // pass it.
82} OptionDefinition;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000083
Jim Inghame64f0dc2011-09-13 23:25:31 +000084#define LLDB_3_TO_5 LLDB_OPT_SET_3|LLDB_OPT_SET_4|LLDB_OPT_SET_5
85#define LLDB_4_TO_5 LLDB_OPT_SET_4|LLDB_OPT_SET_5
86
Greg Claytone0d378b2011-03-24 21:19:54 +000087static OptionDefinition g_options[] =
88{
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +000089 { LLDB_OPT_SET_1, true , "help" , 'h', no_argument , 0, eArgTypeNone,
Jim Ingham12e9a202011-09-15 21:30:02 +000090 "Prints out the usage information for the LLDB debugger." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +000091 { LLDB_OPT_SET_2, true , "version" , 'v', no_argument , 0, eArgTypeNone,
Jim Ingham12e9a202011-09-15 21:30:02 +000092 "Prints out the current version number of the LLDB debugger." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +000093 { LLDB_OPT_SET_3, true , "arch" , 'a', required_argument, 0, eArgTypeArchitecture,
Jim Ingham12e9a202011-09-15 21:30:02 +000094 "Tells the debugger to use the specified architecture when starting and running the program. <architecture> must "
95 "be one of the architectures for which the program was compiled." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +000096 { LLDB_OPT_SET_3, true , "file" , 'f', required_argument, 0, eArgTypeFilename,
Jim Ingham12e9a202011-09-15 21:30:02 +000097 "Tells the debugger to use the file <filename> as the program to be debugged." },
Jason Molenda67c3cf52012-10-24 03:29:40 +000098 { LLDB_OPT_SET_3, false, "core" , 'c', required_argument, 0, eArgTypeFilename,
Johnny Cheneb46f782012-08-15 22:10:42 +000099 "Tells the debugger to use the fullpath to <path> as the core file." },
Jim Inghamf0c63b92014-02-05 21:35:09 +0000100 { LLDB_OPT_SET_5, true , "attach-pid" , 'p', required_argument, 0, eArgTypePid,
101 "Tells the debugger to attach to a process with the given pid." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +0000102 { LLDB_OPT_SET_4, true , "attach-name" , 'n', required_argument, 0, eArgTypeProcessName,
Jim Ingham12e9a202011-09-15 21:30:02 +0000103 "Tells the debugger to attach to a process with the given name." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +0000104 { LLDB_OPT_SET_4, true , "wait-for" , 'w', no_argument , 0, eArgTypeNone,
Jim Ingham12e9a202011-09-15 21:30:02 +0000105 "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 +0000106 { LLDB_3_TO_5, false, "source" , 's', required_argument, 0, eArgTypeFilename,
Jim Ingham47ea51f2013-09-17 01:53:35 +0000107 "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 +0000108 { LLDB_3_TO_5, false, "one-line" , 'o', required_argument, 0, eArgTypeNone,
Jim Ingham47ea51f2013-09-17 01:53:35 +0000109 "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 +0000110 { LLDB_3_TO_5, false, "source-before-file" , 'S', required_argument, 0, eArgTypeFilename,
Jim Ingham47ea51f2013-09-17 01:53:35 +0000111 "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 +0000112 { LLDB_3_TO_5, false, "one-line-before-file" , 'O', required_argument, 0, eArgTypeNone,
Jim Ingham47ea51f2013-09-17 01:53:35 +0000113 "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 +0000114 { LLDB_3_TO_5, false, "one-line-on-crash" , 'k', required_argument, 0, eArgTypeNone,
115 "When in batch mode, tells the debugger to execute this one-line lldb command if the target crashes." },
116 { LLDB_3_TO_5, false, "source-on-crash" , 'K', required_argument, 0, eArgTypeFilename,
117 "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 +0000118 { LLDB_3_TO_5, false, "source-quietly" , 'Q', no_argument , 0, eArgTypeNone,
Jim Inghamffc9f1d2014-10-14 01:20:07 +0000119 "Tells the debugger to execute this one-line lldb command before any file provided on the command line has been loaded." },
120 { LLDB_3_TO_5, false, "batch" , 'b', no_argument , 0, eArgTypeNone,
121 "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, "
122 "the debugger will return to the interactive prompt at the place of the crash." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +0000123 { LLDB_3_TO_5, false, "editor" , 'e', no_argument , 0, eArgTypeNone,
Jim Ingham12e9a202011-09-15 21:30:02 +0000124 "Tells the debugger to open source files using the host's \"external editor\" mechanism." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +0000125 { LLDB_3_TO_5, false, "no-lldbinit" , 'x', no_argument , 0, eArgTypeNone,
Jim Ingham12e9a202011-09-15 21:30:02 +0000126 "Do not automatically parse any '.lldbinit' files." },
Jim Inghamed3252f2013-09-14 00:20:24 +0000127 { LLDB_3_TO_5, false, "no-use-colors" , 'X', no_argument , 0, eArgTypeNone,
Michael Sartainc3ce7f272013-05-23 20:47:45 +0000128 "Do not use colors." },
129 { LLDB_OPT_SET_6, true , "python-path" , 'P', no_argument , 0, eArgTypeNone,
Jim Inghame2231ac2012-12-21 22:22:26 +0000130 "Prints out the path to the lldb.py file for this version of lldb." },
Jim Inghamf0c63b92014-02-05 21:35:09 +0000131 { LLDB_3_TO_5, false, "script-language", 'l', required_argument, 0, eArgTypeScriptLang,
132 "Tells the debugger to use the specified scripting language for user-defined scripts, rather than the default. "
133 "Valid scripting languages that can be specified include Python, Perl, Ruby and Tcl. Currently only the Python "
134 "extensions have been implemented." },
135 { LLDB_3_TO_5, false, "debug" , 'd', no_argument , 0, eArgTypeNone,
136 "Tells the debugger to print out extra information for debugging itself." },
Sean Callanan3e7e9152015-10-20 00:23:46 +0000137 { LLDB_OPT_SET_7, true , "repl" , 'r', optional_argument, 0, eArgTypeNone,
138 "Runs lldb in REPL mode with a stub process." },
139 { LLDB_OPT_SET_7, true , "repl-language" , 'R', required_argument, 0, eArgTypeNone,
140 "Chooses the language for the REPL." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +0000141 { 0, false, NULL , 0 , 0 , 0, eArgTypeNone, NULL }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000142};
143
Jim Inghame64f0dc2011-09-13 23:25:31 +0000144static const uint32_t last_option_set_with_args = 2;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000145
146Driver::Driver () :
147 SBBroadcaster ("Driver"),
Jim Ingham06942692011-08-13 00:22:20 +0000148 m_debugger (SBDebugger::Create(false)),
Greg Clayton44d93782014-01-27 23:43:24 +0000149 m_option_data ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000150{
Greg Claytonfc3f0272011-05-29 04:06:55 +0000151 // We want to be able to handle CTRL+D in the terminal to have it terminate
152 // certain input
153 m_debugger.SetCloseInputOnEOF (false);
Caroline Ticeefed6132010-11-19 20:47:54 +0000154 g_driver = this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000155}
156
157Driver::~Driver ()
158{
Caroline Ticeefed6132010-11-19 20:47:54 +0000159 g_driver = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000160}
161
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000162
Greg Claytonc982c762010-07-09 20:39:50 +0000163// This function takes INDENT, which tells how many spaces to output at the front
164// of each line; TEXT, which is the text that is to be output. It outputs the
165// text, on multiple lines if necessary, to RESULT, with INDENT spaces at the
166// front of each line. It breaks lines on spaces, tabs or newlines, shortening
167// the line if necessary to not break in the middle of a word. It assumes that
168// each output line should contain a maximum of OUTPUT_MAX_COLUMNS characters.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000169
170void
Greg Claytonc982c762010-07-09 20:39:50 +0000171OutputFormattedUsageText (FILE *out, int indent, const char *text, int output_max_columns)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000172{
173 int len = strlen (text);
174 std::string text_string (text);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000175
176 // Force indentation to be reasonable.
177 if (indent >= output_max_columns)
178 indent = 0;
179
180 // Will it all fit on one line?
181
182 if (len + indent < output_max_columns)
183 // Output as a single line
Greg Claytonc982c762010-07-09 20:39:50 +0000184 fprintf (out, "%*s%s\n", indent, "", text);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000185 else
186 {
187 // We need to break it up into multiple lines.
188 int text_width = output_max_columns - indent - 1;
189 int start = 0;
190 int end = start;
191 int final_end = len;
192 int sub_len;
193
194 while (end < final_end)
195 {
196 // Dont start the 'text' on a space, since we're already outputting the indentation.
197 while ((start < final_end) && (text[start] == ' '))
198 start++;
199
200 end = start + text_width;
201 if (end > final_end)
202 end = final_end;
203 else
204 {
205 // If we're not at the end of the text, make sure we break the line on white space.
206 while (end > start
207 && text[end] != ' ' && text[end] != '\t' && text[end] != '\n')
208 end--;
209 }
210 sub_len = end - start;
211 std::string substring = text_string.substr (start, sub_len);
Greg Claytonc982c762010-07-09 20:39:50 +0000212 fprintf (out, "%*s%s\n", indent, "", substring.c_str());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000213 start = end + 1;
214 }
215 }
216}
217
218void
Greg Claytone0d378b2011-03-24 21:19:54 +0000219ShowUsage (FILE *out, OptionDefinition *option_table, Driver::OptionData data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000220{
221 uint32_t screen_width = 80;
222 uint32_t indent_level = 0;
223 const char *name = "lldb";
Jim Ingham86511212010-06-15 18:47:14 +0000224
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000225 fprintf (out, "\nUsage:\n\n");
226
227 indent_level += 2;
228
229
230 // First, show each usage level set of options, e.g. <cmd> [options-for-level-0]
231 // <cmd> [options-for-level-1]
232 // etc.
233
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000234 uint32_t num_options;
Jim Ingham86511212010-06-15 18:47:14 +0000235 uint32_t num_option_sets = 0;
236
237 for (num_options = 0; option_table[num_options].long_option != NULL; ++num_options)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000238 {
Jim Ingham86511212010-06-15 18:47:14 +0000239 uint32_t this_usage_mask = option_table[num_options].usage_mask;
240 if (this_usage_mask == LLDB_OPT_SET_ALL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000241 {
Jim Ingham86511212010-06-15 18:47:14 +0000242 if (num_option_sets == 0)
243 num_option_sets = 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000244 }
245 else
246 {
Greg Claytonc982c762010-07-09 20:39:50 +0000247 for (uint32_t j = 0; j < LLDB_MAX_NUM_OPTION_SETS; j++)
Jim Ingham86511212010-06-15 18:47:14 +0000248 {
249 if (this_usage_mask & 1 << j)
250 {
251 if (num_option_sets <= j)
252 num_option_sets = j + 1;
253 }
254 }
255 }
256 }
257
258 for (uint32_t opt_set = 0; opt_set < num_option_sets; opt_set++)
259 {
260 uint32_t opt_set_mask;
261
262 opt_set_mask = 1 << opt_set;
263
264 if (opt_set > 0)
265 fprintf (out, "\n");
Greg Claytonc982c762010-07-09 20:39:50 +0000266 fprintf (out, "%*s%s", indent_level, "", name);
Jim Ingham556e6532011-08-16 23:15:02 +0000267 bool is_help_line = false;
Jim Ingham86511212010-06-15 18:47:14 +0000268
269 for (uint32_t i = 0; i < num_options; ++i)
270 {
271 if (option_table[i].usage_mask & opt_set_mask)
272 {
Caroline Ticedeaab222010-10-01 19:59:14 +0000273 CommandArgumentType arg_type = option_table[i].argument_type;
Greg Clayton9d0402b2011-02-20 02:15:07 +0000274 const char *arg_name = SBCommandInterpreter::GetArgumentTypeAsCString (arg_type);
Jim Ingham556e6532011-08-16 23:15:02 +0000275 // This is a bit of a hack, but there's no way to say certain options don't have arguments yet...
276 // so we do it by hand here.
277 if (option_table[i].short_option == 'h')
278 is_help_line = true;
279
Jim Ingham86511212010-06-15 18:47:14 +0000280 if (option_table[i].required)
281 {
282 if (option_table[i].option_has_arg == required_argument)
Greg Clayton9d0402b2011-02-20 02:15:07 +0000283 fprintf (out, " -%c <%s>", option_table[i].short_option, arg_name);
Jim Ingham86511212010-06-15 18:47:14 +0000284 else if (option_table[i].option_has_arg == optional_argument)
Greg Clayton9d0402b2011-02-20 02:15:07 +0000285 fprintf (out, " -%c [<%s>]", option_table[i].short_option, arg_name);
Jim Ingham86511212010-06-15 18:47:14 +0000286 else
287 fprintf (out, " -%c", option_table[i].short_option);
288 }
289 else
290 {
291 if (option_table[i].option_has_arg == required_argument)
Greg Clayton9d0402b2011-02-20 02:15:07 +0000292 fprintf (out, " [-%c <%s>]", option_table[i].short_option, arg_name);
Jim Ingham86511212010-06-15 18:47:14 +0000293 else if (option_table[i].option_has_arg == optional_argument)
Greg Clayton9d0402b2011-02-20 02:15:07 +0000294 fprintf (out, " [-%c [<%s>]]", option_table[i].short_option, arg_name);
Jim Ingham86511212010-06-15 18:47:14 +0000295 else
296 fprintf (out, " [-%c]", option_table[i].short_option);
297 }
298 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000299 }
Jim Inghame64f0dc2011-09-13 23:25:31 +0000300 if (!is_help_line && (opt_set <= last_option_set_with_args))
Jim Ingham556e6532011-08-16 23:15:02 +0000301 fprintf (out, " [[--] <PROGRAM-ARG-1> [<PROGRAM_ARG-2> ...]]");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000302 }
303
304 fprintf (out, "\n\n");
305
306 // Now print out all the detailed information about the various options: long form, short form and help text:
307 // -- long_name <argument>
308 // - short <argument>
309 // help text
310
311 // This variable is used to keep track of which options' info we've printed out, because some options can be in
312 // more than one usage level, but we only want to print the long form of its information once.
313
314 Driver::OptionData::OptionSet options_seen;
315 Driver::OptionData::OptionSet::iterator pos;
316
317 indent_level += 5;
318
Jim Ingham86511212010-06-15 18:47:14 +0000319 for (uint32_t i = 0; i < num_options; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000320 {
321 // Only print this option if we haven't already seen it.
322 pos = options_seen.find (option_table[i].short_option);
323 if (pos == options_seen.end())
324 {
Caroline Ticedeaab222010-10-01 19:59:14 +0000325 CommandArgumentType arg_type = option_table[i].argument_type;
Greg Clayton9d0402b2011-02-20 02:15:07 +0000326 const char *arg_name = SBCommandInterpreter::GetArgumentTypeAsCString (arg_type);
Caroline Ticedeaab222010-10-01 19:59:14 +0000327
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000328 options_seen.insert (option_table[i].short_option);
Greg Claytonc982c762010-07-09 20:39:50 +0000329 fprintf (out, "%*s-%c ", indent_level, "", option_table[i].short_option);
Caroline Ticedeaab222010-10-01 19:59:14 +0000330 if (arg_type != eArgTypeNone)
Greg Clayton9d0402b2011-02-20 02:15:07 +0000331 fprintf (out, "<%s>", arg_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000332 fprintf (out, "\n");
Greg Claytonc982c762010-07-09 20:39:50 +0000333 fprintf (out, "%*s--%s ", indent_level, "", option_table[i].long_option);
Caroline Ticedeaab222010-10-01 19:59:14 +0000334 if (arg_type != eArgTypeNone)
Greg Clayton9d0402b2011-02-20 02:15:07 +0000335 fprintf (out, "<%s>", arg_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000336 fprintf (out, "\n");
337 indent_level += 5;
Greg Claytonc982c762010-07-09 20:39:50 +0000338 OutputFormattedUsageText (out, indent_level, option_table[i].usage_text, screen_width);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000339 indent_level -= 5;
340 fprintf (out, "\n");
341 }
342 }
343
344 indent_level -= 5;
Jim Inghamf0c63b92014-02-05 21:35:09 +0000345
346 fprintf (out, "\n%*sNotes:\n",
347 indent_level, "");
348 indent_level += 5;
349
Ed Mastea6b38062015-12-16 15:49:38 +0000350 fprintf (out, "\n%*sMultiple \"-s\" and \"-o\" options can be provided. They will be processed"
351 "\n%*sfrom left to right in order, with the source files and commands"
352 "\n%*sinterleaved. The same is true of the \"-S\" and \"-O\" options. The before"
353 "\n%*sfile and after file sets can intermixed freely, the command parser will"
354 "\n%*ssort them out. The order of the file specifiers (\"-c\", \"-f\", etc.) is"
355 "\n%*snot significant in this regard.\n\n",
Jim Ingham47ea51f2013-09-17 01:53:35 +0000356 indent_level, "",
357 indent_level, "",
358 indent_level, "",
Ed Mastea6b38062015-12-16 15:49:38 +0000359 indent_level, "",
360 indent_level, "",
Jim Ingham47ea51f2013-09-17 01:53:35 +0000361 indent_level, "");
362
Ed Mastea6b38062015-12-16 15:49:38 +0000363 fprintf (out, "\n%*sIf you don't provide -f then the first argument will be the file to be"
364 "\n%*sdebugged which means that '%s -- <filename> [<ARG1> [<ARG2>]]' also"
365 "\n%*sworks. But remember to end the options with \"--\" if any of your"
366 "\n%*sarguments have a \"-\" in them.\n\n",
Jim Inghama9deaf92011-08-16 23:57:58 +0000367 indent_level, "",
368 indent_level, "",
369 name,
Ed Mastea6b38062015-12-16 15:49:38 +0000370 indent_level, "",
Jim Inghama9deaf92011-08-16 23:57:58 +0000371 indent_level, "");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000372}
373
374void
Greg Claytone0d378b2011-03-24 21:19:54 +0000375BuildGetOptTable (OptionDefinition *expanded_option_table, std::vector<struct option> &getopt_table,
Caroline Tice4ab31c92010-10-12 21:57:09 +0000376 uint32_t num_options)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000377{
378 if (num_options == 0)
379 return;
380
381 uint32_t i;
382 uint32_t j;
383 std::bitset<256> option_seen;
384
Caroline Tice4ab31c92010-10-12 21:57:09 +0000385 getopt_table.resize (num_options + 1);
386
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000387 for (i = 0, j = 0; i < num_options; ++i)
Greg Claytonc982c762010-07-09 20:39:50 +0000388 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000389 char short_opt = expanded_option_table[i].short_option;
Greg Claytonc982c762010-07-09 20:39:50 +0000390
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000391 if (option_seen.test(short_opt) == false)
Greg Claytonc982c762010-07-09 20:39:50 +0000392 {
Caroline Tice4ab31c92010-10-12 21:57:09 +0000393 getopt_table[j].name = expanded_option_table[i].long_option;
394 getopt_table[j].has_arg = expanded_option_table[i].option_has_arg;
395 getopt_table[j].flag = NULL;
396 getopt_table[j].val = expanded_option_table[i].short_option;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000397 option_seen.set(short_opt);
398 ++j;
Greg Claytonc982c762010-07-09 20:39:50 +0000399 }
400 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000401
Caroline Tice4ab31c92010-10-12 21:57:09 +0000402 getopt_table[j].name = NULL;
403 getopt_table[j].has_arg = 0;
404 getopt_table[j].flag = NULL;
405 getopt_table[j].val = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000406
407}
408
Greg Clayton66111032010-06-23 01:19:29 +0000409Driver::OptionData::OptionData () :
Greg Clayton8d846da2010-12-08 22:23:24 +0000410 m_args(),
Greg Clayton66111032010-06-23 01:19:29 +0000411 m_script_lang (lldb::eScriptLanguageDefault),
Johnny Cheneb46f782012-08-15 22:10:42 +0000412 m_core_file (),
Greg Claytonc982c762010-07-09 20:39:50 +0000413 m_crash_log (),
Jim Inghamed3252f2013-09-14 00:20:24 +0000414 m_initial_commands (),
415 m_after_file_commands (),
Jim Ingham4add3b12014-11-19 01:28:13 +0000416 m_after_crash_commands(),
Greg Clayton66111032010-06-23 01:19:29 +0000417 m_debug_mode (false),
Jim Inghamed3252f2013-09-14 00:20:24 +0000418 m_source_quietly(false),
Greg Claytonc982c762010-07-09 20:39:50 +0000419 m_print_version (false),
Jim Inghame2231ac2012-12-21 22:22:26 +0000420 m_print_python_path (false),
Greg Clayton66111032010-06-23 01:19:29 +0000421 m_print_help (false),
Jim Inghame64f0dc2011-09-13 23:25:31 +0000422 m_wait_for(false),
Sean Callanan3e7e9152015-10-20 00:23:46 +0000423 m_repl (false),
424 m_repl_lang (eLanguageTypeUnknown),
425 m_repl_options (),
Jim Inghame64f0dc2011-09-13 23:25:31 +0000426 m_process_name(),
427 m_process_pid(LLDB_INVALID_PROCESS_ID),
Daniel Dunbara08823f2011-10-31 22:50:49 +0000428 m_use_external_editor(false),
Jim Inghamffc9f1d2014-10-14 01:20:07 +0000429 m_batch(false),
Stephen Wilson71c21d12011-04-11 19:41:40 +0000430 m_seen_options()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000431{
Greg Clayton66111032010-06-23 01:19:29 +0000432}
433
434Driver::OptionData::~OptionData ()
435{
436}
437
438void
439Driver::OptionData::Clear ()
440{
Greg Clayton8d846da2010-12-08 22:23:24 +0000441 m_args.clear ();
Greg Clayton66111032010-06-23 01:19:29 +0000442 m_script_lang = lldb::eScriptLanguageDefault;
Jim Inghamed3252f2013-09-14 00:20:24 +0000443 m_initial_commands.clear ();
444 m_after_file_commands.clear ();
Jason Molenda878ae012016-02-19 00:05:17 +0000445
446 // If there is a local .lldbinit, add that to the
447 // list of things to be sourced, if the settings
448 // permit it.
449 SBFileSpec local_lldbinit (".lldbinit", true);
450
451 SBFileSpec homedir_dot_lldb = SBHostOS::GetUserHomeDirectory();
452 homedir_dot_lldb.AppendPathComponent (".lldbinit");
453
454 // Only read .lldbinit in the current working directory
455 // if it's not the same as the .lldbinit in the home
456 // directory (which is already being read in).
457 if (local_lldbinit.Exists()
458 && strcmp (local_lldbinit.GetDirectory(), homedir_dot_lldb.GetDirectory()) != 0)
Jim Ingham4add3b12014-11-19 01:28:13 +0000459 {
460 char path[2048];
461 local_lldbinit.GetPath(path, 2047);
Jason Molenda878ae012016-02-19 00:05:17 +0000462 InitialCmdEntry entry(path, true, true, true);
Jim Ingham0f17c552014-11-22 01:33:22 +0000463 m_after_file_commands.push_back (entry);
Jim Ingham4add3b12014-11-19 01:28:13 +0000464 }
465
Greg Clayton66111032010-06-23 01:19:29 +0000466 m_debug_mode = false;
Jim Inghamed3252f2013-09-14 00:20:24 +0000467 m_source_quietly = false;
Greg Clayton66111032010-06-23 01:19:29 +0000468 m_print_help = false;
469 m_print_version = false;
Jim Inghame2231ac2012-12-21 22:22:26 +0000470 m_print_python_path = false;
Jim Inghame40e4212010-08-30 19:44:40 +0000471 m_use_external_editor = false;
Jim Inghame64f0dc2011-09-13 23:25:31 +0000472 m_wait_for = false;
473 m_process_name.erase();
Jim Inghamffc9f1d2014-10-14 01:20:07 +0000474 m_batch = false;
Jim Ingham4add3b12014-11-19 01:28:13 +0000475 m_after_crash_commands.clear();
476
Jim Inghame64f0dc2011-09-13 23:25:31 +0000477 m_process_pid = LLDB_INVALID_PROCESS_ID;
Greg Clayton66111032010-06-23 01:19:29 +0000478}
479
480void
Jim Ingham22302e52015-07-08 00:59:59 +0000481Driver::OptionData::AddInitialCommand (const char *command, CommandPlacement placement, bool is_file, SBError &error)
Jim Inghamed3252f2013-09-14 00:20:24 +0000482{
Jim Ingham0f17c552014-11-22 01:33:22 +0000483 std::vector<InitialCmdEntry> *command_set;
Jim Ingham4add3b12014-11-19 01:28:13 +0000484 switch (placement)
485 {
486 case eCommandPlacementBeforeFile:
Jim Inghamed3252f2013-09-14 00:20:24 +0000487 command_set = &(m_initial_commands);
Jim Ingham4add3b12014-11-19 01:28:13 +0000488 break;
489 case eCommandPlacementAfterFile:
Jim Inghamed3252f2013-09-14 00:20:24 +0000490 command_set = &(m_after_file_commands);
Jim Ingham4add3b12014-11-19 01:28:13 +0000491 break;
492 case eCommandPlacementAfterCrash:
493 command_set = &(m_after_crash_commands);
494 break;
495 }
Jim Inghamed3252f2013-09-14 00:20:24 +0000496
497 if (is_file)
498 {
499 SBFileSpec file(command);
500 if (file.Exists())
Jason Molenda878ae012016-02-19 00:05:17 +0000501 command_set->push_back (InitialCmdEntry(command, is_file, false));
Jim Inghamed3252f2013-09-14 00:20:24 +0000502 else if (file.ResolveExecutableLocation())
503 {
504 char final_path[PATH_MAX];
505 file.GetPath (final_path, sizeof(final_path));
Jason Molenda878ae012016-02-19 00:05:17 +0000506 command_set->push_back (InitialCmdEntry(final_path, is_file, false));
Jim Inghamed3252f2013-09-14 00:20:24 +0000507 }
508 else
509 error.SetErrorStringWithFormat("file specified in --source (-s) option doesn't exist: '%s'", optarg);
510 }
511 else
Jason Molenda878ae012016-02-19 00:05:17 +0000512 command_set->push_back (InitialCmdEntry(command, is_file, false));
Jim Inghamed3252f2013-09-14 00:20:24 +0000513}
514
515void
Greg Clayton66111032010-06-23 01:19:29 +0000516Driver::ResetOptionValues ()
517{
518 m_option_data.Clear ();
519}
520
521const char *
522Driver::GetFilename() const
523{
Greg Clayton8d846da2010-12-08 22:23:24 +0000524 if (m_option_data.m_args.empty())
Greg Clayton66111032010-06-23 01:19:29 +0000525 return NULL;
Greg Clayton8d846da2010-12-08 22:23:24 +0000526 return m_option_data.m_args.front().c_str();
Greg Clayton66111032010-06-23 01:19:29 +0000527}
528
529const char *
530Driver::GetCrashLogFilename() const
531{
532 if (m_option_data.m_crash_log.empty())
533 return NULL;
534 return m_option_data.m_crash_log.c_str();
535}
536
537lldb::ScriptLanguage
538Driver::GetScriptLanguage() const
539{
540 return m_option_data.m_script_lang;
541}
542
Jim Inghamed3252f2013-09-14 00:20:24 +0000543void
Jim Ingham4add3b12014-11-19 01:28:13 +0000544Driver::WriteCommandsForSourcing (CommandPlacement placement, SBStream &strm)
Greg Clayton66111032010-06-23 01:19:29 +0000545{
Jim Ingham0f17c552014-11-22 01:33:22 +0000546 std::vector<OptionData::InitialCmdEntry> *command_set;
Jim Ingham4add3b12014-11-19 01:28:13 +0000547 switch (placement)
548 {
549 case eCommandPlacementBeforeFile:
550 command_set = &m_option_data.m_initial_commands;
551 break;
552 case eCommandPlacementAfterFile:
553 command_set = &m_option_data.m_after_file_commands;
554 break;
555 case eCommandPlacementAfterCrash:
556 command_set = &m_option_data.m_after_crash_commands;
557 break;
558 }
Jim Inghamed3252f2013-09-14 00:20:24 +0000559
Jim Ingham0f17c552014-11-22 01:33:22 +0000560 for (const auto &command_entry : *command_set)
Jim Inghamed3252f2013-09-14 00:20:24 +0000561 {
Jim Ingham0f17c552014-11-22 01:33:22 +0000562 const char *command = command_entry.contents.c_str();
563 if (command_entry.is_file)
564 {
Jason Molenda878ae012016-02-19 00:05:17 +0000565 // If this command_entry is a file to be sourced, and it's the ./.lldbinit file (the .lldbinit
566 // file in the current working directory), only read it if target.load-cwd-lldbinit is 'true'.
567 if (command_entry.is_cwd_lldbinit_file_read)
568 {
569 SBStringList strlist = m_debugger.GetInternalVariableValue ("target.load-cwd-lldbinit",
570 m_debugger.GetInstanceName());
571 if (strlist.GetSize() == 1 && strcmp (strlist.GetStringAtIndex(0), "warn") == 0)
572 {
573 FILE *output = m_debugger.GetOutputFileHandle ();
574 ::fprintf (output,
575 "There is a .lldbinit file in the current directory which is not being read.\n"
576 "To silence this warning without sourcing in the local .lldbinit,\n"
577 "add the following to the lldbinit file in your home directory:\n"
578 " settings set target.load-cwd-lldbinit false\n"
579 "To allow lldb to source .lldbinit files in the current working directory,\n"
580 "set the value of this variable to true. Only do so if you understand and\n"
581 "accept the security risk.\n");
582 return;
583 }
584 if (strlist.GetSize() == 1 && strcmp (strlist.GetStringAtIndex(0), "false") == 0)
585 {
586 return;
587 }
588 }
Jim Ingham0f17c552014-11-22 01:33:22 +0000589 bool source_quietly = m_option_data.m_source_quietly || command_entry.source_quietly;
590 strm.Printf("command source -s %i '%s'\n", source_quietly, command);
591 }
Greg Clayton06357c92014-07-30 17:38:47 +0000592 else
593 strm.Printf("%s\n", command);
Jim Inghamed3252f2013-09-14 00:20:24 +0000594 }
Greg Clayton66111032010-06-23 01:19:29 +0000595}
596
597bool
598Driver::GetDebugMode() const
599{
600 return m_option_data.m_debug_mode;
601}
602
603
604// Check the arguments that were passed to this program to make sure they are valid and to get their
605// argument values (if any). Return a boolean value indicating whether or not to start up the full
606// debugger (i.e. the Command Interpreter) or not. Return FALSE if the arguments were invalid OR
607// if the user only wanted help or version information.
608
609SBError
Deepak Panickal429222c2013-10-15 15:46:40 +0000610Driver::ParseArgs (int argc, const char *argv[], FILE *out_fh, bool &exiting)
Greg Clayton66111032010-06-23 01:19:29 +0000611{
612 ResetOptionValues ();
613
614 SBCommandReturnObject result;
615
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000616 SBError error;
617 std::string option_string;
618 struct option *long_options = NULL;
Caroline Tice4ab31c92010-10-12 21:57:09 +0000619 std::vector<struct option> long_options_vector;
Greg Claytonc982c762010-07-09 20:39:50 +0000620 uint32_t num_options;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000621
Greg Claytonc982c762010-07-09 20:39:50 +0000622 for (num_options = 0; g_options[num_options].long_option != NULL; ++num_options)
623 /* Do Nothing. */;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000624
625 if (num_options == 0)
626 {
627 if (argc > 1)
628 error.SetErrorStringWithFormat ("invalid number of options");
629 return error;
630 }
631
Caroline Tice4ab31c92010-10-12 21:57:09 +0000632 BuildGetOptTable (g_options, long_options_vector, num_options);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000633
Caroline Tice4ab31c92010-10-12 21:57:09 +0000634 if (long_options_vector.empty())
635 long_options = NULL;
636 else
637 long_options = &long_options_vector.front();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000638
639 if (long_options == NULL)
640 {
641 error.SetErrorStringWithFormat ("invalid long options");
642 return error;
643 }
644
Greg Claytonb7ad58a2013-04-04 20:35:24 +0000645 // Build the option_string argument for call to getopt_long_only.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000646
647 for (int i = 0; long_options[i].name != NULL; ++i)
648 {
649 if (long_options[i].flag == NULL)
650 {
651 option_string.push_back ((char) long_options[i].val);
652 switch (long_options[i].has_arg)
653 {
654 default:
655 case no_argument:
656 break;
657 case required_argument:
658 option_string.push_back (':');
659 break;
660 case optional_argument:
661 option_string.append ("::");
662 break;
663 }
664 }
665 }
666
Jim Ingham06942692011-08-13 00:22:20 +0000667 // This is kind of a pain, but since we make the debugger in the Driver's constructor, we can't
668 // know at that point whether we should read in init files yet. So we don't read them in in the
669 // Driver constructor, then set the flags back to "read them in" here, and then if we see the
670 // "-n" flag, we'll turn it off again. Finally we have to read them in by hand later in the
671 // main loop.
672
673 m_debugger.SkipLLDBInitFiles (false);
674 m_debugger.SkipAppInitFiles (false);
675
Greg Claytonb7ad58a2013-04-04 20:35:24 +0000676 // Prepare for & make calls to getopt_long_only.
Eli Friedmanadb35022010-06-13 19:18:49 +0000677#if __GLIBC__
678 optind = 0;
679#else
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000680 optreset = 1;
681 optind = 1;
Eli Friedmanadb35022010-06-13 19:18:49 +0000682#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000683 int val;
684 while (1)
685 {
686 int long_options_index = -1;
Greg Claytonb7ad58a2013-04-04 20:35:24 +0000687 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 +0000688
689 if (val == -1)
690 break;
691 else if (val == '?')
692 {
Greg Clayton66111032010-06-23 01:19:29 +0000693 m_option_data.m_print_help = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000694 error.SetErrorStringWithFormat ("unknown or ambiguous option");
695 break;
696 }
697 else if (val == 0)
698 continue;
699 else
700 {
Greg Clayton66111032010-06-23 01:19:29 +0000701 m_option_data.m_seen_options.insert ((char) val);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000702 if (long_options_index == -1)
703 {
704 for (int i = 0;
705 long_options[i].name || long_options[i].has_arg || long_options[i].flag || long_options[i].val;
706 ++i)
707 {
708 if (long_options[i].val == val)
709 {
710 long_options_index = i;
711 break;
712 }
713 }
714 }
715
716 if (long_options_index >= 0)
717 {
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000718 const int short_option = g_options[long_options_index].short_option;
Greg Clayton66111032010-06-23 01:19:29 +0000719
720 switch (short_option)
721 {
722 case 'h':
723 m_option_data.m_print_help = true;
724 break;
725
726 case 'v':
727 m_option_data.m_print_version = true;
728 break;
729
Jim Inghame2231ac2012-12-21 22:22:26 +0000730 case 'P':
731 m_option_data.m_print_python_path = true;
732 break;
733
Jim Inghamffc9f1d2014-10-14 01:20:07 +0000734 case 'b':
735 m_option_data.m_batch = true;
736 break;
737
Greg Clayton66111032010-06-23 01:19:29 +0000738 case 'c':
Johnny Cheneb46f782012-08-15 22:10:42 +0000739 {
740 SBFileSpec file(optarg);
741 if (file.Exists())
742 {
743 m_option_data.m_core_file = optarg;
744 }
745 else
746 error.SetErrorStringWithFormat("file specified in --core (-c) option doesn't exist: '%s'", optarg);
747 }
Greg Clayton66111032010-06-23 01:19:29 +0000748 break;
Johnny Cheneb46f782012-08-15 22:10:42 +0000749
Jim Inghame40e4212010-08-30 19:44:40 +0000750 case 'e':
751 m_option_data.m_use_external_editor = true;
752 break;
Greg Clayton6eee5aa2010-10-11 01:05:37 +0000753
Jim Inghame64f0dc2011-09-13 23:25:31 +0000754 case 'x':
Greg Clayton6eee5aa2010-10-11 01:05:37 +0000755 m_debugger.SkipLLDBInitFiles (true);
Jim Ingham06942692011-08-13 00:22:20 +0000756 m_debugger.SkipAppInitFiles (true);
Greg Clayton6eee5aa2010-10-11 01:05:37 +0000757 break;
758
Jim Inghamed3252f2013-09-14 00:20:24 +0000759 case 'X':
Michael Sartainc3ce7f272013-05-23 20:47:45 +0000760 m_debugger.SetUseColor (false);
761 break;
762
Greg Clayton66111032010-06-23 01:19:29 +0000763 case 'f':
764 {
765 SBFileSpec file(optarg);
766 if (file.Exists())
Greg Clayton8d846da2010-12-08 22:23:24 +0000767 {
768 m_option_data.m_args.push_back (optarg);
769 }
Caroline Tice428a9a52010-09-10 04:48:55 +0000770 else if (file.ResolveExecutableLocation())
771 {
772 char path[PATH_MAX];
Johnny Chen25f3a3c2011-08-10 22:06:24 +0000773 file.GetPath (path, sizeof(path));
Greg Clayton8d846da2010-12-08 22:23:24 +0000774 m_option_data.m_args.push_back (path);
Caroline Tice428a9a52010-09-10 04:48:55 +0000775 }
Greg Clayton66111032010-06-23 01:19:29 +0000776 else
777 error.SetErrorStringWithFormat("file specified in --file (-f) option doesn't exist: '%s'", optarg);
778 }
779 break;
780
781 case 'a':
782 if (!m_debugger.SetDefaultArchitecture (optarg))
783 error.SetErrorStringWithFormat("invalid architecture in the -a or --arch option: '%s'", optarg);
784 break;
785
786 case 'l':
787 m_option_data.m_script_lang = m_debugger.GetScriptingLanguage (optarg);
788 break;
789
790 case 'd':
791 m_option_data.m_debug_mode = true;
792 break;
793
Jim Inghamf0c63b92014-02-05 21:35:09 +0000794 case 'Q':
Jim Inghamed3252f2013-09-14 00:20:24 +0000795 m_option_data.m_source_quietly = true;
796 break;
797
Jim Ingham661f29d2014-11-20 23:37:13 +0000798 case 'K':
Jim Ingham22302e52015-07-08 00:59:59 +0000799 m_option_data.AddInitialCommand(optarg, eCommandPlacementAfterCrash, true, error);
Jim Ingham4add3b12014-11-19 01:28:13 +0000800 break;
Jim Ingham661f29d2014-11-20 23:37:13 +0000801 case 'k':
Jim Ingham22302e52015-07-08 00:59:59 +0000802 m_option_data.AddInitialCommand(optarg, eCommandPlacementAfterCrash, false, error);
Jim Ingham4add3b12014-11-19 01:28:13 +0000803 break;
804
Jim Inghame64f0dc2011-09-13 23:25:31 +0000805 case 'n':
806 m_option_data.m_process_name = optarg;
807 break;
808
809 case 'w':
810 m_option_data.m_wait_for = true;
811 break;
812
813 case 'p':
814 {
815 char *remainder;
816 m_option_data.m_process_pid = strtol (optarg, &remainder, 0);
817 if (remainder == optarg || *remainder != '\0')
818 error.SetErrorStringWithFormat ("Could not convert process PID: \"%s\" into a pid.",
819 optarg);
820 }
821 break;
Sean Callanan3e7e9152015-10-20 00:23:46 +0000822
823 case 'r':
824 m_option_data.m_repl = true;
825 if (optarg && optarg[0])
826 m_option_data.m_repl_options = optarg;
827 else
828 m_option_data.m_repl_options.clear();
829 break;
830
831 case 'R':
832 m_option_data.m_repl_lang = SBLanguageRuntime::GetLanguageTypeFromString (optarg);
833 if (m_option_data.m_repl_lang == eLanguageTypeUnknown)
834 {
835 error.SetErrorStringWithFormat ("Unrecognized language name: \"%s\"", optarg);
836 }
837 break;
838
Greg Clayton66111032010-06-23 01:19:29 +0000839 case 's':
Jim Ingham22302e52015-07-08 00:59:59 +0000840 m_option_data.AddInitialCommand(optarg, eCommandPlacementAfterFile, true, error);
Greg Clayton66111032010-06-23 01:19:29 +0000841 break;
Jim Inghamed3252f2013-09-14 00:20:24 +0000842 case 'o':
Jim Ingham22302e52015-07-08 00:59:59 +0000843 m_option_data.AddInitialCommand(optarg, eCommandPlacementAfterFile, false, error);
Jim Inghamed3252f2013-09-14 00:20:24 +0000844 break;
845 case 'S':
Jim Ingham22302e52015-07-08 00:59:59 +0000846 m_option_data.AddInitialCommand(optarg, eCommandPlacementBeforeFile, true, error);
Jim Inghamed3252f2013-09-14 00:20:24 +0000847 break;
848 case 'O':
Jim Ingham22302e52015-07-08 00:59:59 +0000849 m_option_data.AddInitialCommand(optarg, eCommandPlacementBeforeFile, false, error);
Jim Inghamed3252f2013-09-14 00:20:24 +0000850 break;
Greg Clayton66111032010-06-23 01:19:29 +0000851 default:
852 m_option_data.m_print_help = true;
853 error.SetErrorStringWithFormat ("unrecognized option %c", short_option);
854 break;
855 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000856 }
857 else
858 {
859 error.SetErrorStringWithFormat ("invalid option with value %i", val);
860 }
861 if (error.Fail())
Caroline Tice4ab31c92010-10-12 21:57:09 +0000862 {
Greg Clayton66111032010-06-23 01:19:29 +0000863 return error;
Caroline Tice4ab31c92010-10-12 21:57:09 +0000864 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000865 }
866 }
Jim Ingham86511212010-06-15 18:47:14 +0000867
Greg Clayton66111032010-06-23 01:19:29 +0000868 if (error.Fail() || m_option_data.m_print_help)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000869 {
870 ShowUsage (out_fh, g_options, m_option_data);
Deepak Panickal429222c2013-10-15 15:46:40 +0000871 exiting = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000872 }
873 else if (m_option_data.m_print_version)
874 {
Greg Clayton66111032010-06-23 01:19:29 +0000875 ::fprintf (out_fh, "%s\n", m_debugger.GetVersionString());
Deepak Panickal429222c2013-10-15 15:46:40 +0000876 exiting = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000877 }
Jim Inghame2231ac2012-12-21 22:22:26 +0000878 else if (m_option_data.m_print_python_path)
879 {
880 SBFileSpec python_file_spec = SBHostOS::GetLLDBPythonPath();
881 if (python_file_spec.IsValid())
882 {
883 char python_path[PATH_MAX];
884 size_t num_chars = python_file_spec.GetPath(python_path, PATH_MAX);
885 if (num_chars < PATH_MAX)
886 {
887 ::fprintf (out_fh, "%s\n", python_path);
888 }
889 else
890 ::fprintf (out_fh, "<PATH TOO LONG>\n");
891 }
892 else
893 ::fprintf (out_fh, "<COULD NOT FIND PATH>\n");
Deepak Panickal429222c2013-10-15 15:46:40 +0000894 exiting = true;
Jim Inghame2231ac2012-12-21 22:22:26 +0000895 }
Jim Inghame64f0dc2011-09-13 23:25:31 +0000896 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 +0000897 {
Greg Clayton8d846da2010-12-08 22:23:24 +0000898 // Any arguments that are left over after option parsing are for
899 // the program. If a file was specified with -f then the filename
900 // is already in the m_option_data.m_args array, and any remaining args
901 // are arguments for the inferior program. If no file was specified with
902 // -f, then what is left is the program name followed by any arguments.
903
Greg Claytonb7ad58a2013-04-04 20:35:24 +0000904 // Skip any options we consumed with getopt_long_only
Greg Clayton8d846da2010-12-08 22:23:24 +0000905 argc -= optind;
906 argv += optind;
907
908 if (argc > 0)
909 {
910 for (int arg_idx=0; arg_idx<argc; ++arg_idx)
911 {
912 const char *arg = argv[arg_idx];
913 if (arg)
914 m_option_data.m_args.push_back (arg);
915 }
916 }
917
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000918 }
Jim Inghame64f0dc2011-09-13 23:25:31 +0000919 else
920 {
Greg Claytonb7ad58a2013-04-04 20:35:24 +0000921 // Skip any options we consumed with getopt_long_only
Jim Inghame64f0dc2011-09-13 23:25:31 +0000922 argc -= optind;
Greg Clayton23f59502012-07-17 03:23:13 +0000923 //argv += optind; // Commented out to keep static analyzer happy
Jim Inghame64f0dc2011-09-13 23:25:31 +0000924
925 if (argc > 0)
926 ::fprintf (out_fh, "Warning: program arguments are ignored when attaching.\n");
927 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000928
Greg Clayton66111032010-06-23 01:19:29 +0000929 return error;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000930}
931
Jim Ingham4add3b12014-11-19 01:28:13 +0000932static ::FILE *
933PrepareCommandsForSourcing (const char *commands_data, size_t commands_size, int fds[2])
934{
935 enum PIPES { READ, WRITE }; // Constants 0 and 1 for READ and WRITE
936
Jim Ingham4add3b12014-11-19 01:28:13 +0000937 ::FILE *commands_file = NULL;
938 fds[0] = -1;
939 fds[1] = -1;
940 int err = 0;
941#ifdef _WIN32
942 err = _pipe(fds, commands_size, O_BINARY);
943#else
944 err = pipe(fds);
945#endif
946 if (err == 0)
947 {
948 ssize_t nrwr = write(fds[WRITE], commands_data, commands_size);
949 if (nrwr < 0)
950 {
Adrian McCarthye704c4f2015-03-30 17:46:36 +0000951 fprintf(stderr, "error: write(%i, %p, %" PRIu64 ") failed (errno = %i) "
Jim Ingham4add3b12014-11-19 01:28:13 +0000952 "when trying to open LLDB commands pipe\n",
Saleem Abdulrasool1ee07252016-02-15 21:50:28 +0000953 fds[WRITE], static_cast<const void *>(commands_data),
954 static_cast<uint64_t>(commands_size), errno);
Jim Ingham4add3b12014-11-19 01:28:13 +0000955 }
956 else if (static_cast<size_t>(nrwr) == commands_size)
957 {
958 // Close the write end of the pipe so when we give the read end to
959 // the debugger/command interpreter it will exit when it consumes all
960 // of the data
961#ifdef _WIN32
962 _close(fds[WRITE]); fds[WRITE] = -1;
963#else
964 close(fds[WRITE]); fds[WRITE] = -1;
965#endif
966 // Now open the read file descriptor in a FILE * that we can give to
967 // the debugger as an input handle
968 commands_file = fdopen(fds[READ], "r");
969 if (commands_file)
970 {
971 fds[READ] = -1; // The FILE * 'commands_file' now owns the read descriptor
972 // Hand ownership if the FILE * over to the debugger for "commands_file".
973 }
974 else
975 {
976 fprintf(stderr,
977 "error: fdopen(%i, \"r\") failed (errno = %i) when "
978 "trying to open LLDB commands pipe\n",
979 fds[READ], errno);
Jim Ingham4add3b12014-11-19 01:28:13 +0000980 }
981 }
982 }
983 else
984 {
985 fprintf(stderr, "error: can't create pipe file descriptors for LLDB commands\n");
Jim Ingham4add3b12014-11-19 01:28:13 +0000986 }
987
988 return commands_file;
989}
990
991void
992CleanupAfterCommandSourcing (int fds[2])
993{
994 enum PIPES { READ, WRITE }; // Constants 0 and 1 for READ and WRITE
995
996 // Close any pipes that we still have ownership of
997 if ( fds[WRITE] != -1)
998 {
999#ifdef _WIN32
1000 _close(fds[WRITE]); fds[WRITE] = -1;
1001#else
1002 close(fds[WRITE]); fds[WRITE] = -1;
1003#endif
1004
1005 }
1006
1007 if ( fds[READ] != -1)
1008 {
1009#ifdef _WIN32
1010 _close(fds[READ]); fds[READ] = -1;
1011#else
1012 close(fds[READ]); fds[READ] = -1;
1013#endif
1014 }
1015
1016}
1017
Pavel Labathaa1ae6f2015-03-05 19:17:56 +00001018std::string
1019EscapeString (std::string arg)
1020{
1021 std::string::size_type pos = 0;
1022 while ((pos = arg.find_first_of("\"\\", pos)) != std::string::npos)
1023 {
1024 arg.insert (pos, 1, '\\');
1025 pos += 2;
1026 }
1027 return '"' + arg + '"';
1028}
1029
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001030void
1031Driver::MainLoop ()
1032{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001033 if (::tcgetattr(STDIN_FILENO, &g_old_stdin_termios) == 0)
Greg Claytonf571b892012-02-02 19:28:31 +00001034 {
1035 g_old_stdin_termios_is_valid = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001036 atexit (reset_stdin_termios);
Greg Claytonf571b892012-02-02 19:28:31 +00001037 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001038
1039 ::setbuf (stdin, NULL);
1040 ::setbuf (stdout, NULL);
1041
Greg Clayton66111032010-06-23 01:19:29 +00001042 m_debugger.SetErrorFileHandle (stderr, false);
1043 m_debugger.SetOutputFileHandle (stdout, false);
Greg Clayton06357c92014-07-30 17:38:47 +00001044 m_debugger.SetInputFileHandle (stdin, false); // Don't take ownership of STDIN yet...
1045
Jim Inghame40e4212010-08-30 19:44:40 +00001046 m_debugger.SetUseExternalEditor(m_option_data.m_use_external_editor);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001047
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001048 struct winsize window_size;
1049 if (isatty (STDIN_FILENO)
1050 && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0)
1051 {
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001052 if (window_size.ws_col > 0)
Greg Claytona7015092010-09-18 01:14:36 +00001053 m_debugger.SetTerminalWidth (window_size.ws_col);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001054 }
1055
Greg Clayton44d93782014-01-27 23:43:24 +00001056 SBCommandInterpreter sb_interpreter = m_debugger.GetCommandInterpreter();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001057
Greg Clayton44d93782014-01-27 23:43:24 +00001058 // Before we handle any options from the command line, we parse the
1059 // .lldbinit file in the user's home directory.
1060 SBCommandReturnObject result;
1061 sb_interpreter.SourceInitFileInHomeDirectory(result);
1062 if (GetDebugMode())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001063 {
Greg Clayton44d93782014-01-27 23:43:24 +00001064 result.PutError (m_debugger.GetErrorFileHandle());
1065 result.PutOutput (m_debugger.GetOutputFileHandle());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001066 }
Greg Clayton44d93782014-01-27 23:43:24 +00001067
1068 // Now we handle options we got from the command line
Ed Mastef8314532014-07-30 19:26:11 +00001069 SBStream commands_stream;
Greg Clayton06357c92014-07-30 17:38:47 +00001070
Greg Clayton44d93782014-01-27 23:43:24 +00001071 // First source in the commands specified to be run before the file arguments are processed.
Jason Molenda878ae012016-02-19 00:05:17 +00001072 WriteCommandsForSourcing (eCommandPlacementBeforeFile, commands_stream);
Greg Clayton06357c92014-07-30 17:38:47 +00001073
Greg Clayton44d93782014-01-27 23:43:24 +00001074 const size_t num_args = m_option_data.m_args.size();
1075 if (num_args > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001076 {
Jim Ingham5b1fe952014-08-07 23:01:31 +00001077 char arch_name[64];
1078 if (m_debugger.GetDefaultArchitecture (arch_name, sizeof (arch_name)))
Pavel Labathaa1ae6f2015-03-05 19:17:56 +00001079 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 +00001080 else
Pavel Labathaa1ae6f2015-03-05 19:17:56 +00001081 commands_stream.Printf("target create %s", EscapeString(m_option_data.m_args[0]).c_str());
Jim Ingham5b1fe952014-08-07 23:01:31 +00001082
Greg Clayton06357c92014-07-30 17:38:47 +00001083 if (!m_option_data.m_core_file.empty())
1084 {
Pavel Labathaa1ae6f2015-03-05 19:17:56 +00001085 commands_stream.Printf(" --core %s", EscapeString(m_option_data.m_core_file).c_str());
Greg Clayton06357c92014-07-30 17:38:47 +00001086 }
1087 commands_stream.Printf("\n");
Greg Clayton44d93782014-01-27 23:43:24 +00001088
1089 if (num_args > 1)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001090 {
Greg Clayton06357c92014-07-30 17:38:47 +00001091 commands_stream.Printf ("settings set -- target.run-args ");
Greg Clayton44d93782014-01-27 23:43:24 +00001092 for (size_t arg_idx = 1; arg_idx < num_args; ++arg_idx)
Pavel Labathaa1ae6f2015-03-05 19:17:56 +00001093 commands_stream.Printf(" %s", EscapeString(m_option_data.m_args[arg_idx]).c_str());
Greg Clayton06357c92014-07-30 17:38:47 +00001094 commands_stream.Printf("\n");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001095 }
1096 }
Greg Clayton06357c92014-07-30 17:38:47 +00001097 else if (!m_option_data.m_core_file.empty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001098 {
Pavel Labathaa1ae6f2015-03-05 19:17:56 +00001099 commands_stream.Printf("target create --core %s\n", EscapeString(m_option_data.m_core_file).c_str());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001100 }
Greg Clayton9c0b64c2014-02-06 18:22:44 +00001101 else if (!m_option_data.m_process_name.empty())
1102 {
Pavel Labathaa1ae6f2015-03-05 19:17:56 +00001103 commands_stream.Printf ("process attach --name %s", EscapeString(m_option_data.m_process_name).c_str());
Greg Clayton06357c92014-07-30 17:38:47 +00001104
1105 if (m_option_data.m_wait_for)
1106 commands_stream.Printf(" --waitfor");
1107
1108 commands_stream.Printf("\n");
1109
Greg Clayton9c0b64c2014-02-06 18:22:44 +00001110 }
1111 else if (LLDB_INVALID_PROCESS_ID != m_option_data.m_process_pid)
1112 {
Greg Clayton06357c92014-07-30 17:38:47 +00001113 commands_stream.Printf ("process attach --pid %" PRIu64 "\n", m_option_data.m_process_pid);
Greg Clayton9c0b64c2014-02-06 18:22:44 +00001114 }
Greg Clayton44d93782014-01-27 23:43:24 +00001115
Jim Ingham4add3b12014-11-19 01:28:13 +00001116 WriteCommandsForSourcing(eCommandPlacementAfterFile, commands_stream);
Greg Clayton06357c92014-07-30 17:38:47 +00001117
Greg Clayton44d93782014-01-27 23:43:24 +00001118 if (GetDebugMode())
1119 {
1120 result.PutError(m_debugger.GetErrorFileHandle());
1121 result.PutOutput(m_debugger.GetOutputFileHandle());
1122 }
1123
1124 bool handle_events = true;
1125 bool spawn_thread = false;
Greg Clayton06357c92014-07-30 17:38:47 +00001126
Sean Callanan3e7e9152015-10-20 00:23:46 +00001127 if (m_option_data.m_repl)
Greg Clayton06357c92014-07-30 17:38:47 +00001128 {
Sean Callanan3e7e9152015-10-20 00:23:46 +00001129 const char *repl_options = NULL;
1130 if (!m_option_data.m_repl_options.empty())
1131 repl_options = m_option_data.m_repl_options.c_str();
1132 SBError error (m_debugger.RunREPL(m_option_data.m_repl_lang, repl_options));
1133 if (error.Fail())
Greg Clayton49668762014-08-01 18:32:07 +00001134 {
Sean Callanan3e7e9152015-10-20 00:23:46 +00001135 const char *error_cstr = error.GetCString();
1136 if (error_cstr && error_cstr[0])
1137 fprintf (stderr, "error: %s\n", error_cstr);
1138 else
1139 fprintf (stderr, "error: %u\n", error.GetError());
Greg Clayton06357c92014-07-30 17:38:47 +00001140 }
1141 }
Sean Callanan3e7e9152015-10-20 00:23:46 +00001142 else
Jim Ingham26c7bf92014-10-11 00:38:27 +00001143 {
Sean Callanan3e7e9152015-10-20 00:23:46 +00001144 // Check if we have any data in the commands stream, and if so, save it to a temp file
1145 // so we can then run the command interpreter using the file contents.
1146 const char *commands_data = commands_stream.GetData();
1147 const size_t commands_size = commands_stream.GetSize();
1148
1149 // The command file might have requested that we quit, this variable will track that.
1150 bool quit_requested = false;
1151 bool stopped_for_crash = false;
1152 if (commands_data && commands_size)
1153 {
1154 int initial_commands_fds[2];
1155 bool success = true;
1156 FILE *commands_file = PrepareCommandsForSourcing (commands_data, commands_size, initial_commands_fds);
1157 if (commands_file)
1158 {
1159 m_debugger.SetInputFileHandle (commands_file, true);
1160
1161 // Set the debugger into Sync mode when running the command file. Otherwise command files
1162 // that run the target won't run in a sensible way.
1163 bool old_async = m_debugger.GetAsync();
1164 m_debugger.SetAsync(false);
1165 int num_errors;
1166
1167 SBCommandInterpreterRunOptions options;
1168 options.SetStopOnError (true);
1169 if (m_option_data.m_batch)
1170 options.SetStopOnCrash (true);
1171
1172 m_debugger.RunCommandInterpreter(handle_events,
1173 spawn_thread,
1174 options,
1175 num_errors,
1176 quit_requested,
1177 stopped_for_crash);
1178
1179 if (m_option_data.m_batch && stopped_for_crash && !m_option_data.m_after_crash_commands.empty())
1180 {
1181 int crash_command_fds[2];
1182 SBStream crash_commands_stream;
1183 WriteCommandsForSourcing (eCommandPlacementAfterCrash, crash_commands_stream);
1184 const char *crash_commands_data = crash_commands_stream.GetData();
1185 const size_t crash_commands_size = crash_commands_stream.GetSize();
1186 commands_file = PrepareCommandsForSourcing (crash_commands_data, crash_commands_size, crash_command_fds);
1187 if (commands_file)
1188 {
1189 bool local_quit_requested;
1190 bool local_stopped_for_crash;
1191 m_debugger.SetInputFileHandle (commands_file, true);
1192
1193 m_debugger.RunCommandInterpreter(handle_events,
1194 spawn_thread,
1195 options,
1196 num_errors,
1197 local_quit_requested,
1198 local_stopped_for_crash);
1199 if (local_quit_requested)
1200 quit_requested = true;
1201
1202 }
1203 }
1204 m_debugger.SetAsync(old_async);
1205 }
1206 else
1207 success = false;
1208
1209 // Close any pipes that we still have ownership of
1210 CleanupAfterCommandSourcing(initial_commands_fds);
1211
1212 // Something went wrong with command pipe
1213 if (!success)
1214 {
1215 exit(1);
1216 }
1217
1218 }
1219
1220 // Now set the input file handle to STDIN and run the command
1221 // interpreter again in interactive mode and let the debugger
1222 // take ownership of stdin
1223
1224 bool go_interactive = true;
1225 if (quit_requested)
1226 go_interactive = false;
1227 else if (m_option_data.m_batch && !stopped_for_crash)
1228 go_interactive = false;
1229
1230 if (go_interactive)
1231 {
1232 m_debugger.SetInputFileHandle (stdin, true);
1233 m_debugger.RunCommandInterpreter(handle_events, spawn_thread);
1234 }
Jim Ingham26c7bf92014-10-11 00:38:27 +00001235 }
Greg Clayton44d93782014-01-27 23:43:24 +00001236
1237 reset_stdin_termios();
1238 fclose (stdin);
1239
1240 SBDebugger::Destroy (m_debugger);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001241}
1242
Greg Clayton44d93782014-01-27 23:43:24 +00001243
Jim Inghamc46fe7c2013-02-22 22:56:55 +00001244void
1245Driver::ResizeWindow (unsigned short col)
1246{
1247 GetDebugger().SetTerminalWidth (col);
Jim Inghamc46fe7c2013-02-22 22:56:55 +00001248}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001249
Caroline Ticedd759852010-09-09 17:45:09 +00001250void
1251sigwinch_handler (int signo)
1252{
1253 struct winsize window_size;
1254 if (isatty (STDIN_FILENO)
1255 && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0)
1256 {
Jim Ingham57190ba2012-04-26 21:39:32 +00001257 if ((window_size.ws_col > 0) && g_driver != NULL)
Caroline Ticedd759852010-09-09 17:45:09 +00001258 {
Jim Inghamc46fe7c2013-02-22 22:56:55 +00001259 g_driver->ResizeWindow (window_size.ws_col);
Caroline Ticedd759852010-09-09 17:45:09 +00001260 }
1261 }
1262}
1263
Caroline Ticeefed6132010-11-19 20:47:54 +00001264void
1265sigint_handler (int signo)
1266{
1267 static bool g_interrupt_sent = false;
1268 if (g_driver)
1269 {
1270 if (!g_interrupt_sent)
1271 {
1272 g_interrupt_sent = true;
1273 g_driver->GetDebugger().DispatchInputInterrupt();
1274 g_interrupt_sent = false;
1275 return;
1276 }
1277 }
1278
1279 exit (signo);
1280}
1281
Jim Inghamc5917d92012-11-30 20:23:19 +00001282void
1283sigtstp_handler (int signo)
1284{
1285 g_driver->GetDebugger().SaveInputTerminalState();
1286 signal (signo, SIG_DFL);
1287 kill (getpid(), signo);
1288 signal (signo, sigtstp_handler);
1289}
1290
1291void
1292sigcont_handler (int signo)
1293{
1294 g_driver->GetDebugger().RestoreInputTerminalState();
1295 signal (signo, SIG_DFL);
1296 kill (getpid(), signo);
1297 signal (signo, sigcont_handler);
1298}
1299
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001300int
Jim Inghama462f5c2011-01-27 20:15:39 +00001301main (int argc, char const *argv[], const char *envp[])
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001302{
Deepak Panickal99fbc072014-03-03 15:39:47 +00001303#ifdef _MSC_VER
1304 // disable buffering on windows
1305 setvbuf(stdout, NULL, _IONBF, 0);
1306 setvbuf(stdin , NULL, _IONBF, 0);
1307#endif
1308
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001309 SBDebugger::Initialize();
1310
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00001311 SBHostOS::ThreadCreated ("<lldb.driver.main-thread>");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001312
Greg Clayton3fcbed62010-10-19 03:25:40 +00001313 signal (SIGPIPE, SIG_IGN);
Caroline Ticedd759852010-09-09 17:45:09 +00001314 signal (SIGWINCH, sigwinch_handler);
Caroline Ticeefed6132010-11-19 20:47:54 +00001315 signal (SIGINT, sigint_handler);
Jim Inghamc5917d92012-11-30 20:23:19 +00001316 signal (SIGTSTP, sigtstp_handler);
1317 signal (SIGCONT, sigcont_handler);
Caroline Ticedd759852010-09-09 17:45:09 +00001318
Greg Clayton66111032010-06-23 01:19:29 +00001319 // Create a scope for driver so that the driver object will destroy itself
1320 // before SBDebugger::Terminate() is called.
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001321 {
Greg Clayton66111032010-06-23 01:19:29 +00001322 Driver driver;
1323
Deepak Panickal429222c2013-10-15 15:46:40 +00001324 bool exiting = false;
1325 SBError error (driver.ParseArgs (argc, argv, stdout, exiting));
Greg Clayton66111032010-06-23 01:19:29 +00001326 if (error.Fail())
1327 {
1328 const char *error_cstr = error.GetCString ();
1329 if (error_cstr)
1330 ::fprintf (stderr, "error: %s\n", error_cstr);
1331 }
Deepak Panickal429222c2013-10-15 15:46:40 +00001332 else if (!exiting)
Greg Clayton66111032010-06-23 01:19:29 +00001333 {
1334 driver.MainLoop ();
1335 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001336 }
1337
1338 SBDebugger::Terminate();
1339 return 0;
1340}