blob: 328b90beab487062b9196c0b83e0eafee719bb64 [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
1040 ::setbuf (stdin, NULL);
1041 ::setbuf (stdout, NULL);
1042
Greg Clayton66111032010-06-23 01:19:29 +00001043 m_debugger.SetErrorFileHandle (stderr, false);
1044 m_debugger.SetOutputFileHandle (stdout, false);
Greg Clayton06357c92014-07-30 17:38:47 +00001045 m_debugger.SetInputFileHandle (stdin, false); // Don't take ownership of STDIN yet...
1046
Jim Inghame40e4212010-08-30 19:44:40 +00001047 m_debugger.SetUseExternalEditor(m_option_data.m_use_external_editor);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001048
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001049 struct winsize window_size;
1050 if (isatty (STDIN_FILENO)
1051 && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0)
1052 {
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001053 if (window_size.ws_col > 0)
Greg Claytona7015092010-09-18 01:14:36 +00001054 m_debugger.SetTerminalWidth (window_size.ws_col);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001055 }
1056
Greg Clayton44d93782014-01-27 23:43:24 +00001057 SBCommandInterpreter sb_interpreter = m_debugger.GetCommandInterpreter();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001058
Greg Clayton44d93782014-01-27 23:43:24 +00001059 // Before we handle any options from the command line, we parse the
1060 // .lldbinit file in the user's home directory.
1061 SBCommandReturnObject result;
1062 sb_interpreter.SourceInitFileInHomeDirectory(result);
1063 if (GetDebugMode())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001064 {
Greg Clayton44d93782014-01-27 23:43:24 +00001065 result.PutError (m_debugger.GetErrorFileHandle());
1066 result.PutOutput (m_debugger.GetOutputFileHandle());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001067 }
Greg Clayton44d93782014-01-27 23:43:24 +00001068
1069 // Now we handle options we got from the command line
Ed Mastef8314532014-07-30 19:26:11 +00001070 SBStream commands_stream;
Greg Clayton06357c92014-07-30 17:38:47 +00001071
Greg Clayton44d93782014-01-27 23:43:24 +00001072 // First source in the commands specified to be run before the file arguments are processed.
Jason Molenda878ae012016-02-19 00:05:17 +00001073 WriteCommandsForSourcing (eCommandPlacementBeforeFile, commands_stream);
Greg Clayton06357c92014-07-30 17:38:47 +00001074
Greg Clayton44d93782014-01-27 23:43:24 +00001075 const size_t num_args = m_option_data.m_args.size();
1076 if (num_args > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001077 {
Jim Ingham5b1fe952014-08-07 23:01:31 +00001078 char arch_name[64];
1079 if (m_debugger.GetDefaultArchitecture (arch_name, sizeof (arch_name)))
Pavel Labathaa1ae6f2015-03-05 19:17:56 +00001080 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 +00001081 else
Pavel Labathaa1ae6f2015-03-05 19:17:56 +00001082 commands_stream.Printf("target create %s", EscapeString(m_option_data.m_args[0]).c_str());
Jim Ingham5b1fe952014-08-07 23:01:31 +00001083
Greg Clayton06357c92014-07-30 17:38:47 +00001084 if (!m_option_data.m_core_file.empty())
1085 {
Pavel Labathaa1ae6f2015-03-05 19:17:56 +00001086 commands_stream.Printf(" --core %s", EscapeString(m_option_data.m_core_file).c_str());
Greg Clayton06357c92014-07-30 17:38:47 +00001087 }
1088 commands_stream.Printf("\n");
Greg Clayton44d93782014-01-27 23:43:24 +00001089
1090 if (num_args > 1)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001091 {
Greg Clayton06357c92014-07-30 17:38:47 +00001092 commands_stream.Printf ("settings set -- target.run-args ");
Greg Clayton44d93782014-01-27 23:43:24 +00001093 for (size_t arg_idx = 1; arg_idx < num_args; ++arg_idx)
Pavel Labathaa1ae6f2015-03-05 19:17:56 +00001094 commands_stream.Printf(" %s", EscapeString(m_option_data.m_args[arg_idx]).c_str());
Greg Clayton06357c92014-07-30 17:38:47 +00001095 commands_stream.Printf("\n");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001096 }
1097 }
Greg Clayton06357c92014-07-30 17:38:47 +00001098 else if (!m_option_data.m_core_file.empty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001099 {
Pavel Labathaa1ae6f2015-03-05 19:17:56 +00001100 commands_stream.Printf("target create --core %s\n", EscapeString(m_option_data.m_core_file).c_str());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001101 }
Greg Clayton9c0b64c2014-02-06 18:22:44 +00001102 else if (!m_option_data.m_process_name.empty())
1103 {
Pavel Labathaa1ae6f2015-03-05 19:17:56 +00001104 commands_stream.Printf ("process attach --name %s", EscapeString(m_option_data.m_process_name).c_str());
Greg Clayton06357c92014-07-30 17:38:47 +00001105
1106 if (m_option_data.m_wait_for)
1107 commands_stream.Printf(" --waitfor");
1108
1109 commands_stream.Printf("\n");
1110
Greg Clayton9c0b64c2014-02-06 18:22:44 +00001111 }
1112 else if (LLDB_INVALID_PROCESS_ID != m_option_data.m_process_pid)
1113 {
Greg Clayton06357c92014-07-30 17:38:47 +00001114 commands_stream.Printf ("process attach --pid %" PRIu64 "\n", m_option_data.m_process_pid);
Greg Clayton9c0b64c2014-02-06 18:22:44 +00001115 }
Greg Clayton44d93782014-01-27 23:43:24 +00001116
Jim Ingham4add3b12014-11-19 01:28:13 +00001117 WriteCommandsForSourcing(eCommandPlacementAfterFile, commands_stream);
Greg Clayton06357c92014-07-30 17:38:47 +00001118
Greg Clayton44d93782014-01-27 23:43:24 +00001119 if (GetDebugMode())
1120 {
1121 result.PutError(m_debugger.GetErrorFileHandle());
1122 result.PutOutput(m_debugger.GetOutputFileHandle());
1123 }
1124
1125 bool handle_events = true;
1126 bool spawn_thread = false;
Greg Clayton06357c92014-07-30 17:38:47 +00001127
Sean Callanan3e7e9152015-10-20 00:23:46 +00001128 if (m_option_data.m_repl)
Greg Clayton06357c92014-07-30 17:38:47 +00001129 {
Sean Callanan3e7e9152015-10-20 00:23:46 +00001130 const char *repl_options = NULL;
1131 if (!m_option_data.m_repl_options.empty())
1132 repl_options = m_option_data.m_repl_options.c_str();
1133 SBError error (m_debugger.RunREPL(m_option_data.m_repl_lang, repl_options));
1134 if (error.Fail())
Greg Clayton49668762014-08-01 18:32:07 +00001135 {
Sean Callanan3e7e9152015-10-20 00:23:46 +00001136 const char *error_cstr = error.GetCString();
1137 if (error_cstr && error_cstr[0])
1138 fprintf (stderr, "error: %s\n", error_cstr);
1139 else
1140 fprintf (stderr, "error: %u\n", error.GetError());
Greg Clayton06357c92014-07-30 17:38:47 +00001141 }
1142 }
Sean Callanan3e7e9152015-10-20 00:23:46 +00001143 else
Jim Ingham26c7bf92014-10-11 00:38:27 +00001144 {
Sean Callanan3e7e9152015-10-20 00:23:46 +00001145 // Check if we have any data in the commands stream, and if so, save it to a temp file
1146 // so we can then run the command interpreter using the file contents.
1147 const char *commands_data = commands_stream.GetData();
1148 const size_t commands_size = commands_stream.GetSize();
1149
1150 // The command file might have requested that we quit, this variable will track that.
1151 bool quit_requested = false;
1152 bool stopped_for_crash = false;
1153 if (commands_data && commands_size)
1154 {
1155 int initial_commands_fds[2];
1156 bool success = true;
1157 FILE *commands_file = PrepareCommandsForSourcing (commands_data, commands_size, initial_commands_fds);
1158 if (commands_file)
1159 {
1160 m_debugger.SetInputFileHandle (commands_file, true);
1161
1162 // Set the debugger into Sync mode when running the command file. Otherwise command files
1163 // that run the target won't run in a sensible way.
1164 bool old_async = m_debugger.GetAsync();
1165 m_debugger.SetAsync(false);
1166 int num_errors;
1167
1168 SBCommandInterpreterRunOptions options;
1169 options.SetStopOnError (true);
1170 if (m_option_data.m_batch)
1171 options.SetStopOnCrash (true);
1172
1173 m_debugger.RunCommandInterpreter(handle_events,
1174 spawn_thread,
1175 options,
1176 num_errors,
1177 quit_requested,
1178 stopped_for_crash);
1179
1180 if (m_option_data.m_batch && stopped_for_crash && !m_option_data.m_after_crash_commands.empty())
1181 {
1182 int crash_command_fds[2];
1183 SBStream crash_commands_stream;
1184 WriteCommandsForSourcing (eCommandPlacementAfterCrash, crash_commands_stream);
1185 const char *crash_commands_data = crash_commands_stream.GetData();
1186 const size_t crash_commands_size = crash_commands_stream.GetSize();
1187 commands_file = PrepareCommandsForSourcing (crash_commands_data, crash_commands_size, crash_command_fds);
1188 if (commands_file)
1189 {
1190 bool local_quit_requested;
1191 bool local_stopped_for_crash;
1192 m_debugger.SetInputFileHandle (commands_file, true);
1193
1194 m_debugger.RunCommandInterpreter(handle_events,
1195 spawn_thread,
1196 options,
1197 num_errors,
1198 local_quit_requested,
1199 local_stopped_for_crash);
1200 if (local_quit_requested)
1201 quit_requested = true;
1202
1203 }
1204 }
1205 m_debugger.SetAsync(old_async);
1206 }
1207 else
1208 success = false;
1209
1210 // Close any pipes that we still have ownership of
1211 CleanupAfterCommandSourcing(initial_commands_fds);
1212
1213 // Something went wrong with command pipe
1214 if (!success)
1215 {
1216 exit(1);
1217 }
1218
1219 }
1220
1221 // Now set the input file handle to STDIN and run the command
1222 // interpreter again in interactive mode and let the debugger
1223 // take ownership of stdin
1224
1225 bool go_interactive = true;
1226 if (quit_requested)
1227 go_interactive = false;
1228 else if (m_option_data.m_batch && !stopped_for_crash)
1229 go_interactive = false;
1230
1231 if (go_interactive)
1232 {
1233 m_debugger.SetInputFileHandle (stdin, true);
1234 m_debugger.RunCommandInterpreter(handle_events, spawn_thread);
1235 }
Jim Ingham26c7bf92014-10-11 00:38:27 +00001236 }
Greg Clayton44d93782014-01-27 23:43:24 +00001237
1238 reset_stdin_termios();
1239 fclose (stdin);
1240
1241 SBDebugger::Destroy (m_debugger);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001242}
1243
Greg Clayton44d93782014-01-27 23:43:24 +00001244
Jim Inghamc46fe7c2013-02-22 22:56:55 +00001245void
1246Driver::ResizeWindow (unsigned short col)
1247{
1248 GetDebugger().SetTerminalWidth (col);
Jim Inghamc46fe7c2013-02-22 22:56:55 +00001249}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001250
Caroline Ticedd759852010-09-09 17:45:09 +00001251void
1252sigwinch_handler (int signo)
1253{
1254 struct winsize window_size;
1255 if (isatty (STDIN_FILENO)
1256 && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0)
1257 {
Jim Ingham57190ba2012-04-26 21:39:32 +00001258 if ((window_size.ws_col > 0) && g_driver != NULL)
Caroline Ticedd759852010-09-09 17:45:09 +00001259 {
Jim Inghamc46fe7c2013-02-22 22:56:55 +00001260 g_driver->ResizeWindow (window_size.ws_col);
Caroline Ticedd759852010-09-09 17:45:09 +00001261 }
1262 }
1263}
1264
Caroline Ticeefed6132010-11-19 20:47:54 +00001265void
1266sigint_handler (int signo)
1267{
1268 static bool g_interrupt_sent = false;
1269 if (g_driver)
1270 {
1271 if (!g_interrupt_sent)
1272 {
1273 g_interrupt_sent = true;
1274 g_driver->GetDebugger().DispatchInputInterrupt();
1275 g_interrupt_sent = false;
1276 return;
1277 }
1278 }
1279
1280 exit (signo);
1281}
1282
Jim Inghamc5917d92012-11-30 20:23:19 +00001283void
1284sigtstp_handler (int signo)
1285{
Pavel Labathbb5c39d2016-04-11 16:40:09 +00001286 if (g_driver)
1287 g_driver->GetDebugger().SaveInputTerminalState();
1288
Jim Inghamc5917d92012-11-30 20:23:19 +00001289 signal (signo, SIG_DFL);
1290 kill (getpid(), signo);
1291 signal (signo, sigtstp_handler);
1292}
1293
1294void
1295sigcont_handler (int signo)
1296{
Pavel Labathbb5c39d2016-04-11 16:40:09 +00001297 if (g_driver)
1298 g_driver->GetDebugger().RestoreInputTerminalState();
1299
Jim Inghamc5917d92012-11-30 20:23:19 +00001300 signal (signo, SIG_DFL);
1301 kill (getpid(), signo);
1302 signal (signo, sigcont_handler);
1303}
1304
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001305int
Zachary Turner190fadc2016-03-22 17:58:09 +00001306#ifdef WIN32
1307wmain(int argc, wchar_t const *wargv[])
1308#else
1309main(int argc, char const *argv[])
1310#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001311{
Deepak Panickal99fbc072014-03-03 15:39:47 +00001312#ifdef _MSC_VER
1313 // disable buffering on windows
1314 setvbuf(stdout, NULL, _IONBF, 0);
1315 setvbuf(stdin , NULL, _IONBF, 0);
1316#endif
1317
Zachary Turner190fadc2016-03-22 17:58:09 +00001318#ifdef _WIN32
1319 // Convert wide arguments to UTF-8
1320 std::vector<std::string> argvStrings(argc);
1321 std::vector<const char *> argvPointers(argc);
1322 for (int i = 0; i != argc; ++i)
1323 {
1324 llvm::convertWideToUTF8(wargv[i], argvStrings[i]);
1325 argvPointers[i] = argvStrings[i].c_str();
1326 }
1327 const char **argv = argvPointers.data();
Zachary Turner29365da2016-03-18 23:47:48 +00001328#endif
Caroline Ticedd759852010-09-09 17:45:09 +00001329
Zachary Turner190fadc2016-03-22 17:58:09 +00001330 SBDebugger::Initialize();
Greg Clayton66111032010-06-23 01:19:29 +00001331
Zachary Turner190fadc2016-03-22 17:58:09 +00001332 SBHostOS::ThreadCreated("<lldb.driver.main-thread>");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001333
Zachary Turner190fadc2016-03-22 17:58:09 +00001334 signal(SIGINT, sigint_handler);
1335#if !defined(_MSC_VER)
1336 signal(SIGPIPE, SIG_IGN);
1337 signal(SIGWINCH, sigwinch_handler);
1338 signal(SIGTSTP, sigtstp_handler);
1339 signal(SIGCONT, sigcont_handler);
1340#endif
1341
1342 // Create a scope for driver so that the driver object will destroy itself
1343 // before SBDebugger::Terminate() is called.
1344 {
1345 Driver driver;
1346
1347 bool exiting = false;
1348 SBError error(driver.ParseArgs(argc, argv, stdout, exiting));
1349 if (error.Fail())
1350 {
1351 const char *error_cstr = error.GetCString();
1352 if (error_cstr)
1353 ::fprintf(stderr, "error: %s\n", error_cstr);
1354 }
1355 else if (!exiting)
1356 {
1357 driver.MainLoop();
1358 }
1359 }
1360
1361 SBDebugger::Terminate();
1362 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001363}