blob: 9394efab0752e5a0f51cf0e60a4725ce8a0764ef [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
18#include <string>
19
Deepak Panickal429222c2013-10-15 15:46:40 +000020#include <thread>
Jim Inghame6bc6cb2012-02-08 05:23:15 +000021#include "lldb/API/SBBreakpoint.h"
Eli Friedmana382d472010-06-09 09:50:17 +000022#include "lldb/API/SBCommandInterpreter.h"
23#include "lldb/API/SBCommandReturnObject.h"
24#include "lldb/API/SBCommunication.h"
25#include "lldb/API/SBDebugger.h"
26#include "lldb/API/SBEvent.h"
27#include "lldb/API/SBHostOS.h"
28#include "lldb/API/SBListener.h"
Jim Ingham85e8b812011-02-19 02:53:09 +000029#include "lldb/API/SBStream.h"
Eli Friedmana382d472010-06-09 09:50:17 +000030#include "lldb/API/SBTarget.h"
31#include "lldb/API/SBThread.h"
32#include "lldb/API/SBProcess.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000033
34using namespace lldb;
35
36static void reset_stdin_termios ();
Greg Claytonf571b892012-02-02 19:28:31 +000037static bool g_old_stdin_termios_is_valid = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000038static struct termios g_old_stdin_termios;
39
Caroline Ticedd759852010-09-09 17:45:09 +000040static char *g_debugger_name = (char *) "";
Caroline Ticeefed6132010-11-19 20:47:54 +000041static Driver *g_driver = NULL;
Caroline Ticedd759852010-09-09 17:45:09 +000042
Chris Lattner30fdc8d2010-06-08 16:52:24 +000043// In the Driver::MainLoop, we change the terminal settings. This function is
44// added as an atexit handler to make sure we clean them up.
45static void
46reset_stdin_termios ()
47{
Greg Claytonf571b892012-02-02 19:28:31 +000048 if (g_old_stdin_termios_is_valid)
49 {
50 g_old_stdin_termios_is_valid = false;
51 ::tcsetattr (STDIN_FILENO, TCSANOW, &g_old_stdin_termios);
52 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000053}
54
Greg Claytone0d378b2011-03-24 21:19:54 +000055typedef struct
Chris Lattner30fdc8d2010-06-08 16:52:24 +000056{
Greg Claytone0d378b2011-03-24 21:19:54 +000057 uint32_t usage_mask; // Used to mark options that can be used together. If (1 << n & usage_mask) != 0
58 // then this option belongs to option set n.
59 bool required; // This option is required (in the current usage level)
60 const char * long_option; // Full name for this option.
Greg Clayton3bcdfc02012-12-04 00:32:51 +000061 int short_option; // Single character for this option.
Greg Claytone0d378b2011-03-24 21:19:54 +000062 int option_has_arg; // no_argument, required_argument or optional_argument
Greg Claytonab65b342011-04-13 22:47:15 +000063 uint32_t completion_type; // Cookie the option class can use to do define the argument completion.
Greg Claytone0d378b2011-03-24 21:19:54 +000064 lldb::CommandArgumentType argument_type; // Type of argument this option takes
65 const char * usage_text; // Full text explaining what this options does and what (if any) argument to
66 // pass it.
67} OptionDefinition;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000068
Jim Inghame64f0dc2011-09-13 23:25:31 +000069#define LLDB_3_TO_5 LLDB_OPT_SET_3|LLDB_OPT_SET_4|LLDB_OPT_SET_5
70#define LLDB_4_TO_5 LLDB_OPT_SET_4|LLDB_OPT_SET_5
71
Greg Claytone0d378b2011-03-24 21:19:54 +000072static OptionDefinition g_options[] =
73{
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +000074 { LLDB_OPT_SET_1, true , "help" , 'h', no_argument , 0, eArgTypeNone,
Jim Ingham12e9a202011-09-15 21:30:02 +000075 "Prints out the usage information for the LLDB debugger." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +000076 { LLDB_OPT_SET_2, true , "version" , 'v', no_argument , 0, eArgTypeNone,
Jim Ingham12e9a202011-09-15 21:30:02 +000077 "Prints out the current version number of the LLDB debugger." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +000078 { LLDB_OPT_SET_3, true , "arch" , 'a', required_argument, 0, eArgTypeArchitecture,
Jim Ingham12e9a202011-09-15 21:30:02 +000079 "Tells the debugger to use the specified architecture when starting and running the program. <architecture> must "
80 "be one of the architectures for which the program was compiled." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +000081 { LLDB_OPT_SET_3, true , "file" , 'f', required_argument, 0, eArgTypeFilename,
Jim Ingham12e9a202011-09-15 21:30:02 +000082 "Tells the debugger to use the file <filename> as the program to be debugged." },
Jason Molenda67c3cf52012-10-24 03:29:40 +000083 { LLDB_OPT_SET_3, false, "core" , 'c', required_argument, 0, eArgTypeFilename,
Johnny Cheneb46f782012-08-15 22:10:42 +000084 "Tells the debugger to use the fullpath to <path> as the core file." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +000085 { LLDB_OPT_SET_4, true , "attach-name" , 'n', required_argument, 0, eArgTypeProcessName,
Jim Ingham12e9a202011-09-15 21:30:02 +000086 "Tells the debugger to attach to a process with the given name." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +000087 { LLDB_OPT_SET_4, true , "wait-for" , 'w', no_argument , 0, eArgTypeNone,
Jim Ingham12e9a202011-09-15 21:30:02 +000088 "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 +000089 { LLDB_OPT_SET_5, true , "attach-pid" , 'p', required_argument, 0, eArgTypePid,
Jim Ingham12e9a202011-09-15 21:30:02 +000090 "Tells the debugger to attach to a process with the given pid." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +000091 { LLDB_3_TO_5, false, "script-language", 'l', required_argument, 0, eArgTypeScriptLang,
Jim Ingham12e9a202011-09-15 21:30:02 +000092 "Tells the debugger to use the specified scripting language for user-defined scripts, rather than the default. "
93 "Valid scripting languages that can be specified include Python, Perl, Ruby and Tcl. Currently only the Python "
94 "extensions have been implemented." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +000095 { LLDB_3_TO_5, false, "debug" , 'd', no_argument , 0, eArgTypeNone,
Jim Ingham12e9a202011-09-15 21:30:02 +000096 "Tells the debugger to print out extra information for debugging itself." },
Jim Inghamed3252f2013-09-14 00:20:24 +000097 { LLDB_3_TO_5, false, "source-quietly" , 'b', no_argument , 0, eArgTypeNone,
98 "Tells the debugger to print out extra information for debugging itself." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +000099 { LLDB_3_TO_5, false, "source" , 's', required_argument, 0, eArgTypeFilename,
Jim Ingham47ea51f2013-09-17 01:53:35 +0000100 "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 +0000101 { LLDB_3_TO_5, false, "one-line" , 'o', required_argument, 0, eArgTypeNone,
Jim Ingham47ea51f2013-09-17 01:53:35 +0000102 "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 +0000103 { LLDB_3_TO_5, false, "source-before-file" , 'S', required_argument, 0, eArgTypeFilename,
Jim Ingham47ea51f2013-09-17 01:53:35 +0000104 "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 +0000105 { LLDB_3_TO_5, false, "one-line-before-file" , 'O', required_argument, 0, eArgTypeNone,
Jim Ingham47ea51f2013-09-17 01:53:35 +0000106 "Tells the debugger to execute this one-line lldb command before any file provided on the command line has been loaded." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +0000107 { LLDB_3_TO_5, false, "editor" , 'e', no_argument , 0, eArgTypeNone,
Jim Ingham12e9a202011-09-15 21:30:02 +0000108 "Tells the debugger to open source files using the host's \"external editor\" mechanism." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +0000109 { LLDB_3_TO_5, false, "no-lldbinit" , 'x', no_argument , 0, eArgTypeNone,
Jim Ingham12e9a202011-09-15 21:30:02 +0000110 "Do not automatically parse any '.lldbinit' files." },
Jim Inghamed3252f2013-09-14 00:20:24 +0000111 { LLDB_3_TO_5, false, "no-use-colors" , 'X', no_argument , 0, eArgTypeNone,
Michael Sartainc3ce7f272013-05-23 20:47:45 +0000112 "Do not use colors." },
113 { LLDB_OPT_SET_6, true , "python-path" , 'P', no_argument , 0, eArgTypeNone,
Jim Inghame2231ac2012-12-21 22:22:26 +0000114 "Prints out the path to the lldb.py file for this version of lldb." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +0000115 { 0, false, NULL , 0 , 0 , 0, eArgTypeNone, NULL }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000116};
117
Jim Inghame64f0dc2011-09-13 23:25:31 +0000118static const uint32_t last_option_set_with_args = 2;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000119
120Driver::Driver () :
121 SBBroadcaster ("Driver"),
Jim Ingham06942692011-08-13 00:22:20 +0000122 m_debugger (SBDebugger::Create(false)),
Greg Clayton44d93782014-01-27 23:43:24 +0000123 m_option_data ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000124{
Greg Claytonfc3f0272011-05-29 04:06:55 +0000125 // We want to be able to handle CTRL+D in the terminal to have it terminate
126 // certain input
127 m_debugger.SetCloseInputOnEOF (false);
Caroline Ticedd759852010-09-09 17:45:09 +0000128 g_debugger_name = (char *) m_debugger.GetInstanceName();
129 if (g_debugger_name == NULL)
130 g_debugger_name = (char *) "";
Caroline Ticeefed6132010-11-19 20:47:54 +0000131 g_driver = this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000132}
133
134Driver::~Driver ()
135{
Caroline Ticeefed6132010-11-19 20:47:54 +0000136 g_driver = NULL;
137 g_debugger_name = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000138}
139
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000140
Greg Claytonc982c762010-07-09 20:39:50 +0000141// This function takes INDENT, which tells how many spaces to output at the front
142// of each line; TEXT, which is the text that is to be output. It outputs the
143// text, on multiple lines if necessary, to RESULT, with INDENT spaces at the
144// front of each line. It breaks lines on spaces, tabs or newlines, shortening
145// the line if necessary to not break in the middle of a word. It assumes that
146// each output line should contain a maximum of OUTPUT_MAX_COLUMNS characters.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000147
148void
Greg Claytonc982c762010-07-09 20:39:50 +0000149OutputFormattedUsageText (FILE *out, int indent, const char *text, int output_max_columns)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000150{
151 int len = strlen (text);
152 std::string text_string (text);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000153
154 // Force indentation to be reasonable.
155 if (indent >= output_max_columns)
156 indent = 0;
157
158 // Will it all fit on one line?
159
160 if (len + indent < output_max_columns)
161 // Output as a single line
Greg Claytonc982c762010-07-09 20:39:50 +0000162 fprintf (out, "%*s%s\n", indent, "", text);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000163 else
164 {
165 // We need to break it up into multiple lines.
166 int text_width = output_max_columns - indent - 1;
167 int start = 0;
168 int end = start;
169 int final_end = len;
170 int sub_len;
171
172 while (end < final_end)
173 {
174 // Dont start the 'text' on a space, since we're already outputting the indentation.
175 while ((start < final_end) && (text[start] == ' '))
176 start++;
177
178 end = start + text_width;
179 if (end > final_end)
180 end = final_end;
181 else
182 {
183 // If we're not at the end of the text, make sure we break the line on white space.
184 while (end > start
185 && text[end] != ' ' && text[end] != '\t' && text[end] != '\n')
186 end--;
187 }
188 sub_len = end - start;
189 std::string substring = text_string.substr (start, sub_len);
Greg Claytonc982c762010-07-09 20:39:50 +0000190 fprintf (out, "%*s%s\n", indent, "", substring.c_str());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000191 start = end + 1;
192 }
193 }
194}
195
196void
Greg Claytone0d378b2011-03-24 21:19:54 +0000197ShowUsage (FILE *out, OptionDefinition *option_table, Driver::OptionData data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000198{
199 uint32_t screen_width = 80;
200 uint32_t indent_level = 0;
201 const char *name = "lldb";
Jim Ingham86511212010-06-15 18:47:14 +0000202
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000203 fprintf (out, "\nUsage:\n\n");
204
205 indent_level += 2;
206
207
208 // First, show each usage level set of options, e.g. <cmd> [options-for-level-0]
209 // <cmd> [options-for-level-1]
210 // etc.
211
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000212 uint32_t num_options;
Jim Ingham86511212010-06-15 18:47:14 +0000213 uint32_t num_option_sets = 0;
214
215 for (num_options = 0; option_table[num_options].long_option != NULL; ++num_options)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000216 {
Jim Ingham86511212010-06-15 18:47:14 +0000217 uint32_t this_usage_mask = option_table[num_options].usage_mask;
218 if (this_usage_mask == LLDB_OPT_SET_ALL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000219 {
Jim Ingham86511212010-06-15 18:47:14 +0000220 if (num_option_sets == 0)
221 num_option_sets = 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000222 }
223 else
224 {
Greg Claytonc982c762010-07-09 20:39:50 +0000225 for (uint32_t j = 0; j < LLDB_MAX_NUM_OPTION_SETS; j++)
Jim Ingham86511212010-06-15 18:47:14 +0000226 {
227 if (this_usage_mask & 1 << j)
228 {
229 if (num_option_sets <= j)
230 num_option_sets = j + 1;
231 }
232 }
233 }
234 }
235
236 for (uint32_t opt_set = 0; opt_set < num_option_sets; opt_set++)
237 {
238 uint32_t opt_set_mask;
239
240 opt_set_mask = 1 << opt_set;
241
242 if (opt_set > 0)
243 fprintf (out, "\n");
Greg Claytonc982c762010-07-09 20:39:50 +0000244 fprintf (out, "%*s%s", indent_level, "", name);
Jim Ingham556e6532011-08-16 23:15:02 +0000245 bool is_help_line = false;
Jim Ingham86511212010-06-15 18:47:14 +0000246
247 for (uint32_t i = 0; i < num_options; ++i)
248 {
249 if (option_table[i].usage_mask & opt_set_mask)
250 {
Caroline Ticedeaab222010-10-01 19:59:14 +0000251 CommandArgumentType arg_type = option_table[i].argument_type;
Greg Clayton9d0402b2011-02-20 02:15:07 +0000252 const char *arg_name = SBCommandInterpreter::GetArgumentTypeAsCString (arg_type);
Jim Ingham556e6532011-08-16 23:15:02 +0000253 // This is a bit of a hack, but there's no way to say certain options don't have arguments yet...
254 // so we do it by hand here.
255 if (option_table[i].short_option == 'h')
256 is_help_line = true;
257
Jim Ingham86511212010-06-15 18:47:14 +0000258 if (option_table[i].required)
259 {
260 if (option_table[i].option_has_arg == required_argument)
Greg Clayton9d0402b2011-02-20 02:15:07 +0000261 fprintf (out, " -%c <%s>", option_table[i].short_option, arg_name);
Jim Ingham86511212010-06-15 18:47:14 +0000262 else if (option_table[i].option_has_arg == optional_argument)
Greg Clayton9d0402b2011-02-20 02:15:07 +0000263 fprintf (out, " -%c [<%s>]", option_table[i].short_option, arg_name);
Jim Ingham86511212010-06-15 18:47:14 +0000264 else
265 fprintf (out, " -%c", option_table[i].short_option);
266 }
267 else
268 {
269 if (option_table[i].option_has_arg == required_argument)
Greg Clayton9d0402b2011-02-20 02:15:07 +0000270 fprintf (out, " [-%c <%s>]", option_table[i].short_option, arg_name);
Jim Ingham86511212010-06-15 18:47:14 +0000271 else if (option_table[i].option_has_arg == optional_argument)
Greg Clayton9d0402b2011-02-20 02:15:07 +0000272 fprintf (out, " [-%c [<%s>]]", option_table[i].short_option, arg_name);
Jim Ingham86511212010-06-15 18:47:14 +0000273 else
274 fprintf (out, " [-%c]", option_table[i].short_option);
275 }
276 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000277 }
Jim Inghame64f0dc2011-09-13 23:25:31 +0000278 if (!is_help_line && (opt_set <= last_option_set_with_args))
Jim Ingham556e6532011-08-16 23:15:02 +0000279 fprintf (out, " [[--] <PROGRAM-ARG-1> [<PROGRAM_ARG-2> ...]]");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000280 }
281
282 fprintf (out, "\n\n");
283
284 // Now print out all the detailed information about the various options: long form, short form and help text:
285 // -- long_name <argument>
286 // - short <argument>
287 // help text
288
289 // This variable is used to keep track of which options' info we've printed out, because some options can be in
290 // more than one usage level, but we only want to print the long form of its information once.
291
292 Driver::OptionData::OptionSet options_seen;
293 Driver::OptionData::OptionSet::iterator pos;
294
295 indent_level += 5;
296
Jim Ingham86511212010-06-15 18:47:14 +0000297 for (uint32_t i = 0; i < num_options; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000298 {
299 // Only print this option if we haven't already seen it.
300 pos = options_seen.find (option_table[i].short_option);
301 if (pos == options_seen.end())
302 {
Caroline Ticedeaab222010-10-01 19:59:14 +0000303 CommandArgumentType arg_type = option_table[i].argument_type;
Greg Clayton9d0402b2011-02-20 02:15:07 +0000304 const char *arg_name = SBCommandInterpreter::GetArgumentTypeAsCString (arg_type);
Caroline Ticedeaab222010-10-01 19:59:14 +0000305
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000306 options_seen.insert (option_table[i].short_option);
Greg Claytonc982c762010-07-09 20:39:50 +0000307 fprintf (out, "%*s-%c ", indent_level, "", option_table[i].short_option);
Caroline Ticedeaab222010-10-01 19:59:14 +0000308 if (arg_type != eArgTypeNone)
Greg Clayton9d0402b2011-02-20 02:15:07 +0000309 fprintf (out, "<%s>", arg_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000310 fprintf (out, "\n");
Greg Claytonc982c762010-07-09 20:39:50 +0000311 fprintf (out, "%*s--%s ", indent_level, "", option_table[i].long_option);
Caroline Ticedeaab222010-10-01 19:59:14 +0000312 if (arg_type != eArgTypeNone)
Greg Clayton9d0402b2011-02-20 02:15:07 +0000313 fprintf (out, "<%s>", arg_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000314 fprintf (out, "\n");
315 indent_level += 5;
Greg Claytonc982c762010-07-09 20:39:50 +0000316 OutputFormattedUsageText (out, indent_level, option_table[i].usage_text, screen_width);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000317 indent_level -= 5;
318 fprintf (out, "\n");
319 }
320 }
321
322 indent_level -= 5;
323
Jim Ingham47ea51f2013-09-17 01:53:35 +0000324 fprintf (out, "\n%*sMultiple \"-s\" and \"-o\" options can be provided. They will be processed from left to right in order, "
325 "\n%*swith the source files and commands interleaved. The same is true of the \"-S\" and \"-O\" options."
326 "\n%*sThe before file and after file sets can intermixed freely, the command parser will sort them out."
327 "\n%*sThe order of the file specifiers (\"-c\", \"-f\", etc.) is not significant in this regard.\n\n",
328 indent_level, "",
329 indent_level, "",
330 indent_level, "",
331 indent_level, "");
332
Jim Inghama9deaf92011-08-16 23:57:58 +0000333 fprintf (out, "\n%*s(If you don't provide -f then the first argument will be the file to be debugged"
334 "\n%*s so '%s -- <filename> [<ARG1> [<ARG2>]]' also works."
335 "\n%*s Remember to end the options with \"--\" if any of your arguments have a \"-\" in them.)\n\n",
336 indent_level, "",
337 indent_level, "",
338 name,
339 indent_level, "");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000340}
341
342void
Greg Claytone0d378b2011-03-24 21:19:54 +0000343BuildGetOptTable (OptionDefinition *expanded_option_table, std::vector<struct option> &getopt_table,
Caroline Tice4ab31c92010-10-12 21:57:09 +0000344 uint32_t num_options)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000345{
346 if (num_options == 0)
347 return;
348
349 uint32_t i;
350 uint32_t j;
351 std::bitset<256> option_seen;
352
Caroline Tice4ab31c92010-10-12 21:57:09 +0000353 getopt_table.resize (num_options + 1);
354
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000355 for (i = 0, j = 0; i < num_options; ++i)
Greg Claytonc982c762010-07-09 20:39:50 +0000356 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000357 char short_opt = expanded_option_table[i].short_option;
Greg Claytonc982c762010-07-09 20:39:50 +0000358
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000359 if (option_seen.test(short_opt) == false)
Greg Claytonc982c762010-07-09 20:39:50 +0000360 {
Caroline Tice4ab31c92010-10-12 21:57:09 +0000361 getopt_table[j].name = expanded_option_table[i].long_option;
362 getopt_table[j].has_arg = expanded_option_table[i].option_has_arg;
363 getopt_table[j].flag = NULL;
364 getopt_table[j].val = expanded_option_table[i].short_option;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000365 option_seen.set(short_opt);
366 ++j;
Greg Claytonc982c762010-07-09 20:39:50 +0000367 }
368 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000369
Caroline Tice4ab31c92010-10-12 21:57:09 +0000370 getopt_table[j].name = NULL;
371 getopt_table[j].has_arg = 0;
372 getopt_table[j].flag = NULL;
373 getopt_table[j].val = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000374
375}
376
Greg Clayton66111032010-06-23 01:19:29 +0000377Driver::OptionData::OptionData () :
Greg Clayton8d846da2010-12-08 22:23:24 +0000378 m_args(),
Greg Clayton66111032010-06-23 01:19:29 +0000379 m_script_lang (lldb::eScriptLanguageDefault),
Johnny Cheneb46f782012-08-15 22:10:42 +0000380 m_core_file (),
Greg Claytonc982c762010-07-09 20:39:50 +0000381 m_crash_log (),
Jim Inghamed3252f2013-09-14 00:20:24 +0000382 m_initial_commands (),
383 m_after_file_commands (),
Greg Clayton66111032010-06-23 01:19:29 +0000384 m_debug_mode (false),
Jim Inghamed3252f2013-09-14 00:20:24 +0000385 m_source_quietly(false),
Greg Claytonc982c762010-07-09 20:39:50 +0000386 m_print_version (false),
Jim Inghame2231ac2012-12-21 22:22:26 +0000387 m_print_python_path (false),
Greg Clayton66111032010-06-23 01:19:29 +0000388 m_print_help (false),
Jim Inghame64f0dc2011-09-13 23:25:31 +0000389 m_wait_for(false),
390 m_process_name(),
391 m_process_pid(LLDB_INVALID_PROCESS_ID),
Daniel Dunbara08823f2011-10-31 22:50:49 +0000392 m_use_external_editor(false),
Stephen Wilson71c21d12011-04-11 19:41:40 +0000393 m_seen_options()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000394{
Greg Clayton66111032010-06-23 01:19:29 +0000395}
396
397Driver::OptionData::~OptionData ()
398{
399}
400
401void
402Driver::OptionData::Clear ()
403{
Greg Clayton8d846da2010-12-08 22:23:24 +0000404 m_args.clear ();
Greg Clayton66111032010-06-23 01:19:29 +0000405 m_script_lang = lldb::eScriptLanguageDefault;
Jim Inghamed3252f2013-09-14 00:20:24 +0000406 m_initial_commands.clear ();
407 m_after_file_commands.clear ();
Greg Clayton66111032010-06-23 01:19:29 +0000408 m_debug_mode = false;
Jim Inghamed3252f2013-09-14 00:20:24 +0000409 m_source_quietly = false;
Greg Clayton66111032010-06-23 01:19:29 +0000410 m_print_help = false;
411 m_print_version = false;
Jim Inghame2231ac2012-12-21 22:22:26 +0000412 m_print_python_path = false;
Jim Inghame40e4212010-08-30 19:44:40 +0000413 m_use_external_editor = false;
Jim Inghame64f0dc2011-09-13 23:25:31 +0000414 m_wait_for = false;
415 m_process_name.erase();
416 m_process_pid = LLDB_INVALID_PROCESS_ID;
Greg Clayton66111032010-06-23 01:19:29 +0000417}
418
419void
Jim Inghamed3252f2013-09-14 00:20:24 +0000420Driver::OptionData::AddInitialCommand (const char *command, bool before_file, bool is_file, SBError &error)
421{
422 std::vector<std::pair<bool, std::string> > *command_set;
423 if (before_file)
424 command_set = &(m_initial_commands);
425 else
426 command_set = &(m_after_file_commands);
427
428 if (is_file)
429 {
430 SBFileSpec file(command);
431 if (file.Exists())
432 command_set->push_back (std::pair<bool, std::string> (true, optarg));
433 else if (file.ResolveExecutableLocation())
434 {
435 char final_path[PATH_MAX];
436 file.GetPath (final_path, sizeof(final_path));
437 std::string path_str (final_path);
438 command_set->push_back (std::pair<bool, std::string> (true, path_str));
439 }
440 else
441 error.SetErrorStringWithFormat("file specified in --source (-s) option doesn't exist: '%s'", optarg);
442 }
443 else
444 command_set->push_back (std::pair<bool, std::string> (false, optarg));
445}
446
447void
Greg Clayton66111032010-06-23 01:19:29 +0000448Driver::ResetOptionValues ()
449{
450 m_option_data.Clear ();
451}
452
453const char *
454Driver::GetFilename() const
455{
Greg Clayton8d846da2010-12-08 22:23:24 +0000456 if (m_option_data.m_args.empty())
Greg Clayton66111032010-06-23 01:19:29 +0000457 return NULL;
Greg Clayton8d846da2010-12-08 22:23:24 +0000458 return m_option_data.m_args.front().c_str();
Greg Clayton66111032010-06-23 01:19:29 +0000459}
460
461const char *
462Driver::GetCrashLogFilename() const
463{
464 if (m_option_data.m_crash_log.empty())
465 return NULL;
466 return m_option_data.m_crash_log.c_str();
467}
468
469lldb::ScriptLanguage
470Driver::GetScriptLanguage() const
471{
472 return m_option_data.m_script_lang;
473}
474
Jim Inghamed3252f2013-09-14 00:20:24 +0000475void
476Driver::ExecuteInitialCommands (bool before_file)
Greg Clayton66111032010-06-23 01:19:29 +0000477{
Jim Inghamed3252f2013-09-14 00:20:24 +0000478 size_t num_commands;
479 std::vector<std::pair<bool, std::string> > *command_set;
480 if (before_file)
481 command_set = &(m_option_data.m_initial_commands);
482 else
483 command_set = &(m_option_data.m_after_file_commands);
484
485 num_commands = command_set->size();
486 SBCommandReturnObject result;
487 bool old_async = GetDebugger().GetAsync();
488 GetDebugger().SetAsync(false);
489 for (size_t idx = 0; idx < num_commands; idx++)
490 {
491 bool is_file = (*command_set)[idx].first;
492 const char *command = (*command_set)[idx].second.c_str();
493 char command_string[PATH_MAX * 2];
494 const bool dump_stream_only_if_no_immediate = true;
495 const char *executed_command = command;
496 if (is_file)
497 {
498 ::snprintf (command_string, sizeof(command_string), "command source '%s'", command);
499 executed_command = command_string;
500 }
501
502 m_debugger.GetCommandInterpreter().HandleCommand (executed_command, result, false);
503 if (!m_option_data.m_source_quietly || result.Succeeded() == false)
504 {
505 const size_t output_size = result.GetOutputSize();
506 if (output_size > 0)
Greg Clayton44d93782014-01-27 23:43:24 +0000507 {
508 const char *cstr = result.GetOutput(dump_stream_only_if_no_immediate);
509 if (cstr)
510 printf ("%s", cstr);
511 }
Jim Inghamed3252f2013-09-14 00:20:24 +0000512 const size_t error_size = result.GetErrorSize();
513 if (error_size > 0)
Greg Clayton44d93782014-01-27 23:43:24 +0000514 {
515 const char *cstr = result.GetError(dump_stream_only_if_no_immediate);
516 if (cstr)
517 printf ("%s", cstr);
518 }
Jim Inghamed3252f2013-09-14 00:20:24 +0000519 }
520
521 if (result.Succeeded() == false)
522 {
Jim Inghamed3252f2013-09-14 00:20:24 +0000523 const char *type = before_file ? "before file" : "after_file";
524 if (is_file)
Greg Clayton44d93782014-01-27 23:43:24 +0000525 ::fprintf(stderr, "Aborting %s command execution, command file: '%s' failed.\n", type, command);
Jim Inghamed3252f2013-09-14 00:20:24 +0000526 else
Greg Clayton44d93782014-01-27 23:43:24 +0000527 ::fprintf(stderr, "Aborting %s command execution, command: '%s' failed.\n", type, command);
Jim Inghamed3252f2013-09-14 00:20:24 +0000528 break;
529 }
530 result.Clear();
531 }
532 GetDebugger().SetAsync(old_async);
Greg Clayton66111032010-06-23 01:19:29 +0000533}
534
535bool
536Driver::GetDebugMode() const
537{
538 return m_option_data.m_debug_mode;
539}
540
541
542// Check the arguments that were passed to this program to make sure they are valid and to get their
543// argument values (if any). Return a boolean value indicating whether or not to start up the full
544// debugger (i.e. the Command Interpreter) or not. Return FALSE if the arguments were invalid OR
545// if the user only wanted help or version information.
546
547SBError
Deepak Panickal429222c2013-10-15 15:46:40 +0000548Driver::ParseArgs (int argc, const char *argv[], FILE *out_fh, bool &exiting)
Greg Clayton66111032010-06-23 01:19:29 +0000549{
550 ResetOptionValues ();
551
552 SBCommandReturnObject result;
553
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000554 SBError error;
555 std::string option_string;
556 struct option *long_options = NULL;
Caroline Tice4ab31c92010-10-12 21:57:09 +0000557 std::vector<struct option> long_options_vector;
Greg Claytonc982c762010-07-09 20:39:50 +0000558 uint32_t num_options;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000559
Greg Claytonc982c762010-07-09 20:39:50 +0000560 for (num_options = 0; g_options[num_options].long_option != NULL; ++num_options)
561 /* Do Nothing. */;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000562
563 if (num_options == 0)
564 {
565 if (argc > 1)
566 error.SetErrorStringWithFormat ("invalid number of options");
567 return error;
568 }
569
Caroline Tice4ab31c92010-10-12 21:57:09 +0000570 BuildGetOptTable (g_options, long_options_vector, num_options);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000571
Caroline Tice4ab31c92010-10-12 21:57:09 +0000572 if (long_options_vector.empty())
573 long_options = NULL;
574 else
575 long_options = &long_options_vector.front();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000576
577 if (long_options == NULL)
578 {
579 error.SetErrorStringWithFormat ("invalid long options");
580 return error;
581 }
582
Greg Claytonb7ad58a2013-04-04 20:35:24 +0000583 // Build the option_string argument for call to getopt_long_only.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000584
585 for (int i = 0; long_options[i].name != NULL; ++i)
586 {
587 if (long_options[i].flag == NULL)
588 {
589 option_string.push_back ((char) long_options[i].val);
590 switch (long_options[i].has_arg)
591 {
592 default:
593 case no_argument:
594 break;
595 case required_argument:
596 option_string.push_back (':');
597 break;
598 case optional_argument:
599 option_string.append ("::");
600 break;
601 }
602 }
603 }
604
Jim Ingham06942692011-08-13 00:22:20 +0000605 // This is kind of a pain, but since we make the debugger in the Driver's constructor, we can't
606 // know at that point whether we should read in init files yet. So we don't read them in in the
607 // Driver constructor, then set the flags back to "read them in" here, and then if we see the
608 // "-n" flag, we'll turn it off again. Finally we have to read them in by hand later in the
609 // main loop.
610
611 m_debugger.SkipLLDBInitFiles (false);
612 m_debugger.SkipAppInitFiles (false);
613
Greg Claytonb7ad58a2013-04-04 20:35:24 +0000614 // Prepare for & make calls to getopt_long_only.
Eli Friedmanadb35022010-06-13 19:18:49 +0000615#if __GLIBC__
616 optind = 0;
617#else
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000618 optreset = 1;
619 optind = 1;
Eli Friedmanadb35022010-06-13 19:18:49 +0000620#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000621 int val;
622 while (1)
623 {
624 int long_options_index = -1;
Greg Claytonb7ad58a2013-04-04 20:35:24 +0000625 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 +0000626
627 if (val == -1)
628 break;
629 else if (val == '?')
630 {
Greg Clayton66111032010-06-23 01:19:29 +0000631 m_option_data.m_print_help = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000632 error.SetErrorStringWithFormat ("unknown or ambiguous option");
633 break;
634 }
635 else if (val == 0)
636 continue;
637 else
638 {
Greg Clayton66111032010-06-23 01:19:29 +0000639 m_option_data.m_seen_options.insert ((char) val);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000640 if (long_options_index == -1)
641 {
642 for (int i = 0;
643 long_options[i].name || long_options[i].has_arg || long_options[i].flag || long_options[i].val;
644 ++i)
645 {
646 if (long_options[i].val == val)
647 {
648 long_options_index = i;
649 break;
650 }
651 }
652 }
653
654 if (long_options_index >= 0)
655 {
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000656 const int short_option = g_options[long_options_index].short_option;
Greg Clayton66111032010-06-23 01:19:29 +0000657
658 switch (short_option)
659 {
660 case 'h':
661 m_option_data.m_print_help = true;
662 break;
663
664 case 'v':
665 m_option_data.m_print_version = true;
666 break;
667
Jim Inghame2231ac2012-12-21 22:22:26 +0000668 case 'P':
669 m_option_data.m_print_python_path = true;
670 break;
671
Greg Clayton66111032010-06-23 01:19:29 +0000672 case 'c':
Johnny Cheneb46f782012-08-15 22:10:42 +0000673 {
674 SBFileSpec file(optarg);
675 if (file.Exists())
676 {
677 m_option_data.m_core_file = optarg;
678 }
679 else
680 error.SetErrorStringWithFormat("file specified in --core (-c) option doesn't exist: '%s'", optarg);
681 }
Greg Clayton66111032010-06-23 01:19:29 +0000682 break;
Johnny Cheneb46f782012-08-15 22:10:42 +0000683
Jim Inghame40e4212010-08-30 19:44:40 +0000684 case 'e':
685 m_option_data.m_use_external_editor = true;
686 break;
Greg Clayton6eee5aa2010-10-11 01:05:37 +0000687
Jim Inghame64f0dc2011-09-13 23:25:31 +0000688 case 'x':
Greg Clayton6eee5aa2010-10-11 01:05:37 +0000689 m_debugger.SkipLLDBInitFiles (true);
Jim Ingham06942692011-08-13 00:22:20 +0000690 m_debugger.SkipAppInitFiles (true);
Greg Clayton6eee5aa2010-10-11 01:05:37 +0000691 break;
692
Jim Inghamed3252f2013-09-14 00:20:24 +0000693 case 'X':
Michael Sartainc3ce7f272013-05-23 20:47:45 +0000694 m_debugger.SetUseColor (false);
695 break;
696
Greg Clayton66111032010-06-23 01:19:29 +0000697 case 'f':
698 {
699 SBFileSpec file(optarg);
700 if (file.Exists())
Greg Clayton8d846da2010-12-08 22:23:24 +0000701 {
702 m_option_data.m_args.push_back (optarg);
703 }
Caroline Tice428a9a52010-09-10 04:48:55 +0000704 else if (file.ResolveExecutableLocation())
705 {
706 char path[PATH_MAX];
Johnny Chen25f3a3c2011-08-10 22:06:24 +0000707 file.GetPath (path, sizeof(path));
Greg Clayton8d846da2010-12-08 22:23:24 +0000708 m_option_data.m_args.push_back (path);
Caroline Tice428a9a52010-09-10 04:48:55 +0000709 }
Greg Clayton66111032010-06-23 01:19:29 +0000710 else
711 error.SetErrorStringWithFormat("file specified in --file (-f) option doesn't exist: '%s'", optarg);
712 }
713 break;
714
715 case 'a':
716 if (!m_debugger.SetDefaultArchitecture (optarg))
717 error.SetErrorStringWithFormat("invalid architecture in the -a or --arch option: '%s'", optarg);
718 break;
719
720 case 'l':
721 m_option_data.m_script_lang = m_debugger.GetScriptingLanguage (optarg);
722 break;
723
724 case 'd':
725 m_option_data.m_debug_mode = true;
726 break;
727
Jim Inghamed3252f2013-09-14 00:20:24 +0000728 case 'q':
729 m_option_data.m_source_quietly = true;
730 break;
731
Jim Inghame64f0dc2011-09-13 23:25:31 +0000732 case 'n':
733 m_option_data.m_process_name = optarg;
734 break;
735
736 case 'w':
737 m_option_data.m_wait_for = true;
738 break;
739
740 case 'p':
741 {
742 char *remainder;
743 m_option_data.m_process_pid = strtol (optarg, &remainder, 0);
744 if (remainder == optarg || *remainder != '\0')
745 error.SetErrorStringWithFormat ("Could not convert process PID: \"%s\" into a pid.",
746 optarg);
747 }
748 break;
Greg Clayton66111032010-06-23 01:19:29 +0000749 case 's':
Jim Inghamed3252f2013-09-14 00:20:24 +0000750 m_option_data.AddInitialCommand(optarg, false, true, error);
Greg Clayton66111032010-06-23 01:19:29 +0000751 break;
Jim Inghamed3252f2013-09-14 00:20:24 +0000752 case 'o':
753 m_option_data.AddInitialCommand(optarg, false, false, error);
754 break;
755 case 'S':
756 m_option_data.AddInitialCommand(optarg, true, true, error);
757 break;
758 case 'O':
759 m_option_data.AddInitialCommand(optarg, true, false, error);
760 break;
Greg Clayton66111032010-06-23 01:19:29 +0000761 default:
762 m_option_data.m_print_help = true;
763 error.SetErrorStringWithFormat ("unrecognized option %c", short_option);
764 break;
765 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000766 }
767 else
768 {
769 error.SetErrorStringWithFormat ("invalid option with value %i", val);
770 }
771 if (error.Fail())
Caroline Tice4ab31c92010-10-12 21:57:09 +0000772 {
Greg Clayton66111032010-06-23 01:19:29 +0000773 return error;
Caroline Tice4ab31c92010-10-12 21:57:09 +0000774 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000775 }
776 }
Jim Ingham86511212010-06-15 18:47:14 +0000777
Greg Clayton66111032010-06-23 01:19:29 +0000778 if (error.Fail() || m_option_data.m_print_help)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000779 {
780 ShowUsage (out_fh, g_options, m_option_data);
Deepak Panickal429222c2013-10-15 15:46:40 +0000781 exiting = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000782 }
783 else if (m_option_data.m_print_version)
784 {
Greg Clayton66111032010-06-23 01:19:29 +0000785 ::fprintf (out_fh, "%s\n", m_debugger.GetVersionString());
Deepak Panickal429222c2013-10-15 15:46:40 +0000786 exiting = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000787 }
Jim Inghame2231ac2012-12-21 22:22:26 +0000788 else if (m_option_data.m_print_python_path)
789 {
790 SBFileSpec python_file_spec = SBHostOS::GetLLDBPythonPath();
791 if (python_file_spec.IsValid())
792 {
793 char python_path[PATH_MAX];
794 size_t num_chars = python_file_spec.GetPath(python_path, PATH_MAX);
795 if (num_chars < PATH_MAX)
796 {
797 ::fprintf (out_fh, "%s\n", python_path);
798 }
799 else
800 ::fprintf (out_fh, "<PATH TOO LONG>\n");
801 }
802 else
803 ::fprintf (out_fh, "<COULD NOT FIND PATH>\n");
Deepak Panickal429222c2013-10-15 15:46:40 +0000804 exiting = true;
Jim Inghame2231ac2012-12-21 22:22:26 +0000805 }
Jim Inghame64f0dc2011-09-13 23:25:31 +0000806 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 +0000807 {
Greg Clayton8d846da2010-12-08 22:23:24 +0000808 // Any arguments that are left over after option parsing are for
809 // the program. If a file was specified with -f then the filename
810 // is already in the m_option_data.m_args array, and any remaining args
811 // are arguments for the inferior program. If no file was specified with
812 // -f, then what is left is the program name followed by any arguments.
813
Greg Claytonb7ad58a2013-04-04 20:35:24 +0000814 // Skip any options we consumed with getopt_long_only
Greg Clayton8d846da2010-12-08 22:23:24 +0000815 argc -= optind;
816 argv += optind;
817
818 if (argc > 0)
819 {
820 for (int arg_idx=0; arg_idx<argc; ++arg_idx)
821 {
822 const char *arg = argv[arg_idx];
823 if (arg)
824 m_option_data.m_args.push_back (arg);
825 }
826 }
827
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000828 }
Jim Inghame64f0dc2011-09-13 23:25:31 +0000829 else
830 {
Greg Claytonb7ad58a2013-04-04 20:35:24 +0000831 // Skip any options we consumed with getopt_long_only
Jim Inghame64f0dc2011-09-13 23:25:31 +0000832 argc -= optind;
Greg Clayton23f59502012-07-17 03:23:13 +0000833 //argv += optind; // Commented out to keep static analyzer happy
Jim Inghame64f0dc2011-09-13 23:25:31 +0000834
835 if (argc > 0)
836 ::fprintf (out_fh, "Warning: program arguments are ignored when attaching.\n");
837 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000838
Greg Clayton66111032010-06-23 01:19:29 +0000839 return error;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000840}
841
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000842void
843Driver::MainLoop ()
844{
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000845 if (::tcgetattr(STDIN_FILENO, &g_old_stdin_termios) == 0)
Greg Claytonf571b892012-02-02 19:28:31 +0000846 {
847 g_old_stdin_termios_is_valid = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000848 atexit (reset_stdin_termios);
Greg Claytonf571b892012-02-02 19:28:31 +0000849 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000850
851 ::setbuf (stdin, NULL);
852 ::setbuf (stdout, NULL);
853
Greg Clayton66111032010-06-23 01:19:29 +0000854 m_debugger.SetErrorFileHandle (stderr, false);
855 m_debugger.SetOutputFileHandle (stdout, false);
856 m_debugger.SetInputFileHandle (stdin, true);
Jim Inghame40e4212010-08-30 19:44:40 +0000857
858 m_debugger.SetUseExternalEditor(m_option_data.m_use_external_editor);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000859
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000860 struct winsize window_size;
861 if (isatty (STDIN_FILENO)
862 && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0)
863 {
Caroline Tice3df9a8d2010-09-04 00:03:46 +0000864 if (window_size.ws_col > 0)
Greg Claytona7015092010-09-18 01:14:36 +0000865 m_debugger.SetTerminalWidth (window_size.ws_col);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000866 }
867
Greg Clayton44d93782014-01-27 23:43:24 +0000868 SBCommandInterpreter sb_interpreter = m_debugger.GetCommandInterpreter();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000869
Greg Clayton44d93782014-01-27 23:43:24 +0000870 // Before we handle any options from the command line, we parse the
871 // .lldbinit file in the user's home directory.
872 SBCommandReturnObject result;
873 sb_interpreter.SourceInitFileInHomeDirectory(result);
874 if (GetDebugMode())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000875 {
Greg Clayton44d93782014-01-27 23:43:24 +0000876 result.PutError (m_debugger.GetErrorFileHandle());
877 result.PutOutput (m_debugger.GetOutputFileHandle());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000878 }
Greg Clayton44d93782014-01-27 23:43:24 +0000879
880 // Now we handle options we got from the command line
881 // First source in the commands specified to be run before the file arguments are processed.
882 ExecuteInitialCommands(true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000883
Greg Clayton44d93782014-01-27 23:43:24 +0000884 // Was there a core file specified?
885 std::string core_file_spec("");
886 if (!m_option_data.m_core_file.empty())
887 core_file_spec.append("--core ").append(m_option_data.m_core_file);
888
889 char command_string[PATH_MAX * 2];
890 const size_t num_args = m_option_data.m_args.size();
891 if (num_args > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000892 {
Greg Clayton44d93782014-01-27 23:43:24 +0000893 char arch_name[64];
894 if (m_debugger.GetDefaultArchitecture (arch_name, sizeof (arch_name)))
895 ::snprintf (command_string,
896 sizeof (command_string),
897 "target create --arch=%s %s \"%s\"",
898 arch_name,
899 core_file_spec.c_str(),
900 m_option_data.m_args[0].c_str());
901 else
902 ::snprintf (command_string,
903 sizeof(command_string),
904 "target create %s \"%s\"",
905 core_file_spec.c_str(),
906 m_option_data.m_args[0].c_str());
907
908 m_debugger.HandleCommand (command_string);
909
910 if (num_args > 1)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000911 {
Greg Clayton44d93782014-01-27 23:43:24 +0000912 m_debugger.HandleCommand ("settings clear target.run-args");
913 char arg_cstr[1024];
914 for (size_t arg_idx = 1; arg_idx < num_args; ++arg_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000915 {
Greg Clayton44d93782014-01-27 23:43:24 +0000916 ::snprintf (arg_cstr,
917 sizeof(arg_cstr),
918 "settings append target.run-args \"%s\"",
919 m_option_data.m_args[arg_idx].c_str());
920 m_debugger.HandleCommand (arg_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000921 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000922 }
923 }
Greg Clayton44d93782014-01-27 23:43:24 +0000924 else if (!core_file_spec.empty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000925 {
Greg Clayton44d93782014-01-27 23:43:24 +0000926 ::snprintf (command_string,
927 sizeof(command_string),
928 "target create %s",
929 core_file_spec.c_str());
930 m_debugger.HandleCommand (command_string);;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000931 }
Greg Clayton44d93782014-01-27 23:43:24 +0000932
933 ExecuteInitialCommands(false);
934
935 // Now that all option parsing is done, we try and parse the .lldbinit
936 // file in the current working directory
937 sb_interpreter.SourceInitFileInCurrentWorkingDirectory (result);
938 if (GetDebugMode())
939 {
940 result.PutError(m_debugger.GetErrorFileHandle());
941 result.PutOutput(m_debugger.GetOutputFileHandle());
942 }
943
944 bool handle_events = true;
945 bool spawn_thread = false;
946 m_debugger.RunCommandInterpreter(handle_events, spawn_thread);
947
948 reset_stdin_termios();
949 fclose (stdin);
950
951 SBDebugger::Destroy (m_debugger);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000952}
953
Greg Clayton44d93782014-01-27 23:43:24 +0000954
Jim Inghamc46fe7c2013-02-22 22:56:55 +0000955void
956Driver::ResizeWindow (unsigned short col)
957{
958 GetDebugger().SetTerminalWidth (col);
Jim Inghamc46fe7c2013-02-22 22:56:55 +0000959}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000960
Caroline Ticedd759852010-09-09 17:45:09 +0000961void
962sigwinch_handler (int signo)
963{
964 struct winsize window_size;
965 if (isatty (STDIN_FILENO)
966 && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0)
967 {
Jim Ingham57190ba2012-04-26 21:39:32 +0000968 if ((window_size.ws_col > 0) && g_driver != NULL)
Caroline Ticedd759852010-09-09 17:45:09 +0000969 {
Jim Inghamc46fe7c2013-02-22 22:56:55 +0000970 g_driver->ResizeWindow (window_size.ws_col);
Caroline Ticedd759852010-09-09 17:45:09 +0000971 }
972 }
973}
974
Caroline Ticeefed6132010-11-19 20:47:54 +0000975void
976sigint_handler (int signo)
977{
978 static bool g_interrupt_sent = false;
979 if (g_driver)
980 {
981 if (!g_interrupt_sent)
982 {
983 g_interrupt_sent = true;
984 g_driver->GetDebugger().DispatchInputInterrupt();
985 g_interrupt_sent = false;
986 return;
987 }
988 }
989
990 exit (signo);
991}
992
Jim Inghamc5917d92012-11-30 20:23:19 +0000993void
994sigtstp_handler (int signo)
995{
996 g_driver->GetDebugger().SaveInputTerminalState();
997 signal (signo, SIG_DFL);
998 kill (getpid(), signo);
999 signal (signo, sigtstp_handler);
1000}
1001
1002void
1003sigcont_handler (int signo)
1004{
1005 g_driver->GetDebugger().RestoreInputTerminalState();
1006 signal (signo, SIG_DFL);
1007 kill (getpid(), signo);
1008 signal (signo, sigcont_handler);
1009}
1010
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001011int
Jim Inghama462f5c2011-01-27 20:15:39 +00001012main (int argc, char const *argv[], const char *envp[])
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001013{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001014 SBDebugger::Initialize();
1015
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00001016 SBHostOS::ThreadCreated ("<lldb.driver.main-thread>");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001017
Greg Clayton3fcbed62010-10-19 03:25:40 +00001018 signal (SIGPIPE, SIG_IGN);
Caroline Ticedd759852010-09-09 17:45:09 +00001019 signal (SIGWINCH, sigwinch_handler);
Caroline Ticeefed6132010-11-19 20:47:54 +00001020 signal (SIGINT, sigint_handler);
Jim Inghamc5917d92012-11-30 20:23:19 +00001021 signal (SIGTSTP, sigtstp_handler);
1022 signal (SIGCONT, sigcont_handler);
Caroline Ticedd759852010-09-09 17:45:09 +00001023
Greg Clayton66111032010-06-23 01:19:29 +00001024 // Create a scope for driver so that the driver object will destroy itself
1025 // before SBDebugger::Terminate() is called.
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001026 {
Greg Clayton66111032010-06-23 01:19:29 +00001027 Driver driver;
1028
Deepak Panickal429222c2013-10-15 15:46:40 +00001029 bool exiting = false;
1030 SBError error (driver.ParseArgs (argc, argv, stdout, exiting));
Greg Clayton66111032010-06-23 01:19:29 +00001031 if (error.Fail())
1032 {
1033 const char *error_cstr = error.GetCString ();
1034 if (error_cstr)
1035 ::fprintf (stderr, "error: %s\n", error_cstr);
1036 }
Deepak Panickal429222c2013-10-15 15:46:40 +00001037 else if (!exiting)
Greg Clayton66111032010-06-23 01:19:29 +00001038 {
1039 driver.MainLoop ();
1040 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001041 }
1042
1043 SBDebugger::Terminate();
1044 return 0;
1045}