blob: 0273b20bab57a35a6d6afac94460062a773fcc6b [file] [log] [blame]
Chris Lattner24943d22010-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
12#include <getopt.h>
13#include <libgen.h>
14#include <sys/ioctl.h>
15#include <termios.h>
16#include <unistd.h>
Eli Friedmanf2f321d2010-06-09 09:50:17 +000017#include <string.h>
18#include <stdlib.h>
19#include <limits.h>
Eli Friedmand6e167d2010-06-09 19:11:30 +000020#include <fcntl.h>
Chris Lattner24943d22010-06-08 16:52:24 +000021
22#include <string>
23
24#include "IOChannel.h"
Eli Friedmanf2f321d2010-06-09 09:50:17 +000025#include "lldb/API/SBCommandInterpreter.h"
26#include "lldb/API/SBCommandReturnObject.h"
27#include "lldb/API/SBCommunication.h"
28#include "lldb/API/SBDebugger.h"
29#include "lldb/API/SBEvent.h"
30#include "lldb/API/SBHostOS.h"
31#include "lldb/API/SBListener.h"
32#include "lldb/API/SBSourceManager.h"
Jim Ingham2e8cb8a2011-02-19 02:53:09 +000033#include "lldb/API/SBStream.h"
Eli Friedmanf2f321d2010-06-09 09:50:17 +000034#include "lldb/API/SBTarget.h"
35#include "lldb/API/SBThread.h"
36#include "lldb/API/SBProcess.h"
Chris Lattner24943d22010-06-08 16:52:24 +000037
38using namespace lldb;
39
40static void reset_stdin_termios ();
41static struct termios g_old_stdin_termios;
42
Caroline Ticeb8314fe2010-09-09 17:45:09 +000043static char *g_debugger_name = (char *) "";
Caroline Ticec4f55fe2010-11-19 20:47:54 +000044static Driver *g_driver = NULL;
Caroline Ticeb8314fe2010-09-09 17:45:09 +000045
Chris Lattner24943d22010-06-08 16:52:24 +000046// In the Driver::MainLoop, we change the terminal settings. This function is
47// added as an atexit handler to make sure we clean them up.
48static void
49reset_stdin_termios ()
50{
51 ::tcsetattr (STDIN_FILENO, TCSANOW, &g_old_stdin_termios);
52}
53
Greg Claytonb3448432011-03-24 21:19:54 +000054typedef struct
Chris Lattner24943d22010-06-08 16:52:24 +000055{
Greg Claytonb3448432011-03-24 21:19:54 +000056 uint32_t usage_mask; // Used to mark options that can be used together. If (1 << n & usage_mask) != 0
57 // then this option belongs to option set n.
58 bool required; // This option is required (in the current usage level)
59 const char * long_option; // Full name for this option.
60 char short_option; // Single character for this option.
61 int option_has_arg; // no_argument, required_argument or optional_argument
Greg Clayton5e342f52011-04-13 22:47:15 +000062 uint32_t completion_type; // Cookie the option class can use to do define the argument completion.
Greg Claytonb3448432011-03-24 21:19:54 +000063 lldb::CommandArgumentType argument_type; // Type of argument this option takes
64 const char * usage_text; // Full text explaining what this options does and what (if any) argument to
65 // pass it.
66} OptionDefinition;
Chris Lattner24943d22010-06-08 16:52:24 +000067
Jim Ingham6ae25442011-08-16 23:15:02 +000068#define LLDB_2_TO_4 LLDB_OPT_SET_2|LLDB_OPT_SET_3|LLDB_OPT_SET_4
Greg Claytonb3448432011-03-24 21:19:54 +000069static OptionDefinition g_options[] =
70{
71 { LLDB_OPT_SET_1, true , "help" , 'h', no_argument , NULL, eArgTypeNone, "Prints out the usage information for the LLDB debugger." },
72 { LLDB_OPT_SET_2, true , "version" , 'v', no_argument , NULL, eArgTypeNone, "Prints out the current version number of the LLDB debugger." },
73 { LLDB_OPT_SET_3, true , "arch" , 'a', required_argument, NULL, eArgTypeArchitecture,"Tells the debugger to use the specified architecture when starting and running the program. <architecture> must be one of the architectures for which the program was compiled." },
74 { LLDB_OPT_SET_3 | LLDB_OPT_SET_4, false, "script-language", 'l', required_argument, NULL, eArgTypeScriptLang,"Tells the debugger to use the specified scripting language for user-defined scripts, rather than the default. Valid scripting languages that can be specified include Python, Perl, Ruby and Tcl. Currently only the Python extensions have been implemented." },
75 { LLDB_OPT_SET_3 | LLDB_OPT_SET_4, false, "debug" , 'd', no_argument , NULL, eArgTypeNone,"Tells the debugger to print out extra information for debugging itself." },
76 { LLDB_OPT_SET_3 | LLDB_OPT_SET_4, false, "source" , 's', required_argument, NULL, eArgTypeFilename, "Tells the debugger to read in and execute the file <file>, which should contain lldb commands." },
77 { LLDB_OPT_SET_3, true , "file" , 'f', required_argument, NULL, eArgTypeFilename, "Tells the debugger to use the file <filename> as the program to be debugged." },
Jim Ingham6ae25442011-08-16 23:15:02 +000078 { LLDB_2_TO_4, false, "editor" , 'e', no_argument , NULL, eArgTypeNone, "Tells the debugger to open source files using the host's \"external editor\" mechanism." },
79 { LLDB_2_TO_4, false, "no-lldbinit" , 'n', no_argument , NULL, eArgTypeNone, "Do not automatically parse any '.lldbinit' files." },
Greg Claytonb3448432011-03-24 21:19:54 +000080 { 0, false, NULL , 0 , 0 , NULL, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +000081};
82
83
84Driver::Driver () :
85 SBBroadcaster ("Driver"),
Jim Ingham558dd5b2011-08-13 00:22:20 +000086 m_debugger (SBDebugger::Create(false)),
Chris Lattner24943d22010-06-08 16:52:24 +000087 m_editline_pty (),
88 m_editline_slave_fh (NULL),
89 m_editline_reader (),
90 m_io_channel_ap (),
91 m_option_data (),
92 m_waiting_for_command (false)
93{
Greg Clayton421ca502011-05-29 04:06:55 +000094 // We want to be able to handle CTRL+D in the terminal to have it terminate
95 // certain input
96 m_debugger.SetCloseInputOnEOF (false);
Caroline Ticeb8314fe2010-09-09 17:45:09 +000097 g_debugger_name = (char *) m_debugger.GetInstanceName();
98 if (g_debugger_name == NULL)
99 g_debugger_name = (char *) "";
Caroline Ticec4f55fe2010-11-19 20:47:54 +0000100 g_driver = this;
Chris Lattner24943d22010-06-08 16:52:24 +0000101}
102
103Driver::~Driver ()
104{
Caroline Ticec4f55fe2010-11-19 20:47:54 +0000105 g_driver = NULL;
106 g_debugger_name = NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000107}
108
109void
110Driver::CloseIOChannelFile ()
111{
112 // Write and End of File sequence to the file descriptor to ensure any
113 // read functions can exit.
114 char eof_str[] = "\x04";
115 ::write (m_editline_pty.GetMasterFileDescriptor(), eof_str, strlen(eof_str));
116
117 m_editline_pty.CloseMasterFileDescriptor();
118
119 if (m_editline_slave_fh)
120 {
121 ::fclose (m_editline_slave_fh);
122 m_editline_slave_fh = NULL;
123 }
124}
125
Greg Clayton54e7afa2010-07-09 20:39:50 +0000126// This function takes INDENT, which tells how many spaces to output at the front
127// of each line; TEXT, which is the text that is to be output. It outputs the
128// text, on multiple lines if necessary, to RESULT, with INDENT spaces at the
129// front of each line. It breaks lines on spaces, tabs or newlines, shortening
130// the line if necessary to not break in the middle of a word. It assumes that
131// each output line should contain a maximum of OUTPUT_MAX_COLUMNS characters.
Chris Lattner24943d22010-06-08 16:52:24 +0000132
133void
Greg Clayton54e7afa2010-07-09 20:39:50 +0000134OutputFormattedUsageText (FILE *out, int indent, const char *text, int output_max_columns)
Chris Lattner24943d22010-06-08 16:52:24 +0000135{
136 int len = strlen (text);
137 std::string text_string (text);
Chris Lattner24943d22010-06-08 16:52:24 +0000138
139 // Force indentation to be reasonable.
140 if (indent >= output_max_columns)
141 indent = 0;
142
143 // Will it all fit on one line?
144
145 if (len + indent < output_max_columns)
146 // Output as a single line
Greg Clayton54e7afa2010-07-09 20:39:50 +0000147 fprintf (out, "%*s%s\n", indent, "", text);
Chris Lattner24943d22010-06-08 16:52:24 +0000148 else
149 {
150 // We need to break it up into multiple lines.
151 int text_width = output_max_columns - indent - 1;
152 int start = 0;
153 int end = start;
154 int final_end = len;
155 int sub_len;
156
157 while (end < final_end)
158 {
159 // Dont start the 'text' on a space, since we're already outputting the indentation.
160 while ((start < final_end) && (text[start] == ' '))
161 start++;
162
163 end = start + text_width;
164 if (end > final_end)
165 end = final_end;
166 else
167 {
168 // If we're not at the end of the text, make sure we break the line on white space.
169 while (end > start
170 && text[end] != ' ' && text[end] != '\t' && text[end] != '\n')
171 end--;
172 }
173 sub_len = end - start;
174 std::string substring = text_string.substr (start, sub_len);
Greg Clayton54e7afa2010-07-09 20:39:50 +0000175 fprintf (out, "%*s%s\n", indent, "", substring.c_str());
Chris Lattner24943d22010-06-08 16:52:24 +0000176 start = end + 1;
177 }
178 }
179}
180
181void
Greg Claytonb3448432011-03-24 21:19:54 +0000182ShowUsage (FILE *out, OptionDefinition *option_table, Driver::OptionData data)
Chris Lattner24943d22010-06-08 16:52:24 +0000183{
184 uint32_t screen_width = 80;
185 uint32_t indent_level = 0;
186 const char *name = "lldb";
Jim Ingham34e9a982010-06-15 18:47:14 +0000187
Chris Lattner24943d22010-06-08 16:52:24 +0000188 fprintf (out, "\nUsage:\n\n");
189
190 indent_level += 2;
191
192
193 // First, show each usage level set of options, e.g. <cmd> [options-for-level-0]
194 // <cmd> [options-for-level-1]
195 // etc.
196
Chris Lattner24943d22010-06-08 16:52:24 +0000197 uint32_t num_options;
Jim Ingham34e9a982010-06-15 18:47:14 +0000198 uint32_t num_option_sets = 0;
199
200 for (num_options = 0; option_table[num_options].long_option != NULL; ++num_options)
Chris Lattner24943d22010-06-08 16:52:24 +0000201 {
Jim Ingham34e9a982010-06-15 18:47:14 +0000202 uint32_t this_usage_mask = option_table[num_options].usage_mask;
203 if (this_usage_mask == LLDB_OPT_SET_ALL)
Chris Lattner24943d22010-06-08 16:52:24 +0000204 {
Jim Ingham34e9a982010-06-15 18:47:14 +0000205 if (num_option_sets == 0)
206 num_option_sets = 1;
Chris Lattner24943d22010-06-08 16:52:24 +0000207 }
208 else
209 {
Greg Clayton54e7afa2010-07-09 20:39:50 +0000210 for (uint32_t j = 0; j < LLDB_MAX_NUM_OPTION_SETS; j++)
Jim Ingham34e9a982010-06-15 18:47:14 +0000211 {
212 if (this_usage_mask & 1 << j)
213 {
214 if (num_option_sets <= j)
215 num_option_sets = j + 1;
216 }
217 }
218 }
219 }
220
221 for (uint32_t opt_set = 0; opt_set < num_option_sets; opt_set++)
222 {
223 uint32_t opt_set_mask;
224
225 opt_set_mask = 1 << opt_set;
226
227 if (opt_set > 0)
228 fprintf (out, "\n");
Greg Clayton54e7afa2010-07-09 20:39:50 +0000229 fprintf (out, "%*s%s", indent_level, "", name);
Jim Ingham6ae25442011-08-16 23:15:02 +0000230 bool is_help_line = false;
Jim Ingham34e9a982010-06-15 18:47:14 +0000231
232 for (uint32_t i = 0; i < num_options; ++i)
233 {
234 if (option_table[i].usage_mask & opt_set_mask)
235 {
Caroline Tice4d6675c2010-10-01 19:59:14 +0000236 CommandArgumentType arg_type = option_table[i].argument_type;
Greg Claytonaa378b12011-02-20 02:15:07 +0000237 const char *arg_name = SBCommandInterpreter::GetArgumentTypeAsCString (arg_type);
Jim Ingham6ae25442011-08-16 23:15:02 +0000238 // This is a bit of a hack, but there's no way to say certain options don't have arguments yet...
239 // so we do it by hand here.
240 if (option_table[i].short_option == 'h')
241 is_help_line = true;
242
Jim Ingham34e9a982010-06-15 18:47:14 +0000243 if (option_table[i].required)
244 {
245 if (option_table[i].option_has_arg == required_argument)
Greg Claytonaa378b12011-02-20 02:15:07 +0000246 fprintf (out, " -%c <%s>", option_table[i].short_option, arg_name);
Jim Ingham34e9a982010-06-15 18:47:14 +0000247 else if (option_table[i].option_has_arg == optional_argument)
Greg Claytonaa378b12011-02-20 02:15:07 +0000248 fprintf (out, " -%c [<%s>]", option_table[i].short_option, arg_name);
Jim Ingham34e9a982010-06-15 18:47:14 +0000249 else
250 fprintf (out, " -%c", option_table[i].short_option);
251 }
252 else
253 {
254 if (option_table[i].option_has_arg == required_argument)
Greg Claytonaa378b12011-02-20 02:15:07 +0000255 fprintf (out, " [-%c <%s>]", option_table[i].short_option, arg_name);
Jim Ingham34e9a982010-06-15 18:47:14 +0000256 else if (option_table[i].option_has_arg == optional_argument)
Greg Claytonaa378b12011-02-20 02:15:07 +0000257 fprintf (out, " [-%c [<%s>]]", option_table[i].short_option, arg_name);
Jim Ingham34e9a982010-06-15 18:47:14 +0000258 else
259 fprintf (out, " [-%c]", option_table[i].short_option);
260 }
261 }
Chris Lattner24943d22010-06-08 16:52:24 +0000262 }
Jim Ingham6ae25442011-08-16 23:15:02 +0000263 if (!is_help_line)
264 fprintf (out, " [[--] <PROGRAM-ARG-1> [<PROGRAM_ARG-2> ...]]");
Chris Lattner24943d22010-06-08 16:52:24 +0000265 }
266
267 fprintf (out, "\n\n");
268
269 // Now print out all the detailed information about the various options: long form, short form and help text:
270 // -- long_name <argument>
271 // - short <argument>
272 // help text
273
274 // This variable is used to keep track of which options' info we've printed out, because some options can be in
275 // more than one usage level, but we only want to print the long form of its information once.
276
277 Driver::OptionData::OptionSet options_seen;
278 Driver::OptionData::OptionSet::iterator pos;
279
280 indent_level += 5;
281
Jim Ingham34e9a982010-06-15 18:47:14 +0000282 for (uint32_t i = 0; i < num_options; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +0000283 {
284 // Only print this option if we haven't already seen it.
285 pos = options_seen.find (option_table[i].short_option);
286 if (pos == options_seen.end())
287 {
Caroline Tice4d6675c2010-10-01 19:59:14 +0000288 CommandArgumentType arg_type = option_table[i].argument_type;
Greg Claytonaa378b12011-02-20 02:15:07 +0000289 const char *arg_name = SBCommandInterpreter::GetArgumentTypeAsCString (arg_type);
Caroline Tice4d6675c2010-10-01 19:59:14 +0000290
Chris Lattner24943d22010-06-08 16:52:24 +0000291 options_seen.insert (option_table[i].short_option);
Greg Clayton54e7afa2010-07-09 20:39:50 +0000292 fprintf (out, "%*s-%c ", indent_level, "", option_table[i].short_option);
Caroline Tice4d6675c2010-10-01 19:59:14 +0000293 if (arg_type != eArgTypeNone)
Greg Claytonaa378b12011-02-20 02:15:07 +0000294 fprintf (out, "<%s>", arg_name);
Chris Lattner24943d22010-06-08 16:52:24 +0000295 fprintf (out, "\n");
Greg Clayton54e7afa2010-07-09 20:39:50 +0000296 fprintf (out, "%*s--%s ", indent_level, "", option_table[i].long_option);
Caroline Tice4d6675c2010-10-01 19:59:14 +0000297 if (arg_type != eArgTypeNone)
Greg Claytonaa378b12011-02-20 02:15:07 +0000298 fprintf (out, "<%s>", arg_name);
Chris Lattner24943d22010-06-08 16:52:24 +0000299 fprintf (out, "\n");
300 indent_level += 5;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000301 OutputFormattedUsageText (out, indent_level, option_table[i].usage_text, screen_width);
Chris Lattner24943d22010-06-08 16:52:24 +0000302 indent_level -= 5;
303 fprintf (out, "\n");
304 }
305 }
306
307 indent_level -= 5;
308
Jim Inghamcf0de262011-08-16 23:57:58 +0000309 fprintf (out, "\n%*s(If you don't provide -f then the first argument will be the file to be debugged"
310 "\n%*s so '%s -- <filename> [<ARG1> [<ARG2>]]' also works."
311 "\n%*s Remember to end the options with \"--\" if any of your arguments have a \"-\" in them.)\n\n",
312 indent_level, "",
313 indent_level, "",
314 name,
315 indent_level, "");
Chris Lattner24943d22010-06-08 16:52:24 +0000316}
317
318void
Greg Claytonb3448432011-03-24 21:19:54 +0000319BuildGetOptTable (OptionDefinition *expanded_option_table, std::vector<struct option> &getopt_table,
Caroline Ticebd5c63e2010-10-12 21:57:09 +0000320 uint32_t num_options)
Chris Lattner24943d22010-06-08 16:52:24 +0000321{
322 if (num_options == 0)
323 return;
324
325 uint32_t i;
326 uint32_t j;
327 std::bitset<256> option_seen;
328
Caroline Ticebd5c63e2010-10-12 21:57:09 +0000329 getopt_table.resize (num_options + 1);
330
Chris Lattner24943d22010-06-08 16:52:24 +0000331 for (i = 0, j = 0; i < num_options; ++i)
Greg Clayton54e7afa2010-07-09 20:39:50 +0000332 {
Chris Lattner24943d22010-06-08 16:52:24 +0000333 char short_opt = expanded_option_table[i].short_option;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000334
Chris Lattner24943d22010-06-08 16:52:24 +0000335 if (option_seen.test(short_opt) == false)
Greg Clayton54e7afa2010-07-09 20:39:50 +0000336 {
Caroline Ticebd5c63e2010-10-12 21:57:09 +0000337 getopt_table[j].name = expanded_option_table[i].long_option;
338 getopt_table[j].has_arg = expanded_option_table[i].option_has_arg;
339 getopt_table[j].flag = NULL;
340 getopt_table[j].val = expanded_option_table[i].short_option;
Chris Lattner24943d22010-06-08 16:52:24 +0000341 option_seen.set(short_opt);
342 ++j;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000343 }
344 }
Chris Lattner24943d22010-06-08 16:52:24 +0000345
Caroline Ticebd5c63e2010-10-12 21:57:09 +0000346 getopt_table[j].name = NULL;
347 getopt_table[j].has_arg = 0;
348 getopt_table[j].flag = NULL;
349 getopt_table[j].val = 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000350
351}
352
Greg Clayton63094e02010-06-23 01:19:29 +0000353Driver::OptionData::OptionData () :
Greg Clayton4dc18922010-12-08 22:23:24 +0000354 m_args(),
Greg Clayton63094e02010-06-23 01:19:29 +0000355 m_script_lang (lldb::eScriptLanguageDefault),
Greg Clayton54e7afa2010-07-09 20:39:50 +0000356 m_crash_log (),
Greg Clayton63094e02010-06-23 01:19:29 +0000357 m_source_command_files (),
358 m_debug_mode (false),
Greg Clayton54e7afa2010-07-09 20:39:50 +0000359 m_print_version (false),
Greg Clayton63094e02010-06-23 01:19:29 +0000360 m_print_help (false),
Stephen Wilsondbeb3e12011-04-11 19:41:40 +0000361 m_use_external_editor(false),
362 m_seen_options()
Chris Lattner24943d22010-06-08 16:52:24 +0000363{
Greg Clayton63094e02010-06-23 01:19:29 +0000364}
365
366Driver::OptionData::~OptionData ()
367{
368}
369
370void
371Driver::OptionData::Clear ()
372{
Greg Clayton4dc18922010-12-08 22:23:24 +0000373 m_args.clear ();
Greg Clayton63094e02010-06-23 01:19:29 +0000374 m_script_lang = lldb::eScriptLanguageDefault;
375 m_source_command_files.clear ();
376 m_debug_mode = false;
377 m_print_help = false;
378 m_print_version = false;
Jim Ingham74989e82010-08-30 19:44:40 +0000379 m_use_external_editor = false;
Greg Clayton63094e02010-06-23 01:19:29 +0000380}
381
382void
383Driver::ResetOptionValues ()
384{
385 m_option_data.Clear ();
386}
387
388const char *
389Driver::GetFilename() const
390{
Greg Clayton4dc18922010-12-08 22:23:24 +0000391 if (m_option_data.m_args.empty())
Greg Clayton63094e02010-06-23 01:19:29 +0000392 return NULL;
Greg Clayton4dc18922010-12-08 22:23:24 +0000393 return m_option_data.m_args.front().c_str();
Greg Clayton63094e02010-06-23 01:19:29 +0000394}
395
396const char *
397Driver::GetCrashLogFilename() const
398{
399 if (m_option_data.m_crash_log.empty())
400 return NULL;
401 return m_option_data.m_crash_log.c_str();
402}
403
404lldb::ScriptLanguage
405Driver::GetScriptLanguage() const
406{
407 return m_option_data.m_script_lang;
408}
409
410size_t
411Driver::GetNumSourceCommandFiles () const
412{
413 return m_option_data.m_source_command_files.size();
414}
415
416const char *
417Driver::GetSourceCommandFileAtIndex (uint32_t idx) const
418{
419 if (idx < m_option_data.m_source_command_files.size())
420 return m_option_data.m_source_command_files[idx].c_str();
421 return NULL;
422}
423
424bool
425Driver::GetDebugMode() const
426{
427 return m_option_data.m_debug_mode;
428}
429
430
431// Check the arguments that were passed to this program to make sure they are valid and to get their
432// argument values (if any). Return a boolean value indicating whether or not to start up the full
433// debugger (i.e. the Command Interpreter) or not. Return FALSE if the arguments were invalid OR
434// if the user only wanted help or version information.
435
436SBError
437Driver::ParseArgs (int argc, const char *argv[], FILE *out_fh, bool &exit)
438{
439 ResetOptionValues ();
440
441 SBCommandReturnObject result;
442
Chris Lattner24943d22010-06-08 16:52:24 +0000443 SBError error;
444 std::string option_string;
445 struct option *long_options = NULL;
Caroline Ticebd5c63e2010-10-12 21:57:09 +0000446 std::vector<struct option> long_options_vector;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000447 uint32_t num_options;
Chris Lattner24943d22010-06-08 16:52:24 +0000448
Greg Clayton54e7afa2010-07-09 20:39:50 +0000449 for (num_options = 0; g_options[num_options].long_option != NULL; ++num_options)
450 /* Do Nothing. */;
Chris Lattner24943d22010-06-08 16:52:24 +0000451
452 if (num_options == 0)
453 {
454 if (argc > 1)
455 error.SetErrorStringWithFormat ("invalid number of options");
456 return error;
457 }
458
Caroline Ticebd5c63e2010-10-12 21:57:09 +0000459 BuildGetOptTable (g_options, long_options_vector, num_options);
Chris Lattner24943d22010-06-08 16:52:24 +0000460
Caroline Ticebd5c63e2010-10-12 21:57:09 +0000461 if (long_options_vector.empty())
462 long_options = NULL;
463 else
464 long_options = &long_options_vector.front();
Chris Lattner24943d22010-06-08 16:52:24 +0000465
466 if (long_options == NULL)
467 {
468 error.SetErrorStringWithFormat ("invalid long options");
469 return error;
470 }
471
472 // Build the option_string argument for call to getopt_long.
473
474 for (int i = 0; long_options[i].name != NULL; ++i)
475 {
476 if (long_options[i].flag == NULL)
477 {
478 option_string.push_back ((char) long_options[i].val);
479 switch (long_options[i].has_arg)
480 {
481 default:
482 case no_argument:
483 break;
484 case required_argument:
485 option_string.push_back (':');
486 break;
487 case optional_argument:
488 option_string.append ("::");
489 break;
490 }
491 }
492 }
493
Jim Ingham558dd5b2011-08-13 00:22:20 +0000494 // This is kind of a pain, but since we make the debugger in the Driver's constructor, we can't
495 // know at that point whether we should read in init files yet. So we don't read them in in the
496 // Driver constructor, then set the flags back to "read them in" here, and then if we see the
497 // "-n" flag, we'll turn it off again. Finally we have to read them in by hand later in the
498 // main loop.
499
500 m_debugger.SkipLLDBInitFiles (false);
501 m_debugger.SkipAppInitFiles (false);
502
Chris Lattner24943d22010-06-08 16:52:24 +0000503 // Prepare for & make calls to getopt_long.
Eli Friedmanef2bc872010-06-13 19:18:49 +0000504#if __GLIBC__
505 optind = 0;
506#else
Chris Lattner24943d22010-06-08 16:52:24 +0000507 optreset = 1;
508 optind = 1;
Eli Friedmanef2bc872010-06-13 19:18:49 +0000509#endif
Chris Lattner24943d22010-06-08 16:52:24 +0000510 int val;
511 while (1)
512 {
513 int long_options_index = -1;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000514 val = ::getopt_long (argc, const_cast<char **>(argv), option_string.c_str(), long_options, &long_options_index);
Chris Lattner24943d22010-06-08 16:52:24 +0000515
516 if (val == -1)
517 break;
518 else if (val == '?')
519 {
Greg Clayton63094e02010-06-23 01:19:29 +0000520 m_option_data.m_print_help = true;
Chris Lattner24943d22010-06-08 16:52:24 +0000521 error.SetErrorStringWithFormat ("unknown or ambiguous option");
522 break;
523 }
524 else if (val == 0)
525 continue;
526 else
527 {
Greg Clayton63094e02010-06-23 01:19:29 +0000528 m_option_data.m_seen_options.insert ((char) val);
Chris Lattner24943d22010-06-08 16:52:24 +0000529 if (long_options_index == -1)
530 {
531 for (int i = 0;
532 long_options[i].name || long_options[i].has_arg || long_options[i].flag || long_options[i].val;
533 ++i)
534 {
535 if (long_options[i].val == val)
536 {
537 long_options_index = i;
538 break;
539 }
540 }
541 }
542
543 if (long_options_index >= 0)
544 {
Greg Clayton63094e02010-06-23 01:19:29 +0000545 const char short_option = (char) g_options[long_options_index].short_option;
546
547 switch (short_option)
548 {
549 case 'h':
550 m_option_data.m_print_help = true;
551 break;
552
553 case 'v':
554 m_option_data.m_print_version = true;
555 break;
556
557 case 'c':
558 m_option_data.m_crash_log = optarg;
559 break;
Greg Clayton887aa282010-10-11 01:05:37 +0000560
Jim Ingham74989e82010-08-30 19:44:40 +0000561 case 'e':
562 m_option_data.m_use_external_editor = true;
563 break;
Greg Clayton887aa282010-10-11 01:05:37 +0000564
565 case 'n':
566 m_debugger.SkipLLDBInitFiles (true);
Jim Ingham558dd5b2011-08-13 00:22:20 +0000567 m_debugger.SkipAppInitFiles (true);
Greg Clayton887aa282010-10-11 01:05:37 +0000568 break;
569
Greg Clayton63094e02010-06-23 01:19:29 +0000570 case 'f':
571 {
572 SBFileSpec file(optarg);
573 if (file.Exists())
Greg Clayton4dc18922010-12-08 22:23:24 +0000574 {
575 m_option_data.m_args.push_back (optarg);
576 }
Caroline Ticeeddffe92010-09-10 04:48:55 +0000577 else if (file.ResolveExecutableLocation())
578 {
579 char path[PATH_MAX];
Johnny Chenee6e7902011-08-10 22:06:24 +0000580 file.GetPath (path, sizeof(path));
Greg Clayton4dc18922010-12-08 22:23:24 +0000581 m_option_data.m_args.push_back (path);
Caroline Ticeeddffe92010-09-10 04:48:55 +0000582 }
Greg Clayton63094e02010-06-23 01:19:29 +0000583 else
584 error.SetErrorStringWithFormat("file specified in --file (-f) option doesn't exist: '%s'", optarg);
585 }
586 break;
587
588 case 'a':
589 if (!m_debugger.SetDefaultArchitecture (optarg))
590 error.SetErrorStringWithFormat("invalid architecture in the -a or --arch option: '%s'", optarg);
591 break;
592
593 case 'l':
594 m_option_data.m_script_lang = m_debugger.GetScriptingLanguage (optarg);
595 break;
596
597 case 'd':
598 m_option_data.m_debug_mode = true;
599 break;
600
601 case 's':
602 {
603 SBFileSpec file(optarg);
604 if (file.Exists())
605 m_option_data.m_source_command_files.push_back (optarg);
Caroline Ticeeddffe92010-09-10 04:48:55 +0000606 else if (file.ResolveExecutableLocation())
607 {
608 char final_path[PATH_MAX];
Johnny Chenee6e7902011-08-10 22:06:24 +0000609 file.GetPath (final_path, sizeof(final_path));
Caroline Ticeeddffe92010-09-10 04:48:55 +0000610 std::string path_str (final_path);
611 m_option_data.m_source_command_files.push_back (path_str);
612 }
Greg Clayton63094e02010-06-23 01:19:29 +0000613 else
614 error.SetErrorStringWithFormat("file specified in --source (-s) option doesn't exist: '%s'", optarg);
615 }
616 break;
617
618 default:
619 m_option_data.m_print_help = true;
620 error.SetErrorStringWithFormat ("unrecognized option %c", short_option);
621 break;
622 }
Chris Lattner24943d22010-06-08 16:52:24 +0000623 }
624 else
625 {
626 error.SetErrorStringWithFormat ("invalid option with value %i", val);
627 }
628 if (error.Fail())
Caroline Ticebd5c63e2010-10-12 21:57:09 +0000629 {
Greg Clayton63094e02010-06-23 01:19:29 +0000630 return error;
Caroline Ticebd5c63e2010-10-12 21:57:09 +0000631 }
Chris Lattner24943d22010-06-08 16:52:24 +0000632 }
633 }
Jim Ingham34e9a982010-06-15 18:47:14 +0000634
Greg Clayton63094e02010-06-23 01:19:29 +0000635 if (error.Fail() || m_option_data.m_print_help)
Chris Lattner24943d22010-06-08 16:52:24 +0000636 {
637 ShowUsage (out_fh, g_options, m_option_data);
Greg Clayton9caa9462010-10-11 01:13:37 +0000638 exit = true;
Chris Lattner24943d22010-06-08 16:52:24 +0000639 }
640 else if (m_option_data.m_print_version)
641 {
Greg Clayton63094e02010-06-23 01:19:29 +0000642 ::fprintf (out_fh, "%s\n", m_debugger.GetVersionString());
643 exit = true;
Chris Lattner24943d22010-06-08 16:52:24 +0000644 }
645 else if (! m_option_data.m_crash_log.empty())
646 {
647 // Handle crash log stuff here.
648 }
649 else
650 {
Greg Clayton4dc18922010-12-08 22:23:24 +0000651 // Any arguments that are left over after option parsing are for
652 // the program. If a file was specified with -f then the filename
653 // is already in the m_option_data.m_args array, and any remaining args
654 // are arguments for the inferior program. If no file was specified with
655 // -f, then what is left is the program name followed by any arguments.
656
657 // Skip any options we consumed with getopt_long
658 argc -= optind;
659 argv += optind;
660
661 if (argc > 0)
662 {
663 for (int arg_idx=0; arg_idx<argc; ++arg_idx)
664 {
665 const char *arg = argv[arg_idx];
666 if (arg)
667 m_option_data.m_args.push_back (arg);
668 }
669 }
670
Chris Lattner24943d22010-06-08 16:52:24 +0000671 }
672
Greg Clayton63094e02010-06-23 01:19:29 +0000673 return error;
Chris Lattner24943d22010-06-08 16:52:24 +0000674}
675
Caroline Tice757500e2010-09-29 18:35:42 +0000676size_t
Chris Lattner24943d22010-06-08 16:52:24 +0000677Driver::GetProcessSTDOUT ()
678{
679 // The process has stuff waiting for stdout; get it and write it out to the appropriate place.
680 char stdio_buffer[1024];
681 size_t len;
Caroline Tice757500e2010-09-29 18:35:42 +0000682 size_t total_bytes = 0;
Jim Inghamc8332952010-08-26 21:32:51 +0000683 while ((len = m_debugger.GetSelectedTarget().GetProcess().GetSTDOUT (stdio_buffer, sizeof (stdio_buffer))) > 0)
Caroline Tice757500e2010-09-29 18:35:42 +0000684 {
Caroline Tice4a348082011-05-02 20:41:46 +0000685 m_io_channel_ap->OutWrite (stdio_buffer, len, ASYNC);
Caroline Tice757500e2010-09-29 18:35:42 +0000686 total_bytes += len;
687 }
688 return total_bytes;
Chris Lattner24943d22010-06-08 16:52:24 +0000689}
690
Caroline Tice757500e2010-09-29 18:35:42 +0000691size_t
Chris Lattner24943d22010-06-08 16:52:24 +0000692Driver::GetProcessSTDERR ()
693{
694 // The process has stuff waiting for stderr; get it and write it out to the appropriate place.
695 char stdio_buffer[1024];
696 size_t len;
Caroline Tice757500e2010-09-29 18:35:42 +0000697 size_t total_bytes = 0;
Jim Inghamc8332952010-08-26 21:32:51 +0000698 while ((len = m_debugger.GetSelectedTarget().GetProcess().GetSTDERR (stdio_buffer, sizeof (stdio_buffer))) > 0)
Caroline Tice757500e2010-09-29 18:35:42 +0000699 {
Caroline Tice4a348082011-05-02 20:41:46 +0000700 m_io_channel_ap->ErrWrite (stdio_buffer, len, ASYNC);
Caroline Tice757500e2010-09-29 18:35:42 +0000701 total_bytes += len;
702 }
703 return total_bytes;
Chris Lattner24943d22010-06-08 16:52:24 +0000704}
705
706void
Jim Inghamc8332952010-08-26 21:32:51 +0000707Driver::UpdateSelectedThread ()
Chris Lattner24943d22010-06-08 16:52:24 +0000708{
709 using namespace lldb;
Jim Inghamc8332952010-08-26 21:32:51 +0000710 SBProcess process(m_debugger.GetSelectedTarget().GetProcess());
Chris Lattner24943d22010-06-08 16:52:24 +0000711 if (process.IsValid())
712 {
Jim Inghamc8332952010-08-26 21:32:51 +0000713 SBThread curr_thread (process.GetSelectedThread());
Chris Lattner24943d22010-06-08 16:52:24 +0000714 SBThread thread;
715 StopReason curr_thread_stop_reason = eStopReasonInvalid;
716 curr_thread_stop_reason = curr_thread.GetStopReason();
717
718 if (!curr_thread.IsValid() ||
719 curr_thread_stop_reason == eStopReasonInvalid ||
720 curr_thread_stop_reason == eStopReasonNone)
721 {
722 // Prefer a thread that has just completed its plan over another thread as current thread.
723 SBThread plan_thread;
724 SBThread other_thread;
725 const size_t num_threads = process.GetNumThreads();
726 size_t i;
727 for (i = 0; i < num_threads; ++i)
728 {
729 thread = process.GetThreadAtIndex(i);
730 StopReason thread_stop_reason = thread.GetStopReason();
731 switch (thread_stop_reason)
732 {
733 default:
734 case eStopReasonInvalid:
735 case eStopReasonNone:
736 break;
737
738 case eStopReasonTrace:
739 case eStopReasonBreakpoint:
740 case eStopReasonWatchpoint:
741 case eStopReasonSignal:
742 case eStopReasonException:
743 if (!other_thread.IsValid())
744 other_thread = thread;
745 break;
746 case eStopReasonPlanComplete:
747 if (!plan_thread.IsValid())
748 plan_thread = thread;
749 break;
750 }
751 }
752 if (plan_thread.IsValid())
Jim Inghamc8332952010-08-26 21:32:51 +0000753 process.SetSelectedThread (plan_thread);
Chris Lattner24943d22010-06-08 16:52:24 +0000754 else if (other_thread.IsValid())
Jim Inghamc8332952010-08-26 21:32:51 +0000755 process.SetSelectedThread (other_thread);
Chris Lattner24943d22010-06-08 16:52:24 +0000756 else
757 {
758 if (curr_thread.IsValid())
759 thread = curr_thread;
760 else
761 thread = process.GetThreadAtIndex(0);
762
763 if (thread.IsValid())
Jim Inghamc8332952010-08-26 21:32:51 +0000764 process.SetSelectedThread (thread);
Chris Lattner24943d22010-06-08 16:52:24 +0000765 }
766 }
767 }
768}
769
770
771// This function handles events that were broadcast by the process.
772void
773Driver::HandleProcessEvent (const SBEvent &event)
774{
775 using namespace lldb;
776 const uint32_t event_type = event.GetType();
777
778 if (event_type & SBProcess::eBroadcastBitSTDOUT)
779 {
780 // The process has stdout available, get it and write it out to the
781 // appropriate place.
Caroline Tice4a348082011-05-02 20:41:46 +0000782 GetProcessSTDOUT ();
Chris Lattner24943d22010-06-08 16:52:24 +0000783 }
784 else if (event_type & SBProcess::eBroadcastBitSTDERR)
785 {
786 // The process has stderr available, get it and write it out to the
787 // appropriate place.
Caroline Tice4a348082011-05-02 20:41:46 +0000788 GetProcessSTDERR ();
Chris Lattner24943d22010-06-08 16:52:24 +0000789 }
790 else if (event_type & SBProcess::eBroadcastBitStateChanged)
791 {
792 // Drain all stout and stderr so we don't see any output come after
793 // we print our prompts
Caroline Tice4a348082011-05-02 20:41:46 +0000794 GetProcessSTDOUT ();
795 GetProcessSTDERR ();
Chris Lattner24943d22010-06-08 16:52:24 +0000796 // Something changed in the process; get the event and report the process's current status and location to
797 // the user.
798 StateType event_state = SBProcess::GetStateFromEvent (event);
799 if (event_state == eStateInvalid)
800 return;
801
802 SBProcess process (SBProcess::GetProcessFromEvent (event));
803 assert (process.IsValid());
804
805 switch (event_state)
806 {
807 case eStateInvalid:
808 case eStateUnloaded:
Greg Claytone71e2582011-02-04 01:58:07 +0000809 case eStateConnected:
Chris Lattner24943d22010-06-08 16:52:24 +0000810 case eStateAttaching:
811 case eStateLaunching:
812 case eStateStepping:
813 case eStateDetached:
814 {
815 char message[1024];
816 int message_len = ::snprintf (message, sizeof(message), "Process %d %s\n", process.GetProcessID(),
Greg Clayton63094e02010-06-23 01:19:29 +0000817 m_debugger.StateAsCString (event_state));
Caroline Tice4a348082011-05-02 20:41:46 +0000818 m_io_channel_ap->OutWrite(message, message_len, ASYNC);
Chris Lattner24943d22010-06-08 16:52:24 +0000819 }
820 break;
821
822 case eStateRunning:
823 // Don't be chatty when we run...
824 break;
825
826 case eStateExited:
Caroline Tice757500e2010-09-29 18:35:42 +0000827 {
828 SBCommandReturnObject result;
829 m_debugger.GetCommandInterpreter().HandleCommand("process status", result, false);
Caroline Tice4a348082011-05-02 20:41:46 +0000830 m_io_channel_ap->ErrWrite (result.GetError(), result.GetErrorSize(), ASYNC);
831 m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize(), ASYNC);
Caroline Tice757500e2010-09-29 18:35:42 +0000832 }
Chris Lattner24943d22010-06-08 16:52:24 +0000833 break;
834
835 case eStateStopped:
836 case eStateCrashed:
837 case eStateSuspended:
838 // Make sure the program hasn't been auto-restarted:
839 if (SBProcess::GetRestartedFromEvent (event))
840 {
841 // FIXME: Do we want to report this, or would that just be annoyingly chatty?
842 char message[1024];
843 int message_len = ::snprintf (message, sizeof(message), "Process %d stopped and was programmatically restarted.\n",
844 process.GetProcessID());
Caroline Tice4a348082011-05-02 20:41:46 +0000845 m_io_channel_ap->OutWrite(message, message_len, ASYNC);
Chris Lattner24943d22010-06-08 16:52:24 +0000846 }
847 else
848 {
Caroline Tice757500e2010-09-29 18:35:42 +0000849 SBCommandReturnObject result;
Jim Inghamc8332952010-08-26 21:32:51 +0000850 UpdateSelectedThread ();
Caroline Tice757500e2010-09-29 18:35:42 +0000851 m_debugger.GetCommandInterpreter().HandleCommand("process status", result, false);
Caroline Tice4a348082011-05-02 20:41:46 +0000852 m_io_channel_ap->ErrWrite (result.GetError(), result.GetErrorSize(), ASYNC);
853 m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize(), ASYNC);
Chris Lattner24943d22010-06-08 16:52:24 +0000854 }
855 break;
856 }
857 }
858}
859
860// This function handles events broadcast by the IOChannel (HasInput, UserInterrupt, or ThreadShouldExit).
861
862bool
863Driver::HandleIOEvent (const SBEvent &event)
864{
865 bool quit = false;
866
867 const uint32_t event_type = event.GetType();
868
869 if (event_type & IOChannel::eBroadcastBitHasUserInput)
870 {
871 // We got some input (i.e. a command string) from the user; pass it off to the command interpreter for
872 // handling.
873
874 const char *command_string = SBEvent::GetCStringFromEvent(event);
875 if (command_string == NULL)
Greg Clayton54e7afa2010-07-09 20:39:50 +0000876 command_string = "";
Chris Lattner24943d22010-06-08 16:52:24 +0000877 SBCommandReturnObject result;
Jim Ingham2e8cb8a2011-02-19 02:53:09 +0000878
Caroline Tice845d6da2011-05-16 19:20:50 +0000879 // We don't want the result to bypass the OutWrite function in IOChannel, as this can result in odd
880 // output orderings and problems with the prompt.
Jim Ingham2e8cb8a2011-02-19 02:53:09 +0000881 m_debugger.GetCommandInterpreter().HandleCommand (command_string, result, true);
882
Caroline Tice845d6da2011-05-16 19:20:50 +0000883 if (result.GetOutputSize() > 0)
884 m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize(), NO_ASYNC);
885
886 if (result.GetErrorSize() > 0)
887 m_io_channel_ap->OutWrite (result.GetError(), result.GetErrorSize(), NO_ASYNC);
888
Chris Lattner24943d22010-06-08 16:52:24 +0000889 // We are done getting and running our command, we can now clear the
890 // m_waiting_for_command so we can get another one.
891 m_waiting_for_command = false;
892
893 // If our editline input reader is active, it means another input reader
894 // got pushed onto the input reader and caused us to become deactivated.
895 // When the input reader above us gets popped, we will get re-activated
896 // and our prompt will refresh in our callback
897 if (m_editline_reader.IsActive())
898 {
899 ReadyForCommand ();
900 }
901 }
902 else if (event_type & IOChannel::eBroadcastBitUserInterrupt)
903 {
904 // This is here to handle control-c interrupts from the user. It has not yet really been implemented.
905 // TO BE DONE: PROPERLY HANDLE CONTROL-C FROM USER
906 //m_io_channel_ap->CancelInput();
907 // Anything else? Send Interrupt to process?
908 }
909 else if ((event_type & IOChannel::eBroadcastBitThreadShouldExit) ||
910 (event_type & IOChannel::eBroadcastBitThreadDidExit))
911 {
912 // If the IOChannel thread is trying to go away, then it is definitely
913 // time to end the debugging session.
914 quit = true;
915 }
916
917 return quit;
918}
919
Chris Lattner24943d22010-06-08 16:52:24 +0000920void
921Driver::MasterThreadBytesReceived (void *baton, const void *src, size_t src_len)
922{
923 Driver *driver = (Driver*)baton;
924 driver->GetFromMaster ((const char *)src, src_len);
925}
926
927void
928Driver::GetFromMaster (const char *src, size_t src_len)
929{
930 // Echo the characters back to the Debugger's stdout, that way if you
931 // type characters while a command is running, you'll see what you've typed.
Greg Clayton63094e02010-06-23 01:19:29 +0000932 FILE *out_fh = m_debugger.GetOutputFileHandle();
Chris Lattner24943d22010-06-08 16:52:24 +0000933 if (out_fh)
934 ::fwrite (src, 1, src_len, out_fh);
935}
936
937size_t
938Driver::EditLineInputReaderCallback
939(
940 void *baton,
941 SBInputReader *reader,
942 InputReaderAction notification,
943 const char *bytes,
944 size_t bytes_len
945)
946{
947 Driver *driver = (Driver *)baton;
948
949 switch (notification)
950 {
951 case eInputReaderActivate:
952 break;
953
954 case eInputReaderReactivate:
955 driver->ReadyForCommand();
956 break;
957
958 case eInputReaderDeactivate:
959 break;
Caroline Tice4a348082011-05-02 20:41:46 +0000960
961 case eInputReaderAsynchronousOutputWritten:
962 if (driver->m_io_channel_ap.get() != NULL)
963 driver->m_io_channel_ap->RefreshPrompt();
964 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000965
Caroline Ticec4f55fe2010-11-19 20:47:54 +0000966 case eInputReaderInterrupt:
967 if (driver->m_io_channel_ap.get() != NULL)
968 {
Caroline Tice4a348082011-05-02 20:41:46 +0000969 driver->m_io_channel_ap->OutWrite ("^C\n", 3, NO_ASYNC);
Caroline Ticec4f55fe2010-11-19 20:47:54 +0000970 driver->m_io_channel_ap->RefreshPrompt();
971 }
972 break;
973
974 case eInputReaderEndOfFile:
975 if (driver->m_io_channel_ap.get() != NULL)
976 {
Caroline Tice4a348082011-05-02 20:41:46 +0000977 driver->m_io_channel_ap->OutWrite ("^D\n", 3, NO_ASYNC);
Caroline Ticec4f55fe2010-11-19 20:47:54 +0000978 driver->m_io_channel_ap->RefreshPrompt ();
979 }
980 write (driver->m_editline_pty.GetMasterFileDescriptor(), "quit\n", 5);
981 break;
982
Chris Lattner24943d22010-06-08 16:52:24 +0000983 case eInputReaderGotToken:
984 write (driver->m_editline_pty.GetMasterFileDescriptor(), bytes, bytes_len);
985 break;
986
987 case eInputReaderDone:
988 break;
989 }
990 return bytes_len;
991}
992
993void
994Driver::MainLoop ()
995{
996 char error_str[1024];
997 if (m_editline_pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY, error_str, sizeof(error_str)) == false)
998 {
999 ::fprintf (stderr, "error: failed to open driver pseudo terminal : %s", error_str);
1000 exit(1);
1001 }
1002 else
1003 {
1004 const char *driver_slave_name = m_editline_pty.GetSlaveName (error_str, sizeof(error_str));
1005 if (driver_slave_name == NULL)
1006 {
1007 ::fprintf (stderr, "error: failed to get slave name for driver pseudo terminal : %s", error_str);
1008 exit(2);
1009 }
1010 else
1011 {
1012 m_editline_slave_fh = ::fopen (driver_slave_name, "r+");
1013 if (m_editline_slave_fh == NULL)
1014 {
1015 SBError error;
1016 error.SetErrorToErrno();
1017 ::fprintf (stderr, "error: failed to get open slave for driver pseudo terminal : %s",
1018 error.GetCString());
1019 exit(3);
1020 }
1021
1022 ::setbuf (m_editline_slave_fh, NULL);
1023 }
1024 }
1025
Caroline Tice4a348082011-05-02 20:41:46 +00001026 lldb_utility::PseudoTerminal editline_output_pty;
1027 FILE *editline_output_slave_fh = NULL;
1028
1029 if (editline_output_pty.OpenFirstAvailableMaster (O_RDWR|O_NOCTTY, error_str, sizeof (error_str)) == false)
1030 {
1031 ::fprintf (stderr, "error: failed to open output pseudo terminal : %s", error_str);
1032 exit(1);
1033 }
1034 else
1035 {
1036 const char *output_slave_name = editline_output_pty.GetSlaveName (error_str, sizeof(error_str));
1037 if (output_slave_name == NULL)
1038 {
1039 ::fprintf (stderr, "error: failed to get slave name for output pseudo terminal : %s", error_str);
1040 exit(2);
1041 }
1042 else
1043 {
1044 editline_output_slave_fh = ::fopen (output_slave_name, "r+");
1045 if (editline_output_slave_fh == NULL)
1046 {
1047 SBError error;
1048 error.SetErrorToErrno();
1049 ::fprintf (stderr, "error: failed to get open slave for output pseudo terminal : %s",
1050 error.GetCString());
1051 exit(3);
1052 }
1053 ::setbuf (editline_output_slave_fh, NULL);
1054 }
1055 }
Chris Lattner24943d22010-06-08 16:52:24 +00001056
1057 // struct termios stdin_termios;
1058
1059 if (::tcgetattr(STDIN_FILENO, &g_old_stdin_termios) == 0)
1060 atexit (reset_stdin_termios);
1061
1062 ::setbuf (stdin, NULL);
1063 ::setbuf (stdout, NULL);
1064
Greg Clayton63094e02010-06-23 01:19:29 +00001065 m_debugger.SetErrorFileHandle (stderr, false);
1066 m_debugger.SetOutputFileHandle (stdout, false);
1067 m_debugger.SetInputFileHandle (stdin, true);
Jim Ingham74989e82010-08-30 19:44:40 +00001068
1069 m_debugger.SetUseExternalEditor(m_option_data.m_use_external_editor);
Chris Lattner24943d22010-06-08 16:52:24 +00001070
1071 // You have to drain anything that comes to the master side of the PTY. master_out_comm is
1072 // for that purpose. The reason you need to do this is a curious reason... editline will echo
1073 // characters to the PTY when it gets characters while el_gets is not running, and then when
1074 // you call el_gets (or el_getc) it will try to reset the terminal back to raw mode which blocks
1075 // if there are unconsumed characters in the out buffer.
1076 // However, you don't need to do anything with the characters, since editline will dump these
1077 // unconsumed characters after printing the prompt again in el_gets.
1078
Greg Claytoneecb0f32010-12-04 02:39:47 +00001079 SBCommunication master_out_comm("driver.editline");
1080 master_out_comm.SetCloseOnEOF (false);
Chris Lattner24943d22010-06-08 16:52:24 +00001081 master_out_comm.AdoptFileDesriptor(m_editline_pty.GetMasterFileDescriptor(), false);
1082 master_out_comm.SetReadThreadBytesReceivedCallback(Driver::MasterThreadBytesReceived, this);
1083
1084 if (master_out_comm.ReadThreadStart () == false)
1085 {
1086 ::fprintf (stderr, "error: failed to start master out read thread");
1087 exit(5);
1088 }
1089
Greg Clayton63094e02010-06-23 01:19:29 +00001090 SBCommandInterpreter sb_interpreter = m_debugger.GetCommandInterpreter();
Chris Lattner24943d22010-06-08 16:52:24 +00001091
Caroline Tice4a348082011-05-02 20:41:46 +00001092 m_io_channel_ap.reset (new IOChannel(m_editline_slave_fh, editline_output_slave_fh, stdout, stderr, this));
1093
1094 SBCommunication out_comm_2("driver.editline_output");
1095 out_comm_2.SetCloseOnEOF (false);
1096 out_comm_2.AdoptFileDesriptor (editline_output_pty.GetMasterFileDescriptor(), false);
1097 out_comm_2.SetReadThreadBytesReceivedCallback (IOChannel::LibeditOutputBytesReceived, m_io_channel_ap.get());
1098
1099 if (out_comm_2.ReadThreadStart () == false)
1100 {
1101 ::fprintf (stderr, "error: failed to start libedit output read thread");
1102 exit (5);
1103 }
1104
Chris Lattner24943d22010-06-08 16:52:24 +00001105
1106 struct winsize window_size;
1107 if (isatty (STDIN_FILENO)
1108 && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0)
1109 {
Caroline Tice6e4c5ce2010-09-04 00:03:46 +00001110 if (window_size.ws_col > 0)
Greg Clayton238c0a12010-09-18 01:14:36 +00001111 m_debugger.SetTerminalWidth (window_size.ws_col);
Chris Lattner24943d22010-06-08 16:52:24 +00001112 }
1113
1114 // Since input can be redirected by the debugger, we must insert our editline
1115 // input reader in the queue so we know when our reader should be active
1116 // and so we can receive bytes only when we are supposed to.
Greg Clayton63094e02010-06-23 01:19:29 +00001117 SBError err (m_editline_reader.Initialize (m_debugger,
1118 Driver::EditLineInputReaderCallback, // callback
Chris Lattner24943d22010-06-08 16:52:24 +00001119 this, // baton
1120 eInputReaderGranularityByte, // token_size
1121 NULL, // end token - NULL means never done
1122 NULL, // prompt - taken care of elsewhere
1123 false)); // echo input - don't need Debugger
1124 // to do this, we handle it elsewhere
1125
1126 if (err.Fail())
1127 {
1128 ::fprintf (stderr, "error: %s", err.GetCString());
1129 exit (6);
1130 }
1131
Greg Clayton63094e02010-06-23 01:19:29 +00001132 m_debugger.PushInputReader (m_editline_reader);
Chris Lattner24943d22010-06-08 16:52:24 +00001133
Greg Clayton63094e02010-06-23 01:19:29 +00001134 SBListener listener(m_debugger.GetListener());
Chris Lattner24943d22010-06-08 16:52:24 +00001135 if (listener.IsValid())
1136 {
1137
1138 listener.StartListeningForEvents (*m_io_channel_ap,
1139 IOChannel::eBroadcastBitHasUserInput |
1140 IOChannel::eBroadcastBitUserInterrupt |
1141 IOChannel::eBroadcastBitThreadShouldExit |
1142 IOChannel::eBroadcastBitThreadDidStart |
1143 IOChannel::eBroadcastBitThreadDidExit);
1144
1145 if (m_io_channel_ap->Start ())
1146 {
1147 bool iochannel_thread_exited = false;
1148
1149 listener.StartListeningForEvents (sb_interpreter.GetBroadcaster(),
Caroline Tice388ca8f2011-05-03 20:53:11 +00001150 SBCommandInterpreter::eBroadcastBitQuitCommandReceived |
1151 SBCommandInterpreter::eBroadcastBitAsynchronousOutputData |
1152 SBCommandInterpreter::eBroadcastBitAsynchronousErrorData);
Chris Lattner24943d22010-06-08 16:52:24 +00001153
1154 // Before we handle any options from the command line, we parse the
1155 // .lldbinit file in the user's home directory.
1156 SBCommandReturnObject result;
1157 sb_interpreter.SourceInitFileInHomeDirectory(result);
1158 if (GetDebugMode())
1159 {
Greg Clayton63094e02010-06-23 01:19:29 +00001160 result.PutError (m_debugger.GetErrorFileHandle());
1161 result.PutOutput (m_debugger.GetOutputFileHandle());
Chris Lattner24943d22010-06-08 16:52:24 +00001162 }
1163
1164 // Now we handle options we got from the command line
1165 char command_string[PATH_MAX * 2];
1166 const size_t num_source_command_files = GetNumSourceCommandFiles();
1167 if (num_source_command_files > 0)
1168 {
1169 for (size_t i=0; i < num_source_command_files; ++i)
1170 {
1171 const char *command_file = GetSourceCommandFileAtIndex(i);
Johnny Chen7c984242010-07-28 21:16:11 +00001172 ::snprintf (command_string, sizeof(command_string), "command source '%s'", command_file);
Greg Clayton63094e02010-06-23 01:19:29 +00001173 m_debugger.GetCommandInterpreter().HandleCommand (command_string, result, false);
Chris Lattner24943d22010-06-08 16:52:24 +00001174 if (GetDebugMode())
1175 {
Greg Clayton63094e02010-06-23 01:19:29 +00001176 result.PutError (m_debugger.GetErrorFileHandle());
1177 result.PutOutput (m_debugger.GetOutputFileHandle());
Chris Lattner24943d22010-06-08 16:52:24 +00001178 }
1179 }
1180 }
1181
Greg Clayton4dc18922010-12-08 22:23:24 +00001182 const size_t num_args = m_option_data.m_args.size();
1183 if (num_args > 0)
Chris Lattner24943d22010-06-08 16:52:24 +00001184 {
1185 char arch_name[64];
Greg Clayton63094e02010-06-23 01:19:29 +00001186 if (m_debugger.GetDefaultArchitecture (arch_name, sizeof (arch_name)))
Greg Clayton4dc18922010-12-08 22:23:24 +00001187 ::snprintf (command_string,
1188 sizeof (command_string),
Greg Claytonabe0fed2011-04-18 08:33:37 +00001189 "target create --arch=%s '%s'",
Greg Clayton4dc18922010-12-08 22:23:24 +00001190 arch_name,
1191 m_option_data.m_args[0].c_str());
Chris Lattner24943d22010-06-08 16:52:24 +00001192 else
Greg Clayton4dc18922010-12-08 22:23:24 +00001193 ::snprintf (command_string,
1194 sizeof(command_string),
Greg Claytonabe0fed2011-04-18 08:33:37 +00001195 "target create '%s'",
Greg Clayton4dc18922010-12-08 22:23:24 +00001196 m_option_data.m_args[0].c_str());
Chris Lattner24943d22010-06-08 16:52:24 +00001197
Greg Clayton63094e02010-06-23 01:19:29 +00001198 m_debugger.HandleCommand (command_string);
Greg Clayton4dc18922010-12-08 22:23:24 +00001199
1200 if (num_args > 1)
1201 {
1202 m_debugger.HandleCommand ("settings clear target.process.run-args");
1203 char arg_cstr[1024];
1204 for (size_t arg_idx = 1; arg_idx < num_args; ++arg_idx)
1205 {
1206 ::snprintf (arg_cstr, sizeof(arg_cstr), "settings append target.process.run-args \"%s\"", m_option_data.m_args[arg_idx].c_str());
1207 m_debugger.HandleCommand (arg_cstr);
1208 }
1209 }
Chris Lattner24943d22010-06-08 16:52:24 +00001210 }
1211
1212 // Now that all option parsing is done, we try and parse the .lldbinit
1213 // file in the current working directory
1214 sb_interpreter.SourceInitFileInCurrentWorkingDirectory (result);
1215 if (GetDebugMode())
1216 {
Greg Clayton63094e02010-06-23 01:19:29 +00001217 result.PutError(m_debugger.GetErrorFileHandle());
1218 result.PutOutput(m_debugger.GetOutputFileHandle());
Chris Lattner24943d22010-06-08 16:52:24 +00001219 }
1220
1221 SBEvent event;
1222
1223 // Make sure the IO channel is started up before we try to tell it we
1224 // are ready for input
1225 listener.WaitForEventForBroadcasterWithType (UINT32_MAX,
1226 *m_io_channel_ap,
1227 IOChannel::eBroadcastBitThreadDidStart,
1228 event);
1229
1230 ReadyForCommand ();
1231
1232 bool done = false;
1233 while (!done)
1234 {
1235 listener.WaitForEvent (UINT32_MAX, event);
1236 if (event.IsValid())
1237 {
1238 if (event.GetBroadcaster().IsValid())
1239 {
1240 uint32_t event_type = event.GetType();
1241 if (event.BroadcasterMatchesRef (*m_io_channel_ap))
1242 {
1243 if ((event_type & IOChannel::eBroadcastBitThreadShouldExit) ||
1244 (event_type & IOChannel::eBroadcastBitThreadDidExit))
1245 {
1246 done = true;
1247 if (event_type & IOChannel::eBroadcastBitThreadDidExit)
1248 iochannel_thread_exited = true;
Chris Lattner24943d22010-06-08 16:52:24 +00001249 }
1250 else
1251 done = HandleIOEvent (event);
1252 }
Jim Inghamc8332952010-08-26 21:32:51 +00001253 else if (event.BroadcasterMatchesRef (m_debugger.GetSelectedTarget().GetProcess().GetBroadcaster()))
Chris Lattner24943d22010-06-08 16:52:24 +00001254 {
1255 HandleProcessEvent (event);
1256 }
1257 else if (event.BroadcasterMatchesRef (sb_interpreter.GetBroadcaster()))
1258 {
1259 if (event_type & SBCommandInterpreter::eBroadcastBitQuitCommandReceived)
1260 done = true;
Caroline Tice388ca8f2011-05-03 20:53:11 +00001261 else if (event_type & SBCommandInterpreter::eBroadcastBitAsynchronousErrorData)
1262 {
1263 const char *data = SBEvent::GetCStringFromEvent (event);
1264 m_io_channel_ap->ErrWrite (data, strlen(data), ASYNC);
1265 }
1266 else if (event_type & SBCommandInterpreter::eBroadcastBitAsynchronousOutputData)
1267 {
1268 const char *data = SBEvent::GetCStringFromEvent (event);
1269 m_io_channel_ap->OutWrite (data, strlen(data), ASYNC);
1270 }
Chris Lattner24943d22010-06-08 16:52:24 +00001271 }
1272 }
1273 }
1274 }
1275
1276 reset_stdin_termios ();
1277
1278 CloseIOChannelFile ();
1279
1280 if (!iochannel_thread_exited)
1281 {
Greg Claytonbef15832010-07-14 00:18:15 +00001282 event.Clear();
Chris Lattner24943d22010-06-08 16:52:24 +00001283 listener.GetNextEventForBroadcasterWithType (*m_io_channel_ap,
1284 IOChannel::eBroadcastBitThreadDidExit,
1285 event);
1286 if (!event.IsValid())
1287 {
1288 // Send end EOF to the driver file descriptor
1289 m_io_channel_ap->Stop();
1290 }
1291 }
1292
Jim Inghamc8332952010-08-26 21:32:51 +00001293 SBProcess process = m_debugger.GetSelectedTarget().GetProcess();
Chris Lattner24943d22010-06-08 16:52:24 +00001294 if (process.IsValid())
1295 process.Destroy();
1296 }
1297 }
1298}
1299
1300
1301void
1302Driver::ReadyForCommand ()
1303{
1304 if (m_waiting_for_command == false)
1305 {
1306 m_waiting_for_command = true;
1307 BroadcastEventByType (Driver::eBroadcastBitReadyForInput, true);
1308 }
1309}
1310
1311
Caroline Ticeb8314fe2010-09-09 17:45:09 +00001312void
1313sigwinch_handler (int signo)
1314{
1315 struct winsize window_size;
1316 if (isatty (STDIN_FILENO)
1317 && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0)
1318 {
1319 if ((window_size.ws_col > 0) && (strlen (g_debugger_name) > 0))
1320 {
1321 char width_str_buffer[25];
1322 ::sprintf (width_str_buffer, "%d", window_size.ws_col);
1323 SBDebugger::SetInternalVariable ("term-width", width_str_buffer, g_debugger_name);
1324 }
1325 }
1326}
1327
Caroline Ticec4f55fe2010-11-19 20:47:54 +00001328void
1329sigint_handler (int signo)
1330{
1331 static bool g_interrupt_sent = false;
1332 if (g_driver)
1333 {
1334 if (!g_interrupt_sent)
1335 {
1336 g_interrupt_sent = true;
1337 g_driver->GetDebugger().DispatchInputInterrupt();
1338 g_interrupt_sent = false;
1339 return;
1340 }
1341 }
1342
1343 exit (signo);
1344}
1345
Chris Lattner24943d22010-06-08 16:52:24 +00001346int
Jim Inghamb2b604f2011-01-27 20:15:39 +00001347main (int argc, char const *argv[], const char *envp[])
Chris Lattner24943d22010-06-08 16:52:24 +00001348{
Chris Lattner24943d22010-06-08 16:52:24 +00001349 SBDebugger::Initialize();
1350
Greg Clayton95e33b72010-11-07 21:02:03 +00001351 SBHostOS::ThreadCreated ("<lldb.driver.main-thread>");
Chris Lattner24943d22010-06-08 16:52:24 +00001352
Greg Clayton36f63a92010-10-19 03:25:40 +00001353 signal (SIGPIPE, SIG_IGN);
Caroline Ticeb8314fe2010-09-09 17:45:09 +00001354 signal (SIGWINCH, sigwinch_handler);
Caroline Ticec4f55fe2010-11-19 20:47:54 +00001355 signal (SIGINT, sigint_handler);
Caroline Ticeb8314fe2010-09-09 17:45:09 +00001356
Greg Clayton63094e02010-06-23 01:19:29 +00001357 // Create a scope for driver so that the driver object will destroy itself
1358 // before SBDebugger::Terminate() is called.
Chris Lattner24943d22010-06-08 16:52:24 +00001359 {
Greg Clayton63094e02010-06-23 01:19:29 +00001360 Driver driver;
1361
1362 bool exit = false;
1363 SBError error (driver.ParseArgs (argc, argv, stdout, exit));
1364 if (error.Fail())
1365 {
1366 const char *error_cstr = error.GetCString ();
1367 if (error_cstr)
1368 ::fprintf (stderr, "error: %s\n", error_cstr);
1369 }
1370 else if (!exit)
1371 {
1372 driver.MainLoop ();
1373 }
Chris Lattner24943d22010-06-08 16:52:24 +00001374 }
1375
1376 SBDebugger::Terminate();
1377 return 0;
1378}