blob: 17c29fc4fdaaf0b979062a489b32c5fc6cb9d4be [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- Driver.cpp ----------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "Driver.h"
11
Deepak Panickal429222c2013-10-15 15:46:40 +000012#include <stdio.h>
Eli Friedmana382d472010-06-09 09:50:17 +000013#include <string.h>
14#include <stdlib.h>
15#include <limits.h>
Eli Friedman07b16272010-06-09 19:11:30 +000016#include <fcntl.h>
Chris Lattner30fdc8d2010-06-08 16:52:24 +000017
Greg Clayton49668762014-08-01 18:32:07 +000018// Includes for pipe()
19#if defined(_WIN32)
20#include <io.h>
21#include <fcntl.h>
Shawn Best8da0bf32014-11-08 01:41:49 +000022#elif defined(__ANDROID_NDK__)
23#include <errno.h>
Greg Clayton49668762014-08-01 18:32:07 +000024#else
25#include <unistd.h>
26#endif
27
Chris Lattner30fdc8d2010-06-08 16:52:24 +000028#include <string>
29
Deepak Panickal429222c2013-10-15 15:46:40 +000030#include <thread>
Jim Inghame6bc6cb2012-02-08 05:23:15 +000031#include "lldb/API/SBBreakpoint.h"
Eli Friedmana382d472010-06-09 09:50:17 +000032#include "lldb/API/SBCommandInterpreter.h"
33#include "lldb/API/SBCommandReturnObject.h"
34#include "lldb/API/SBCommunication.h"
35#include "lldb/API/SBDebugger.h"
36#include "lldb/API/SBEvent.h"
37#include "lldb/API/SBHostOS.h"
Sean Callanan3e7e9152015-10-20 00:23:46 +000038#include "lldb/API/SBLanguageRuntime.h"
Eli Friedmana382d472010-06-09 09:50:17 +000039#include "lldb/API/SBListener.h"
Jim Ingham85e8b812011-02-19 02:53:09 +000040#include "lldb/API/SBStream.h"
Eli Friedmana382d472010-06-09 09:50:17 +000041#include "lldb/API/SBTarget.h"
42#include "lldb/API/SBThread.h"
43#include "lldb/API/SBProcess.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000044
Todd Fialab82ad2a2014-09-15 15:17:13 +000045#if !defined(__APPLE__)
Zachary Turner40a069a2014-09-11 20:26:49 +000046#include "llvm/Support/DataTypes.h"
Todd Fialab82ad2a2014-09-15 15:17:13 +000047#endif
Zachary Turner40a069a2014-09-11 20:26:49 +000048
Chris Lattner30fdc8d2010-06-08 16:52:24 +000049using namespace lldb;
50
51static void reset_stdin_termios ();
Greg Claytonf571b892012-02-02 19:28:31 +000052static bool g_old_stdin_termios_is_valid = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000053static struct termios g_old_stdin_termios;
54
Caroline Ticeefed6132010-11-19 20:47:54 +000055static Driver *g_driver = NULL;
Caroline Ticedd759852010-09-09 17:45:09 +000056
Chris Lattner30fdc8d2010-06-08 16:52:24 +000057// In the Driver::MainLoop, we change the terminal settings. This function is
58// added as an atexit handler to make sure we clean them up.
59static void
60reset_stdin_termios ()
61{
Greg Claytonf571b892012-02-02 19:28:31 +000062 if (g_old_stdin_termios_is_valid)
63 {
64 g_old_stdin_termios_is_valid = false;
65 ::tcsetattr (STDIN_FILENO, TCSANOW, &g_old_stdin_termios);
66 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000067}
68
Greg Claytone0d378b2011-03-24 21:19:54 +000069typedef struct
Chris Lattner30fdc8d2010-06-08 16:52:24 +000070{
Greg Claytone0d378b2011-03-24 21:19:54 +000071 uint32_t usage_mask; // Used to mark options that can be used together. If (1 << n & usage_mask) != 0
72 // then this option belongs to option set n.
73 bool required; // This option is required (in the current usage level)
74 const char * long_option; // Full name for this option.
Greg Clayton3bcdfc02012-12-04 00:32:51 +000075 int short_option; // Single character for this option.
Greg Claytone0d378b2011-03-24 21:19:54 +000076 int option_has_arg; // no_argument, required_argument or optional_argument
Greg Claytonab65b342011-04-13 22:47:15 +000077 uint32_t completion_type; // Cookie the option class can use to do define the argument completion.
Greg Claytone0d378b2011-03-24 21:19:54 +000078 lldb::CommandArgumentType argument_type; // Type of argument this option takes
79 const char * usage_text; // Full text explaining what this options does and what (if any) argument to
80 // pass it.
81} OptionDefinition;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000082
Jim Inghame64f0dc2011-09-13 23:25:31 +000083#define LLDB_3_TO_5 LLDB_OPT_SET_3|LLDB_OPT_SET_4|LLDB_OPT_SET_5
84#define LLDB_4_TO_5 LLDB_OPT_SET_4|LLDB_OPT_SET_5
85
Greg Claytone0d378b2011-03-24 21:19:54 +000086static OptionDefinition g_options[] =
87{
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +000088 { LLDB_OPT_SET_1, true , "help" , 'h', no_argument , 0, eArgTypeNone,
Jim Ingham12e9a202011-09-15 21:30:02 +000089 "Prints out the usage information for the LLDB debugger." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +000090 { LLDB_OPT_SET_2, true , "version" , 'v', no_argument , 0, eArgTypeNone,
Jim Ingham12e9a202011-09-15 21:30:02 +000091 "Prints out the current version number of the LLDB debugger." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +000092 { LLDB_OPT_SET_3, true , "arch" , 'a', required_argument, 0, eArgTypeArchitecture,
Jim Ingham12e9a202011-09-15 21:30:02 +000093 "Tells the debugger to use the specified architecture when starting and running the program. <architecture> must "
94 "be one of the architectures for which the program was compiled." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +000095 { LLDB_OPT_SET_3, true , "file" , 'f', required_argument, 0, eArgTypeFilename,
Jim Ingham12e9a202011-09-15 21:30:02 +000096 "Tells the debugger to use the file <filename> as the program to be debugged." },
Jason Molenda67c3cf52012-10-24 03:29:40 +000097 { LLDB_OPT_SET_3, false, "core" , 'c', required_argument, 0, eArgTypeFilename,
Johnny Cheneb46f782012-08-15 22:10:42 +000098 "Tells the debugger to use the fullpath to <path> as the core file." },
Jim Inghamf0c63b92014-02-05 21:35:09 +000099 { LLDB_OPT_SET_5, true , "attach-pid" , 'p', required_argument, 0, eArgTypePid,
100 "Tells the debugger to attach to a process with the given pid." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +0000101 { LLDB_OPT_SET_4, true , "attach-name" , 'n', required_argument, 0, eArgTypeProcessName,
Jim Ingham12e9a202011-09-15 21:30:02 +0000102 "Tells the debugger to attach to a process with the given name." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +0000103 { LLDB_OPT_SET_4, true , "wait-for" , 'w', no_argument , 0, eArgTypeNone,
Jim Ingham12e9a202011-09-15 21:30:02 +0000104 "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 +0000105 { LLDB_3_TO_5, false, "source" , 's', required_argument, 0, eArgTypeFilename,
Jim Ingham47ea51f2013-09-17 01:53:35 +0000106 "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 +0000107 { LLDB_3_TO_5, false, "one-line" , 'o', required_argument, 0, eArgTypeNone,
Jim Ingham47ea51f2013-09-17 01:53:35 +0000108 "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 +0000109 { LLDB_3_TO_5, false, "source-before-file" , 'S', required_argument, 0, eArgTypeFilename,
Jim Ingham47ea51f2013-09-17 01:53:35 +0000110 "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 +0000111 { LLDB_3_TO_5, false, "one-line-before-file" , 'O', required_argument, 0, eArgTypeNone,
Jim Ingham47ea51f2013-09-17 01:53:35 +0000112 "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 +0000113 { LLDB_3_TO_5, false, "one-line-on-crash" , 'k', required_argument, 0, eArgTypeNone,
114 "When in batch mode, tells the debugger to execute this one-line lldb command if the target crashes." },
115 { LLDB_3_TO_5, false, "source-on-crash" , 'K', required_argument, 0, eArgTypeFilename,
116 "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 +0000117 { LLDB_3_TO_5, false, "source-quietly" , 'Q', no_argument , 0, eArgTypeNone,
Jim Inghamffc9f1d2014-10-14 01:20:07 +0000118 "Tells the debugger to execute this one-line lldb command before any file provided on the command line has been loaded." },
119 { LLDB_3_TO_5, false, "batch" , 'b', no_argument , 0, eArgTypeNone,
120 "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, "
121 "the debugger will return to the interactive prompt at the place of the crash." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +0000122 { LLDB_3_TO_5, false, "editor" , 'e', no_argument , 0, eArgTypeNone,
Jim Ingham12e9a202011-09-15 21:30:02 +0000123 "Tells the debugger to open source files using the host's \"external editor\" mechanism." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +0000124 { LLDB_3_TO_5, false, "no-lldbinit" , 'x', no_argument , 0, eArgTypeNone,
Jim Ingham12e9a202011-09-15 21:30:02 +0000125 "Do not automatically parse any '.lldbinit' files." },
Jim Inghamed3252f2013-09-14 00:20:24 +0000126 { LLDB_3_TO_5, false, "no-use-colors" , 'X', no_argument , 0, eArgTypeNone,
Michael Sartainc3ce7f272013-05-23 20:47:45 +0000127 "Do not use colors." },
128 { LLDB_OPT_SET_6, true , "python-path" , 'P', no_argument , 0, eArgTypeNone,
Jim Inghame2231ac2012-12-21 22:22:26 +0000129 "Prints out the path to the lldb.py file for this version of lldb." },
Jim Inghamf0c63b92014-02-05 21:35:09 +0000130 { LLDB_3_TO_5, false, "script-language", 'l', required_argument, 0, eArgTypeScriptLang,
131 "Tells the debugger to use the specified scripting language for user-defined scripts, rather than the default. "
132 "Valid scripting languages that can be specified include Python, Perl, Ruby and Tcl. Currently only the Python "
133 "extensions have been implemented." },
134 { LLDB_3_TO_5, false, "debug" , 'd', no_argument , 0, eArgTypeNone,
135 "Tells the debugger to print out extra information for debugging itself." },
Sean Callanan3e7e9152015-10-20 00:23:46 +0000136 { LLDB_OPT_SET_7, true , "repl" , 'r', optional_argument, 0, eArgTypeNone,
137 "Runs lldb in REPL mode with a stub process." },
138 { LLDB_OPT_SET_7, true , "repl-language" , 'R', required_argument, 0, eArgTypeNone,
139 "Chooses the language for the REPL." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +0000140 { 0, false, NULL , 0 , 0 , 0, eArgTypeNone, NULL }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000141};
142
Jim Inghame64f0dc2011-09-13 23:25:31 +0000143static const uint32_t last_option_set_with_args = 2;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000144
145Driver::Driver () :
146 SBBroadcaster ("Driver"),
Jim Ingham06942692011-08-13 00:22:20 +0000147 m_debugger (SBDebugger::Create(false)),
Greg Clayton44d93782014-01-27 23:43:24 +0000148 m_option_data ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000149{
Greg Claytonfc3f0272011-05-29 04:06:55 +0000150 // We want to be able to handle CTRL+D in the terminal to have it terminate
151 // certain input
152 m_debugger.SetCloseInputOnEOF (false);
Caroline Ticeefed6132010-11-19 20:47:54 +0000153 g_driver = this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000154}
155
156Driver::~Driver ()
157{
Caroline Ticeefed6132010-11-19 20:47:54 +0000158 g_driver = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000159}
160
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000161
Greg Claytonc982c762010-07-09 20:39:50 +0000162// This function takes INDENT, which tells how many spaces to output at the front
163// of each line; TEXT, which is the text that is to be output. It outputs the
164// text, on multiple lines if necessary, to RESULT, with INDENT spaces at the
165// front of each line. It breaks lines on spaces, tabs or newlines, shortening
166// the line if necessary to not break in the middle of a word. It assumes that
167// each output line should contain a maximum of OUTPUT_MAX_COLUMNS characters.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000168
169void
Greg Claytonc982c762010-07-09 20:39:50 +0000170OutputFormattedUsageText (FILE *out, int indent, const char *text, int output_max_columns)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000171{
172 int len = strlen (text);
173 std::string text_string (text);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000174
175 // Force indentation to be reasonable.
176 if (indent >= output_max_columns)
177 indent = 0;
178
179 // Will it all fit on one line?
180
181 if (len + indent < output_max_columns)
182 // Output as a single line
Greg Claytonc982c762010-07-09 20:39:50 +0000183 fprintf (out, "%*s%s\n", indent, "", text);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000184 else
185 {
186 // We need to break it up into multiple lines.
187 int text_width = output_max_columns - indent - 1;
188 int start = 0;
189 int end = start;
190 int final_end = len;
191 int sub_len;
192
193 while (end < final_end)
194 {
195 // Dont start the 'text' on a space, since we're already outputting the indentation.
196 while ((start < final_end) && (text[start] == ' '))
197 start++;
198
199 end = start + text_width;
200 if (end > final_end)
201 end = final_end;
202 else
203 {
204 // If we're not at the end of the text, make sure we break the line on white space.
205 while (end > start
206 && text[end] != ' ' && text[end] != '\t' && text[end] != '\n')
207 end--;
208 }
209 sub_len = end - start;
210 std::string substring = text_string.substr (start, sub_len);
Greg Claytonc982c762010-07-09 20:39:50 +0000211 fprintf (out, "%*s%s\n", indent, "", substring.c_str());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000212 start = end + 1;
213 }
214 }
215}
216
217void
Greg Claytone0d378b2011-03-24 21:19:54 +0000218ShowUsage (FILE *out, OptionDefinition *option_table, Driver::OptionData data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000219{
220 uint32_t screen_width = 80;
221 uint32_t indent_level = 0;
222 const char *name = "lldb";
Jim Ingham86511212010-06-15 18:47:14 +0000223
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000224 fprintf (out, "\nUsage:\n\n");
225
226 indent_level += 2;
227
228
229 // First, show each usage level set of options, e.g. <cmd> [options-for-level-0]
230 // <cmd> [options-for-level-1]
231 // etc.
232
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000233 uint32_t num_options;
Jim Ingham86511212010-06-15 18:47:14 +0000234 uint32_t num_option_sets = 0;
235
236 for (num_options = 0; option_table[num_options].long_option != NULL; ++num_options)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000237 {
Jim Ingham86511212010-06-15 18:47:14 +0000238 uint32_t this_usage_mask = option_table[num_options].usage_mask;
239 if (this_usage_mask == LLDB_OPT_SET_ALL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000240 {
Jim Ingham86511212010-06-15 18:47:14 +0000241 if (num_option_sets == 0)
242 num_option_sets = 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000243 }
244 else
245 {
Greg Claytonc982c762010-07-09 20:39:50 +0000246 for (uint32_t j = 0; j < LLDB_MAX_NUM_OPTION_SETS; j++)
Jim Ingham86511212010-06-15 18:47:14 +0000247 {
248 if (this_usage_mask & 1 << j)
249 {
250 if (num_option_sets <= j)
251 num_option_sets = j + 1;
252 }
253 }
254 }
255 }
256
257 for (uint32_t opt_set = 0; opt_set < num_option_sets; opt_set++)
258 {
259 uint32_t opt_set_mask;
260
261 opt_set_mask = 1 << opt_set;
262
263 if (opt_set > 0)
264 fprintf (out, "\n");
Greg Claytonc982c762010-07-09 20:39:50 +0000265 fprintf (out, "%*s%s", indent_level, "", name);
Jim Ingham556e6532011-08-16 23:15:02 +0000266 bool is_help_line = false;
Jim Ingham86511212010-06-15 18:47:14 +0000267
268 for (uint32_t i = 0; i < num_options; ++i)
269 {
270 if (option_table[i].usage_mask & opt_set_mask)
271 {
Caroline Ticedeaab222010-10-01 19:59:14 +0000272 CommandArgumentType arg_type = option_table[i].argument_type;
Greg Clayton9d0402b2011-02-20 02:15:07 +0000273 const char *arg_name = SBCommandInterpreter::GetArgumentTypeAsCString (arg_type);
Jim Ingham556e6532011-08-16 23:15:02 +0000274 // This is a bit of a hack, but there's no way to say certain options don't have arguments yet...
275 // so we do it by hand here.
276 if (option_table[i].short_option == 'h')
277 is_help_line = true;
278
Jim Ingham86511212010-06-15 18:47:14 +0000279 if (option_table[i].required)
280 {
281 if (option_table[i].option_has_arg == required_argument)
Greg Clayton9d0402b2011-02-20 02:15:07 +0000282 fprintf (out, " -%c <%s>", option_table[i].short_option, arg_name);
Jim Ingham86511212010-06-15 18:47:14 +0000283 else if (option_table[i].option_has_arg == optional_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
286 fprintf (out, " -%c", option_table[i].short_option);
287 }
288 else
289 {
290 if (option_table[i].option_has_arg == required_argument)
Greg Clayton9d0402b2011-02-20 02:15:07 +0000291 fprintf (out, " [-%c <%s>]", option_table[i].short_option, arg_name);
Jim Ingham86511212010-06-15 18:47:14 +0000292 else if (option_table[i].option_has_arg == optional_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
295 fprintf (out, " [-%c]", option_table[i].short_option);
296 }
297 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000298 }
Jim Inghame64f0dc2011-09-13 23:25:31 +0000299 if (!is_help_line && (opt_set <= last_option_set_with_args))
Jim Ingham556e6532011-08-16 23:15:02 +0000300 fprintf (out, " [[--] <PROGRAM-ARG-1> [<PROGRAM_ARG-2> ...]]");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000301 }
302
303 fprintf (out, "\n\n");
304
305 // Now print out all the detailed information about the various options: long form, short form and help text:
306 // -- long_name <argument>
307 // - short <argument>
308 // help text
309
310 // This variable is used to keep track of which options' info we've printed out, because some options can be in
311 // more than one usage level, but we only want to print the long form of its information once.
312
313 Driver::OptionData::OptionSet options_seen;
314 Driver::OptionData::OptionSet::iterator pos;
315
316 indent_level += 5;
317
Jim Ingham86511212010-06-15 18:47:14 +0000318 for (uint32_t i = 0; i < num_options; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000319 {
320 // Only print this option if we haven't already seen it.
321 pos = options_seen.find (option_table[i].short_option);
322 if (pos == options_seen.end())
323 {
Caroline Ticedeaab222010-10-01 19:59:14 +0000324 CommandArgumentType arg_type = option_table[i].argument_type;
Greg Clayton9d0402b2011-02-20 02:15:07 +0000325 const char *arg_name = SBCommandInterpreter::GetArgumentTypeAsCString (arg_type);
Caroline Ticedeaab222010-10-01 19:59:14 +0000326
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000327 options_seen.insert (option_table[i].short_option);
Greg Claytonc982c762010-07-09 20:39:50 +0000328 fprintf (out, "%*s-%c ", indent_level, "", option_table[i].short_option);
Caroline Ticedeaab222010-10-01 19:59:14 +0000329 if (arg_type != eArgTypeNone)
Greg Clayton9d0402b2011-02-20 02:15:07 +0000330 fprintf (out, "<%s>", arg_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000331 fprintf (out, "\n");
Greg Claytonc982c762010-07-09 20:39:50 +0000332 fprintf (out, "%*s--%s ", indent_level, "", option_table[i].long_option);
Caroline Ticedeaab222010-10-01 19:59:14 +0000333 if (arg_type != eArgTypeNone)
Greg Clayton9d0402b2011-02-20 02:15:07 +0000334 fprintf (out, "<%s>", arg_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000335 fprintf (out, "\n");
336 indent_level += 5;
Greg Claytonc982c762010-07-09 20:39:50 +0000337 OutputFormattedUsageText (out, indent_level, option_table[i].usage_text, screen_width);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000338 indent_level -= 5;
339 fprintf (out, "\n");
340 }
341 }
342
343 indent_level -= 5;
Jim Inghamf0c63b92014-02-05 21:35:09 +0000344
345 fprintf (out, "\n%*sNotes:\n",
346 indent_level, "");
347 indent_level += 5;
348
Jim Ingham47ea51f2013-09-17 01:53:35 +0000349 fprintf (out, "\n%*sMultiple \"-s\" and \"-o\" options can be provided. They will be processed from left to right in order, "
350 "\n%*swith the source files and commands interleaved. The same is true of the \"-S\" and \"-O\" options."
351 "\n%*sThe before file and after file sets can intermixed freely, the command parser will sort them out."
352 "\n%*sThe order of the file specifiers (\"-c\", \"-f\", etc.) is not significant in this regard.\n\n",
353 indent_level, "",
354 indent_level, "",
355 indent_level, "",
356 indent_level, "");
357
Jim Inghamf0c63b92014-02-05 21:35:09 +0000358 fprintf (out, "\n%*sIf you don't provide -f then the first argument will be the file to be debugged"
359 "\n%*swhich means that '%s -- <filename> [<ARG1> [<ARG2>]]' also works."
360 "\n%*sBut remember to end the options with \"--\" if any of your arguments have a \"-\" in them.\n\n",
Jim Inghama9deaf92011-08-16 23:57:58 +0000361 indent_level, "",
362 indent_level, "",
363 name,
364 indent_level, "");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000365}
366
367void
Greg Claytone0d378b2011-03-24 21:19:54 +0000368BuildGetOptTable (OptionDefinition *expanded_option_table, std::vector<struct option> &getopt_table,
Caroline Tice4ab31c92010-10-12 21:57:09 +0000369 uint32_t num_options)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000370{
371 if (num_options == 0)
372 return;
373
374 uint32_t i;
375 uint32_t j;
376 std::bitset<256> option_seen;
377
Caroline Tice4ab31c92010-10-12 21:57:09 +0000378 getopt_table.resize (num_options + 1);
379
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000380 for (i = 0, j = 0; i < num_options; ++i)
Greg Claytonc982c762010-07-09 20:39:50 +0000381 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000382 char short_opt = expanded_option_table[i].short_option;
Greg Claytonc982c762010-07-09 20:39:50 +0000383
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000384 if (option_seen.test(short_opt) == false)
Greg Claytonc982c762010-07-09 20:39:50 +0000385 {
Caroline Tice4ab31c92010-10-12 21:57:09 +0000386 getopt_table[j].name = expanded_option_table[i].long_option;
387 getopt_table[j].has_arg = expanded_option_table[i].option_has_arg;
388 getopt_table[j].flag = NULL;
389 getopt_table[j].val = expanded_option_table[i].short_option;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000390 option_seen.set(short_opt);
391 ++j;
Greg Claytonc982c762010-07-09 20:39:50 +0000392 }
393 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000394
Caroline Tice4ab31c92010-10-12 21:57:09 +0000395 getopt_table[j].name = NULL;
396 getopt_table[j].has_arg = 0;
397 getopt_table[j].flag = NULL;
398 getopt_table[j].val = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000399
400}
401
Greg Clayton66111032010-06-23 01:19:29 +0000402Driver::OptionData::OptionData () :
Greg Clayton8d846da2010-12-08 22:23:24 +0000403 m_args(),
Greg Clayton66111032010-06-23 01:19:29 +0000404 m_script_lang (lldb::eScriptLanguageDefault),
Johnny Cheneb46f782012-08-15 22:10:42 +0000405 m_core_file (),
Greg Claytonc982c762010-07-09 20:39:50 +0000406 m_crash_log (),
Jim Inghamed3252f2013-09-14 00:20:24 +0000407 m_initial_commands (),
408 m_after_file_commands (),
Jim Ingham4add3b12014-11-19 01:28:13 +0000409 m_after_crash_commands(),
Greg Clayton66111032010-06-23 01:19:29 +0000410 m_debug_mode (false),
Jim Inghamed3252f2013-09-14 00:20:24 +0000411 m_source_quietly(false),
Greg Claytonc982c762010-07-09 20:39:50 +0000412 m_print_version (false),
Jim Inghame2231ac2012-12-21 22:22:26 +0000413 m_print_python_path (false),
Greg Clayton66111032010-06-23 01:19:29 +0000414 m_print_help (false),
Jim Inghame64f0dc2011-09-13 23:25:31 +0000415 m_wait_for(false),
Sean Callanan3e7e9152015-10-20 00:23:46 +0000416 m_repl (false),
417 m_repl_lang (eLanguageTypeUnknown),
418 m_repl_options (),
Jim Inghame64f0dc2011-09-13 23:25:31 +0000419 m_process_name(),
420 m_process_pid(LLDB_INVALID_PROCESS_ID),
Daniel Dunbara08823f2011-10-31 22:50:49 +0000421 m_use_external_editor(false),
Jim Inghamffc9f1d2014-10-14 01:20:07 +0000422 m_batch(false),
Stephen Wilson71c21d12011-04-11 19:41:40 +0000423 m_seen_options()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000424{
Greg Clayton66111032010-06-23 01:19:29 +0000425}
426
427Driver::OptionData::~OptionData ()
428{
429}
430
431void
432Driver::OptionData::Clear ()
433{
Greg Clayton8d846da2010-12-08 22:23:24 +0000434 m_args.clear ();
Greg Clayton66111032010-06-23 01:19:29 +0000435 m_script_lang = lldb::eScriptLanguageDefault;
Jim Inghamed3252f2013-09-14 00:20:24 +0000436 m_initial_commands.clear ();
437 m_after_file_commands.clear ();
Jim Ingham4add3b12014-11-19 01:28:13 +0000438 // If there is a local .lldbinit, source that:
439 SBFileSpec local_lldbinit("./.lldbinit", true);
440 if (local_lldbinit.Exists())
441 {
442 char path[2048];
443 local_lldbinit.GetPath(path, 2047);
Jim Ingham0f17c552014-11-22 01:33:22 +0000444 InitialCmdEntry entry(path, true, true);
445 m_after_file_commands.push_back (entry);
Jim Ingham4add3b12014-11-19 01:28:13 +0000446 }
447
Greg Clayton66111032010-06-23 01:19:29 +0000448 m_debug_mode = false;
Jim Inghamed3252f2013-09-14 00:20:24 +0000449 m_source_quietly = false;
Greg Clayton66111032010-06-23 01:19:29 +0000450 m_print_help = false;
451 m_print_version = false;
Jim Inghame2231ac2012-12-21 22:22:26 +0000452 m_print_python_path = false;
Jim Inghame40e4212010-08-30 19:44:40 +0000453 m_use_external_editor = false;
Jim Inghame64f0dc2011-09-13 23:25:31 +0000454 m_wait_for = false;
455 m_process_name.erase();
Jim Inghamffc9f1d2014-10-14 01:20:07 +0000456 m_batch = false;
Jim Ingham4add3b12014-11-19 01:28:13 +0000457 m_after_crash_commands.clear();
458
Jim Inghame64f0dc2011-09-13 23:25:31 +0000459 m_process_pid = LLDB_INVALID_PROCESS_ID;
Greg Clayton66111032010-06-23 01:19:29 +0000460}
461
462void
Jim Ingham22302e52015-07-08 00:59:59 +0000463Driver::OptionData::AddInitialCommand (const char *command, CommandPlacement placement, bool is_file, SBError &error)
Jim Inghamed3252f2013-09-14 00:20:24 +0000464{
Jim Ingham0f17c552014-11-22 01:33:22 +0000465 std::vector<InitialCmdEntry> *command_set;
Jim Ingham4add3b12014-11-19 01:28:13 +0000466 switch (placement)
467 {
468 case eCommandPlacementBeforeFile:
Jim Inghamed3252f2013-09-14 00:20:24 +0000469 command_set = &(m_initial_commands);
Jim Ingham4add3b12014-11-19 01:28:13 +0000470 break;
471 case eCommandPlacementAfterFile:
Jim Inghamed3252f2013-09-14 00:20:24 +0000472 command_set = &(m_after_file_commands);
Jim Ingham4add3b12014-11-19 01:28:13 +0000473 break;
474 case eCommandPlacementAfterCrash:
475 command_set = &(m_after_crash_commands);
476 break;
477 }
Jim Inghamed3252f2013-09-14 00:20:24 +0000478
479 if (is_file)
480 {
481 SBFileSpec file(command);
482 if (file.Exists())
Jim Ingham22302e52015-07-08 00:59:59 +0000483 command_set->push_back (InitialCmdEntry(command, is_file));
Jim Inghamed3252f2013-09-14 00:20:24 +0000484 else if (file.ResolveExecutableLocation())
485 {
486 char final_path[PATH_MAX];
487 file.GetPath (final_path, sizeof(final_path));
Jim Ingham22302e52015-07-08 00:59:59 +0000488 command_set->push_back (InitialCmdEntry(final_path, is_file));
Jim Inghamed3252f2013-09-14 00:20:24 +0000489 }
490 else
491 error.SetErrorStringWithFormat("file specified in --source (-s) option doesn't exist: '%s'", optarg);
492 }
493 else
Jim Ingham22302e52015-07-08 00:59:59 +0000494 command_set->push_back (InitialCmdEntry(command, is_file));
Jim Inghamed3252f2013-09-14 00:20:24 +0000495}
496
497void
Greg Clayton66111032010-06-23 01:19:29 +0000498Driver::ResetOptionValues ()
499{
500 m_option_data.Clear ();
501}
502
503const char *
504Driver::GetFilename() const
505{
Greg Clayton8d846da2010-12-08 22:23:24 +0000506 if (m_option_data.m_args.empty())
Greg Clayton66111032010-06-23 01:19:29 +0000507 return NULL;
Greg Clayton8d846da2010-12-08 22:23:24 +0000508 return m_option_data.m_args.front().c_str();
Greg Clayton66111032010-06-23 01:19:29 +0000509}
510
511const char *
512Driver::GetCrashLogFilename() const
513{
514 if (m_option_data.m_crash_log.empty())
515 return NULL;
516 return m_option_data.m_crash_log.c_str();
517}
518
519lldb::ScriptLanguage
520Driver::GetScriptLanguage() const
521{
522 return m_option_data.m_script_lang;
523}
524
Jim Inghamed3252f2013-09-14 00:20:24 +0000525void
Jim Ingham4add3b12014-11-19 01:28:13 +0000526Driver::WriteCommandsForSourcing (CommandPlacement placement, SBStream &strm)
Greg Clayton66111032010-06-23 01:19:29 +0000527{
Jim Ingham0f17c552014-11-22 01:33:22 +0000528 std::vector<OptionData::InitialCmdEntry> *command_set;
Jim Ingham4add3b12014-11-19 01:28:13 +0000529 switch (placement)
530 {
531 case eCommandPlacementBeforeFile:
532 command_set = &m_option_data.m_initial_commands;
533 break;
534 case eCommandPlacementAfterFile:
535 command_set = &m_option_data.m_after_file_commands;
536 break;
537 case eCommandPlacementAfterCrash:
538 command_set = &m_option_data.m_after_crash_commands;
539 break;
540 }
Jim Inghamed3252f2013-09-14 00:20:24 +0000541
Jim Ingham0f17c552014-11-22 01:33:22 +0000542 for (const auto &command_entry : *command_set)
Jim Inghamed3252f2013-09-14 00:20:24 +0000543 {
Jim Ingham0f17c552014-11-22 01:33:22 +0000544 const char *command = command_entry.contents.c_str();
545 if (command_entry.is_file)
546 {
547 bool source_quietly = m_option_data.m_source_quietly || command_entry.source_quietly;
548 strm.Printf("command source -s %i '%s'\n", source_quietly, command);
549 }
Greg Clayton06357c92014-07-30 17:38:47 +0000550 else
551 strm.Printf("%s\n", command);
Jim Inghamed3252f2013-09-14 00:20:24 +0000552 }
Greg Clayton66111032010-06-23 01:19:29 +0000553}
554
555bool
556Driver::GetDebugMode() const
557{
558 return m_option_data.m_debug_mode;
559}
560
561
562// Check the arguments that were passed to this program to make sure they are valid and to get their
563// argument values (if any). Return a boolean value indicating whether or not to start up the full
564// debugger (i.e. the Command Interpreter) or not. Return FALSE if the arguments were invalid OR
565// if the user only wanted help or version information.
566
567SBError
Deepak Panickal429222c2013-10-15 15:46:40 +0000568Driver::ParseArgs (int argc, const char *argv[], FILE *out_fh, bool &exiting)
Greg Clayton66111032010-06-23 01:19:29 +0000569{
570 ResetOptionValues ();
571
572 SBCommandReturnObject result;
573
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000574 SBError error;
575 std::string option_string;
576 struct option *long_options = NULL;
Caroline Tice4ab31c92010-10-12 21:57:09 +0000577 std::vector<struct option> long_options_vector;
Greg Claytonc982c762010-07-09 20:39:50 +0000578 uint32_t num_options;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000579
Greg Claytonc982c762010-07-09 20:39:50 +0000580 for (num_options = 0; g_options[num_options].long_option != NULL; ++num_options)
581 /* Do Nothing. */;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000582
583 if (num_options == 0)
584 {
585 if (argc > 1)
586 error.SetErrorStringWithFormat ("invalid number of options");
587 return error;
588 }
589
Caroline Tice4ab31c92010-10-12 21:57:09 +0000590 BuildGetOptTable (g_options, long_options_vector, num_options);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000591
Caroline Tice4ab31c92010-10-12 21:57:09 +0000592 if (long_options_vector.empty())
593 long_options = NULL;
594 else
595 long_options = &long_options_vector.front();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000596
597 if (long_options == NULL)
598 {
599 error.SetErrorStringWithFormat ("invalid long options");
600 return error;
601 }
602
Greg Claytonb7ad58a2013-04-04 20:35:24 +0000603 // Build the option_string argument for call to getopt_long_only.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000604
605 for (int i = 0; long_options[i].name != NULL; ++i)
606 {
607 if (long_options[i].flag == NULL)
608 {
609 option_string.push_back ((char) long_options[i].val);
610 switch (long_options[i].has_arg)
611 {
612 default:
613 case no_argument:
614 break;
615 case required_argument:
616 option_string.push_back (':');
617 break;
618 case optional_argument:
619 option_string.append ("::");
620 break;
621 }
622 }
623 }
624
Jim Ingham06942692011-08-13 00:22:20 +0000625 // This is kind of a pain, but since we make the debugger in the Driver's constructor, we can't
626 // know at that point whether we should read in init files yet. So we don't read them in in the
627 // Driver constructor, then set the flags back to "read them in" here, and then if we see the
628 // "-n" flag, we'll turn it off again. Finally we have to read them in by hand later in the
629 // main loop.
630
631 m_debugger.SkipLLDBInitFiles (false);
632 m_debugger.SkipAppInitFiles (false);
633
Greg Claytonb7ad58a2013-04-04 20:35:24 +0000634 // Prepare for & make calls to getopt_long_only.
Eli Friedmanadb35022010-06-13 19:18:49 +0000635#if __GLIBC__
636 optind = 0;
637#else
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000638 optreset = 1;
639 optind = 1;
Eli Friedmanadb35022010-06-13 19:18:49 +0000640#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000641 int val;
642 while (1)
643 {
644 int long_options_index = -1;
Greg Claytonb7ad58a2013-04-04 20:35:24 +0000645 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 +0000646
647 if (val == -1)
648 break;
649 else if (val == '?')
650 {
Greg Clayton66111032010-06-23 01:19:29 +0000651 m_option_data.m_print_help = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000652 error.SetErrorStringWithFormat ("unknown or ambiguous option");
653 break;
654 }
655 else if (val == 0)
656 continue;
657 else
658 {
Greg Clayton66111032010-06-23 01:19:29 +0000659 m_option_data.m_seen_options.insert ((char) val);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000660 if (long_options_index == -1)
661 {
662 for (int i = 0;
663 long_options[i].name || long_options[i].has_arg || long_options[i].flag || long_options[i].val;
664 ++i)
665 {
666 if (long_options[i].val == val)
667 {
668 long_options_index = i;
669 break;
670 }
671 }
672 }
673
674 if (long_options_index >= 0)
675 {
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000676 const int short_option = g_options[long_options_index].short_option;
Greg Clayton66111032010-06-23 01:19:29 +0000677
678 switch (short_option)
679 {
680 case 'h':
681 m_option_data.m_print_help = true;
682 break;
683
684 case 'v':
685 m_option_data.m_print_version = true;
686 break;
687
Jim Inghame2231ac2012-12-21 22:22:26 +0000688 case 'P':
689 m_option_data.m_print_python_path = true;
690 break;
691
Jim Inghamffc9f1d2014-10-14 01:20:07 +0000692 case 'b':
693 m_option_data.m_batch = true;
694 break;
695
Greg Clayton66111032010-06-23 01:19:29 +0000696 case 'c':
Johnny Cheneb46f782012-08-15 22:10:42 +0000697 {
698 SBFileSpec file(optarg);
699 if (file.Exists())
700 {
701 m_option_data.m_core_file = optarg;
702 }
703 else
704 error.SetErrorStringWithFormat("file specified in --core (-c) option doesn't exist: '%s'", optarg);
705 }
Greg Clayton66111032010-06-23 01:19:29 +0000706 break;
Johnny Cheneb46f782012-08-15 22:10:42 +0000707
Jim Inghame40e4212010-08-30 19:44:40 +0000708 case 'e':
709 m_option_data.m_use_external_editor = true;
710 break;
Greg Clayton6eee5aa2010-10-11 01:05:37 +0000711
Jim Inghame64f0dc2011-09-13 23:25:31 +0000712 case 'x':
Greg Clayton6eee5aa2010-10-11 01:05:37 +0000713 m_debugger.SkipLLDBInitFiles (true);
Jim Ingham06942692011-08-13 00:22:20 +0000714 m_debugger.SkipAppInitFiles (true);
Greg Clayton6eee5aa2010-10-11 01:05:37 +0000715 break;
716
Jim Inghamed3252f2013-09-14 00:20:24 +0000717 case 'X':
Michael Sartainc3ce7f272013-05-23 20:47:45 +0000718 m_debugger.SetUseColor (false);
719 break;
720
Greg Clayton66111032010-06-23 01:19:29 +0000721 case 'f':
722 {
723 SBFileSpec file(optarg);
724 if (file.Exists())
Greg Clayton8d846da2010-12-08 22:23:24 +0000725 {
726 m_option_data.m_args.push_back (optarg);
727 }
Caroline Tice428a9a52010-09-10 04:48:55 +0000728 else if (file.ResolveExecutableLocation())
729 {
730 char path[PATH_MAX];
Johnny Chen25f3a3c2011-08-10 22:06:24 +0000731 file.GetPath (path, sizeof(path));
Greg Clayton8d846da2010-12-08 22:23:24 +0000732 m_option_data.m_args.push_back (path);
Caroline Tice428a9a52010-09-10 04:48:55 +0000733 }
Greg Clayton66111032010-06-23 01:19:29 +0000734 else
735 error.SetErrorStringWithFormat("file specified in --file (-f) option doesn't exist: '%s'", optarg);
736 }
737 break;
738
739 case 'a':
740 if (!m_debugger.SetDefaultArchitecture (optarg))
741 error.SetErrorStringWithFormat("invalid architecture in the -a or --arch option: '%s'", optarg);
742 break;
743
744 case 'l':
745 m_option_data.m_script_lang = m_debugger.GetScriptingLanguage (optarg);
746 break;
747
748 case 'd':
749 m_option_data.m_debug_mode = true;
750 break;
751
Jim Inghamf0c63b92014-02-05 21:35:09 +0000752 case 'Q':
Jim Inghamed3252f2013-09-14 00:20:24 +0000753 m_option_data.m_source_quietly = true;
754 break;
755
Jim Ingham661f29d2014-11-20 23:37:13 +0000756 case 'K':
Jim Ingham22302e52015-07-08 00:59:59 +0000757 m_option_data.AddInitialCommand(optarg, eCommandPlacementAfterCrash, true, error);
Jim Ingham4add3b12014-11-19 01:28:13 +0000758 break;
Jim Ingham661f29d2014-11-20 23:37:13 +0000759 case 'k':
Jim Ingham22302e52015-07-08 00:59:59 +0000760 m_option_data.AddInitialCommand(optarg, eCommandPlacementAfterCrash, false, error);
Jim Ingham4add3b12014-11-19 01:28:13 +0000761 break;
762
Jim Inghame64f0dc2011-09-13 23:25:31 +0000763 case 'n':
764 m_option_data.m_process_name = optarg;
765 break;
766
767 case 'w':
768 m_option_data.m_wait_for = true;
769 break;
770
771 case 'p':
772 {
773 char *remainder;
774 m_option_data.m_process_pid = strtol (optarg, &remainder, 0);
775 if (remainder == optarg || *remainder != '\0')
776 error.SetErrorStringWithFormat ("Could not convert process PID: \"%s\" into a pid.",
777 optarg);
778 }
779 break;
Sean Callanan3e7e9152015-10-20 00:23:46 +0000780
781 case 'r':
782 m_option_data.m_repl = true;
783 if (optarg && optarg[0])
784 m_option_data.m_repl_options = optarg;
785 else
786 m_option_data.m_repl_options.clear();
787 break;
788
789 case 'R':
790 m_option_data.m_repl_lang = SBLanguageRuntime::GetLanguageTypeFromString (optarg);
791 if (m_option_data.m_repl_lang == eLanguageTypeUnknown)
792 {
793 error.SetErrorStringWithFormat ("Unrecognized language name: \"%s\"", optarg);
794 }
795 break;
796
Greg Clayton66111032010-06-23 01:19:29 +0000797 case 's':
Jim Ingham22302e52015-07-08 00:59:59 +0000798 m_option_data.AddInitialCommand(optarg, eCommandPlacementAfterFile, true, error);
Greg Clayton66111032010-06-23 01:19:29 +0000799 break;
Jim Inghamed3252f2013-09-14 00:20:24 +0000800 case 'o':
Jim Ingham22302e52015-07-08 00:59:59 +0000801 m_option_data.AddInitialCommand(optarg, eCommandPlacementAfterFile, false, error);
Jim Inghamed3252f2013-09-14 00:20:24 +0000802 break;
803 case 'S':
Jim Ingham22302e52015-07-08 00:59:59 +0000804 m_option_data.AddInitialCommand(optarg, eCommandPlacementBeforeFile, true, error);
Jim Inghamed3252f2013-09-14 00:20:24 +0000805 break;
806 case 'O':
Jim Ingham22302e52015-07-08 00:59:59 +0000807 m_option_data.AddInitialCommand(optarg, eCommandPlacementBeforeFile, false, error);
Jim Inghamed3252f2013-09-14 00:20:24 +0000808 break;
Greg Clayton66111032010-06-23 01:19:29 +0000809 default:
810 m_option_data.m_print_help = true;
811 error.SetErrorStringWithFormat ("unrecognized option %c", short_option);
812 break;
813 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000814 }
815 else
816 {
817 error.SetErrorStringWithFormat ("invalid option with value %i", val);
818 }
819 if (error.Fail())
Caroline Tice4ab31c92010-10-12 21:57:09 +0000820 {
Greg Clayton66111032010-06-23 01:19:29 +0000821 return error;
Caroline Tice4ab31c92010-10-12 21:57:09 +0000822 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000823 }
824 }
Jim Ingham86511212010-06-15 18:47:14 +0000825
Greg Clayton66111032010-06-23 01:19:29 +0000826 if (error.Fail() || m_option_data.m_print_help)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000827 {
828 ShowUsage (out_fh, g_options, m_option_data);
Deepak Panickal429222c2013-10-15 15:46:40 +0000829 exiting = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000830 }
831 else if (m_option_data.m_print_version)
832 {
Greg Clayton66111032010-06-23 01:19:29 +0000833 ::fprintf (out_fh, "%s\n", m_debugger.GetVersionString());
Deepak Panickal429222c2013-10-15 15:46:40 +0000834 exiting = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000835 }
Jim Inghame2231ac2012-12-21 22:22:26 +0000836 else if (m_option_data.m_print_python_path)
837 {
838 SBFileSpec python_file_spec = SBHostOS::GetLLDBPythonPath();
839 if (python_file_spec.IsValid())
840 {
841 char python_path[PATH_MAX];
842 size_t num_chars = python_file_spec.GetPath(python_path, PATH_MAX);
843 if (num_chars < PATH_MAX)
844 {
845 ::fprintf (out_fh, "%s\n", python_path);
846 }
847 else
848 ::fprintf (out_fh, "<PATH TOO LONG>\n");
849 }
850 else
851 ::fprintf (out_fh, "<COULD NOT FIND PATH>\n");
Deepak Panickal429222c2013-10-15 15:46:40 +0000852 exiting = true;
Jim Inghame2231ac2012-12-21 22:22:26 +0000853 }
Jim Inghame64f0dc2011-09-13 23:25:31 +0000854 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 +0000855 {
Greg Clayton8d846da2010-12-08 22:23:24 +0000856 // Any arguments that are left over after option parsing are for
857 // the program. If a file was specified with -f then the filename
858 // is already in the m_option_data.m_args array, and any remaining args
859 // are arguments for the inferior program. If no file was specified with
860 // -f, then what is left is the program name followed by any arguments.
861
Greg Claytonb7ad58a2013-04-04 20:35:24 +0000862 // Skip any options we consumed with getopt_long_only
Greg Clayton8d846da2010-12-08 22:23:24 +0000863 argc -= optind;
864 argv += optind;
865
866 if (argc > 0)
867 {
868 for (int arg_idx=0; arg_idx<argc; ++arg_idx)
869 {
870 const char *arg = argv[arg_idx];
871 if (arg)
872 m_option_data.m_args.push_back (arg);
873 }
874 }
875
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000876 }
Jim Inghame64f0dc2011-09-13 23:25:31 +0000877 else
878 {
Greg Claytonb7ad58a2013-04-04 20:35:24 +0000879 // Skip any options we consumed with getopt_long_only
Jim Inghame64f0dc2011-09-13 23:25:31 +0000880 argc -= optind;
Greg Clayton23f59502012-07-17 03:23:13 +0000881 //argv += optind; // Commented out to keep static analyzer happy
Jim Inghame64f0dc2011-09-13 23:25:31 +0000882
883 if (argc > 0)
884 ::fprintf (out_fh, "Warning: program arguments are ignored when attaching.\n");
885 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000886
Greg Clayton66111032010-06-23 01:19:29 +0000887 return error;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000888}
889
Jim Ingham4add3b12014-11-19 01:28:13 +0000890static ::FILE *
891PrepareCommandsForSourcing (const char *commands_data, size_t commands_size, int fds[2])
892{
893 enum PIPES { READ, WRITE }; // Constants 0 and 1 for READ and WRITE
894
Jim Ingham4add3b12014-11-19 01:28:13 +0000895 ::FILE *commands_file = NULL;
896 fds[0] = -1;
897 fds[1] = -1;
898 int err = 0;
899#ifdef _WIN32
900 err = _pipe(fds, commands_size, O_BINARY);
901#else
902 err = pipe(fds);
903#endif
904 if (err == 0)
905 {
906 ssize_t nrwr = write(fds[WRITE], commands_data, commands_size);
907 if (nrwr < 0)
908 {
Adrian McCarthye704c4f2015-03-30 17:46:36 +0000909 fprintf(stderr, "error: write(%i, %p, %" PRIu64 ") failed (errno = %i) "
Jim Ingham4add3b12014-11-19 01:28:13 +0000910 "when trying to open LLDB commands pipe\n",
Adrian McCarthye704c4f2015-03-30 17:46:36 +0000911 fds[WRITE], commands_data, static_cast<uint64_t>(commands_size), errno);
Jim Ingham4add3b12014-11-19 01:28:13 +0000912 }
913 else if (static_cast<size_t>(nrwr) == commands_size)
914 {
915 // Close the write end of the pipe so when we give the read end to
916 // the debugger/command interpreter it will exit when it consumes all
917 // of the data
918#ifdef _WIN32
919 _close(fds[WRITE]); fds[WRITE] = -1;
920#else
921 close(fds[WRITE]); fds[WRITE] = -1;
922#endif
923 // Now open the read file descriptor in a FILE * that we can give to
924 // the debugger as an input handle
925 commands_file = fdopen(fds[READ], "r");
926 if (commands_file)
927 {
928 fds[READ] = -1; // The FILE * 'commands_file' now owns the read descriptor
929 // Hand ownership if the FILE * over to the debugger for "commands_file".
930 }
931 else
932 {
933 fprintf(stderr,
934 "error: fdopen(%i, \"r\") failed (errno = %i) when "
935 "trying to open LLDB commands pipe\n",
936 fds[READ], errno);
Jim Ingham4add3b12014-11-19 01:28:13 +0000937 }
938 }
939 }
940 else
941 {
942 fprintf(stderr, "error: can't create pipe file descriptors for LLDB commands\n");
Jim Ingham4add3b12014-11-19 01:28:13 +0000943 }
944
945 return commands_file;
946}
947
948void
949CleanupAfterCommandSourcing (int fds[2])
950{
951 enum PIPES { READ, WRITE }; // Constants 0 and 1 for READ and WRITE
952
953 // Close any pipes that we still have ownership of
954 if ( fds[WRITE] != -1)
955 {
956#ifdef _WIN32
957 _close(fds[WRITE]); fds[WRITE] = -1;
958#else
959 close(fds[WRITE]); fds[WRITE] = -1;
960#endif
961
962 }
963
964 if ( fds[READ] != -1)
965 {
966#ifdef _WIN32
967 _close(fds[READ]); fds[READ] = -1;
968#else
969 close(fds[READ]); fds[READ] = -1;
970#endif
971 }
972
973}
974
Pavel Labathaa1ae6f2015-03-05 19:17:56 +0000975std::string
976EscapeString (std::string arg)
977{
978 std::string::size_type pos = 0;
979 while ((pos = arg.find_first_of("\"\\", pos)) != std::string::npos)
980 {
981 arg.insert (pos, 1, '\\');
982 pos += 2;
983 }
984 return '"' + arg + '"';
985}
986
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000987void
988Driver::MainLoop ()
989{
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000990 if (::tcgetattr(STDIN_FILENO, &g_old_stdin_termios) == 0)
Greg Claytonf571b892012-02-02 19:28:31 +0000991 {
992 g_old_stdin_termios_is_valid = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000993 atexit (reset_stdin_termios);
Greg Claytonf571b892012-02-02 19:28:31 +0000994 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000995
996 ::setbuf (stdin, NULL);
997 ::setbuf (stdout, NULL);
998
Greg Clayton66111032010-06-23 01:19:29 +0000999 m_debugger.SetErrorFileHandle (stderr, false);
1000 m_debugger.SetOutputFileHandle (stdout, false);
Greg Clayton06357c92014-07-30 17:38:47 +00001001 m_debugger.SetInputFileHandle (stdin, false); // Don't take ownership of STDIN yet...
1002
Jim Inghame40e4212010-08-30 19:44:40 +00001003 m_debugger.SetUseExternalEditor(m_option_data.m_use_external_editor);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001004
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001005 struct winsize window_size;
1006 if (isatty (STDIN_FILENO)
1007 && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0)
1008 {
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001009 if (window_size.ws_col > 0)
Greg Claytona7015092010-09-18 01:14:36 +00001010 m_debugger.SetTerminalWidth (window_size.ws_col);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001011 }
1012
Greg Clayton44d93782014-01-27 23:43:24 +00001013 SBCommandInterpreter sb_interpreter = m_debugger.GetCommandInterpreter();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001014
Greg Clayton44d93782014-01-27 23:43:24 +00001015 // Before we handle any options from the command line, we parse the
1016 // .lldbinit file in the user's home directory.
1017 SBCommandReturnObject result;
1018 sb_interpreter.SourceInitFileInHomeDirectory(result);
1019 if (GetDebugMode())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001020 {
Greg Clayton44d93782014-01-27 23:43:24 +00001021 result.PutError (m_debugger.GetErrorFileHandle());
1022 result.PutOutput (m_debugger.GetOutputFileHandle());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001023 }
Greg Clayton44d93782014-01-27 23:43:24 +00001024
1025 // Now we handle options we got from the command line
Ed Mastef8314532014-07-30 19:26:11 +00001026 SBStream commands_stream;
Greg Clayton06357c92014-07-30 17:38:47 +00001027
Greg Clayton44d93782014-01-27 23:43:24 +00001028 // First source in the commands specified to be run before the file arguments are processed.
Jim Ingham4add3b12014-11-19 01:28:13 +00001029 WriteCommandsForSourcing(eCommandPlacementBeforeFile, commands_stream);
Greg Clayton06357c92014-07-30 17:38:47 +00001030
Greg Clayton44d93782014-01-27 23:43:24 +00001031 const size_t num_args = m_option_data.m_args.size();
1032 if (num_args > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001033 {
Jim Ingham5b1fe952014-08-07 23:01:31 +00001034 char arch_name[64];
1035 if (m_debugger.GetDefaultArchitecture (arch_name, sizeof (arch_name)))
Pavel Labathaa1ae6f2015-03-05 19:17:56 +00001036 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 +00001037 else
Pavel Labathaa1ae6f2015-03-05 19:17:56 +00001038 commands_stream.Printf("target create %s", EscapeString(m_option_data.m_args[0]).c_str());
Jim Ingham5b1fe952014-08-07 23:01:31 +00001039
Greg Clayton06357c92014-07-30 17:38:47 +00001040 if (!m_option_data.m_core_file.empty())
1041 {
Pavel Labathaa1ae6f2015-03-05 19:17:56 +00001042 commands_stream.Printf(" --core %s", EscapeString(m_option_data.m_core_file).c_str());
Greg Clayton06357c92014-07-30 17:38:47 +00001043 }
1044 commands_stream.Printf("\n");
Greg Clayton44d93782014-01-27 23:43:24 +00001045
1046 if (num_args > 1)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001047 {
Greg Clayton06357c92014-07-30 17:38:47 +00001048 commands_stream.Printf ("settings set -- target.run-args ");
Greg Clayton44d93782014-01-27 23:43:24 +00001049 for (size_t arg_idx = 1; arg_idx < num_args; ++arg_idx)
Pavel Labathaa1ae6f2015-03-05 19:17:56 +00001050 commands_stream.Printf(" %s", EscapeString(m_option_data.m_args[arg_idx]).c_str());
Greg Clayton06357c92014-07-30 17:38:47 +00001051 commands_stream.Printf("\n");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001052 }
1053 }
Greg Clayton06357c92014-07-30 17:38:47 +00001054 else if (!m_option_data.m_core_file.empty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001055 {
Pavel Labathaa1ae6f2015-03-05 19:17:56 +00001056 commands_stream.Printf("target create --core %s\n", EscapeString(m_option_data.m_core_file).c_str());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001057 }
Greg Clayton9c0b64c2014-02-06 18:22:44 +00001058 else if (!m_option_data.m_process_name.empty())
1059 {
Pavel Labathaa1ae6f2015-03-05 19:17:56 +00001060 commands_stream.Printf ("process attach --name %s", EscapeString(m_option_data.m_process_name).c_str());
Greg Clayton06357c92014-07-30 17:38:47 +00001061
1062 if (m_option_data.m_wait_for)
1063 commands_stream.Printf(" --waitfor");
1064
1065 commands_stream.Printf("\n");
1066
Greg Clayton9c0b64c2014-02-06 18:22:44 +00001067 }
1068 else if (LLDB_INVALID_PROCESS_ID != m_option_data.m_process_pid)
1069 {
Greg Clayton06357c92014-07-30 17:38:47 +00001070 commands_stream.Printf ("process attach --pid %" PRIu64 "\n", m_option_data.m_process_pid);
Greg Clayton9c0b64c2014-02-06 18:22:44 +00001071 }
Greg Clayton44d93782014-01-27 23:43:24 +00001072
Jim Ingham4add3b12014-11-19 01:28:13 +00001073 WriteCommandsForSourcing(eCommandPlacementAfterFile, commands_stream);
Greg Clayton06357c92014-07-30 17:38:47 +00001074
Greg Clayton44d93782014-01-27 23:43:24 +00001075 if (GetDebugMode())
1076 {
1077 result.PutError(m_debugger.GetErrorFileHandle());
1078 result.PutOutput(m_debugger.GetOutputFileHandle());
1079 }
1080
1081 bool handle_events = true;
1082 bool spawn_thread = false;
Greg Clayton06357c92014-07-30 17:38:47 +00001083
Sean Callanan3e7e9152015-10-20 00:23:46 +00001084 if (m_option_data.m_repl)
Greg Clayton06357c92014-07-30 17:38:47 +00001085 {
Sean Callanan3e7e9152015-10-20 00:23:46 +00001086 const char *repl_options = NULL;
1087 if (!m_option_data.m_repl_options.empty())
1088 repl_options = m_option_data.m_repl_options.c_str();
1089 SBError error (m_debugger.RunREPL(m_option_data.m_repl_lang, repl_options));
1090 if (error.Fail())
Greg Clayton49668762014-08-01 18:32:07 +00001091 {
Sean Callanan3e7e9152015-10-20 00:23:46 +00001092 const char *error_cstr = error.GetCString();
1093 if (error_cstr && error_cstr[0])
1094 fprintf (stderr, "error: %s\n", error_cstr);
1095 else
1096 fprintf (stderr, "error: %u\n", error.GetError());
Greg Clayton06357c92014-07-30 17:38:47 +00001097 }
1098 }
Sean Callanan3e7e9152015-10-20 00:23:46 +00001099 else
Jim Ingham26c7bf92014-10-11 00:38:27 +00001100 {
Sean Callanan3e7e9152015-10-20 00:23:46 +00001101 // Check if we have any data in the commands stream, and if so, save it to a temp file
1102 // so we can then run the command interpreter using the file contents.
1103 const char *commands_data = commands_stream.GetData();
1104 const size_t commands_size = commands_stream.GetSize();
1105
1106 // The command file might have requested that we quit, this variable will track that.
1107 bool quit_requested = false;
1108 bool stopped_for_crash = false;
1109 if (commands_data && commands_size)
1110 {
1111 int initial_commands_fds[2];
1112 bool success = true;
1113 FILE *commands_file = PrepareCommandsForSourcing (commands_data, commands_size, initial_commands_fds);
1114 if (commands_file)
1115 {
1116 m_debugger.SetInputFileHandle (commands_file, true);
1117
1118 // Set the debugger into Sync mode when running the command file. Otherwise command files
1119 // that run the target won't run in a sensible way.
1120 bool old_async = m_debugger.GetAsync();
1121 m_debugger.SetAsync(false);
1122 int num_errors;
1123
1124 SBCommandInterpreterRunOptions options;
1125 options.SetStopOnError (true);
1126 if (m_option_data.m_batch)
1127 options.SetStopOnCrash (true);
1128
1129 m_debugger.RunCommandInterpreter(handle_events,
1130 spawn_thread,
1131 options,
1132 num_errors,
1133 quit_requested,
1134 stopped_for_crash);
1135
1136 if (m_option_data.m_batch && stopped_for_crash && !m_option_data.m_after_crash_commands.empty())
1137 {
1138 int crash_command_fds[2];
1139 SBStream crash_commands_stream;
1140 WriteCommandsForSourcing (eCommandPlacementAfterCrash, crash_commands_stream);
1141 const char *crash_commands_data = crash_commands_stream.GetData();
1142 const size_t crash_commands_size = crash_commands_stream.GetSize();
1143 commands_file = PrepareCommandsForSourcing (crash_commands_data, crash_commands_size, crash_command_fds);
1144 if (commands_file)
1145 {
1146 bool local_quit_requested;
1147 bool local_stopped_for_crash;
1148 m_debugger.SetInputFileHandle (commands_file, true);
1149
1150 m_debugger.RunCommandInterpreter(handle_events,
1151 spawn_thread,
1152 options,
1153 num_errors,
1154 local_quit_requested,
1155 local_stopped_for_crash);
1156 if (local_quit_requested)
1157 quit_requested = true;
1158
1159 }
1160 }
1161 m_debugger.SetAsync(old_async);
1162 }
1163 else
1164 success = false;
1165
1166 // Close any pipes that we still have ownership of
1167 CleanupAfterCommandSourcing(initial_commands_fds);
1168
1169 // Something went wrong with command pipe
1170 if (!success)
1171 {
1172 exit(1);
1173 }
1174
1175 }
1176
1177 // Now set the input file handle to STDIN and run the command
1178 // interpreter again in interactive mode and let the debugger
1179 // take ownership of stdin
1180
1181 bool go_interactive = true;
1182 if (quit_requested)
1183 go_interactive = false;
1184 else if (m_option_data.m_batch && !stopped_for_crash)
1185 go_interactive = false;
1186
1187 if (go_interactive)
1188 {
1189 m_debugger.SetInputFileHandle (stdin, true);
1190 m_debugger.RunCommandInterpreter(handle_events, spawn_thread);
1191 }
Jim Ingham26c7bf92014-10-11 00:38:27 +00001192 }
Greg Clayton44d93782014-01-27 23:43:24 +00001193
1194 reset_stdin_termios();
1195 fclose (stdin);
1196
1197 SBDebugger::Destroy (m_debugger);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001198}
1199
Greg Clayton44d93782014-01-27 23:43:24 +00001200
Jim Inghamc46fe7c2013-02-22 22:56:55 +00001201void
1202Driver::ResizeWindow (unsigned short col)
1203{
1204 GetDebugger().SetTerminalWidth (col);
Jim Inghamc46fe7c2013-02-22 22:56:55 +00001205}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001206
Caroline Ticedd759852010-09-09 17:45:09 +00001207void
1208sigwinch_handler (int signo)
1209{
1210 struct winsize window_size;
1211 if (isatty (STDIN_FILENO)
1212 && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0)
1213 {
Jim Ingham57190ba2012-04-26 21:39:32 +00001214 if ((window_size.ws_col > 0) && g_driver != NULL)
Caroline Ticedd759852010-09-09 17:45:09 +00001215 {
Jim Inghamc46fe7c2013-02-22 22:56:55 +00001216 g_driver->ResizeWindow (window_size.ws_col);
Caroline Ticedd759852010-09-09 17:45:09 +00001217 }
1218 }
1219}
1220
Caroline Ticeefed6132010-11-19 20:47:54 +00001221void
1222sigint_handler (int signo)
1223{
1224 static bool g_interrupt_sent = false;
1225 if (g_driver)
1226 {
1227 if (!g_interrupt_sent)
1228 {
1229 g_interrupt_sent = true;
1230 g_driver->GetDebugger().DispatchInputInterrupt();
1231 g_interrupt_sent = false;
1232 return;
1233 }
1234 }
1235
1236 exit (signo);
1237}
1238
Jim Inghamc5917d92012-11-30 20:23:19 +00001239void
1240sigtstp_handler (int signo)
1241{
1242 g_driver->GetDebugger().SaveInputTerminalState();
1243 signal (signo, SIG_DFL);
1244 kill (getpid(), signo);
1245 signal (signo, sigtstp_handler);
1246}
1247
1248void
1249sigcont_handler (int signo)
1250{
1251 g_driver->GetDebugger().RestoreInputTerminalState();
1252 signal (signo, SIG_DFL);
1253 kill (getpid(), signo);
1254 signal (signo, sigcont_handler);
1255}
1256
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001257int
Jim Inghama462f5c2011-01-27 20:15:39 +00001258main (int argc, char const *argv[], const char *envp[])
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001259{
Deepak Panickal99fbc072014-03-03 15:39:47 +00001260#ifdef _MSC_VER
1261 // disable buffering on windows
1262 setvbuf(stdout, NULL, _IONBF, 0);
1263 setvbuf(stdin , NULL, _IONBF, 0);
1264#endif
1265
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001266 SBDebugger::Initialize();
1267
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00001268 SBHostOS::ThreadCreated ("<lldb.driver.main-thread>");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001269
Greg Clayton3fcbed62010-10-19 03:25:40 +00001270 signal (SIGPIPE, SIG_IGN);
Caroline Ticedd759852010-09-09 17:45:09 +00001271 signal (SIGWINCH, sigwinch_handler);
Caroline Ticeefed6132010-11-19 20:47:54 +00001272 signal (SIGINT, sigint_handler);
Jim Inghamc5917d92012-11-30 20:23:19 +00001273 signal (SIGTSTP, sigtstp_handler);
1274 signal (SIGCONT, sigcont_handler);
Caroline Ticedd759852010-09-09 17:45:09 +00001275
Greg Clayton66111032010-06-23 01:19:29 +00001276 // Create a scope for driver so that the driver object will destroy itself
1277 // before SBDebugger::Terminate() is called.
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001278 {
Greg Clayton66111032010-06-23 01:19:29 +00001279 Driver driver;
1280
Deepak Panickal429222c2013-10-15 15:46:40 +00001281 bool exiting = false;
1282 SBError error (driver.ParseArgs (argc, argv, stdout, exiting));
Greg Clayton66111032010-06-23 01:19:29 +00001283 if (error.Fail())
1284 {
1285 const char *error_cstr = error.GetCString ();
1286 if (error_cstr)
1287 ::fprintf (stderr, "error: %s\n", error_cstr);
1288 }
Deepak Panickal429222c2013-10-15 15:46:40 +00001289 else if (!exiting)
Greg Clayton66111032010-06-23 01:19:29 +00001290 {
1291 driver.MainLoop ();
1292 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001293 }
1294
1295 SBDebugger::Terminate();
1296 return 0;
1297}