blob: 4afe254a32988cc231dc476762fe9b733e84c67e [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"
33#include "lldb/API/SBTarget.h"
34#include "lldb/API/SBThread.h"
35#include "lldb/API/SBProcess.h"
Chris Lattner24943d22010-06-08 16:52:24 +000036
37using namespace lldb;
38
39static void reset_stdin_termios ();
40static struct termios g_old_stdin_termios;
41
42// In the Driver::MainLoop, we change the terminal settings. This function is
43// added as an atexit handler to make sure we clean them up.
44static void
45reset_stdin_termios ()
46{
47 ::tcsetattr (STDIN_FILENO, TCSANOW, &g_old_stdin_termios);
48}
49
50static lldb::OptionDefinition g_options[] =
51{
Jim Ingham34e9a982010-06-15 18:47:14 +000052 { LLDB_OPT_SET_1, true, "help", 'h', no_argument, NULL, NULL, NULL,
Chris Lattner24943d22010-06-08 16:52:24 +000053 "Prints out the usage information for the LLDB debugger." },
54
Jim Ingham34e9a982010-06-15 18:47:14 +000055 { LLDB_OPT_SET_2, true, "version", 'v', no_argument, NULL, NULL, NULL,
Chris Lattner24943d22010-06-08 16:52:24 +000056 "Prints out the current version number of the LLDB debugger." },
57
Jim Ingham34e9a982010-06-15 18:47:14 +000058 { LLDB_OPT_SET_3, false, "arch", 'a', required_argument, NULL, NULL, "<architecture>",
Chris Lattner24943d22010-06-08 16:52:24 +000059 "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." },
60
Jim Ingham34e9a982010-06-15 18:47:14 +000061 { LLDB_OPT_SET_3 | LLDB_OPT_SET_4, false, "script-language",'l', required_argument, NULL, NULL, "<scripting-language>",
Chris Lattner24943d22010-06-08 16:52:24 +000062 "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." },
63
Jim Ingham34e9a982010-06-15 18:47:14 +000064 { LLDB_OPT_SET_3 | LLDB_OPT_SET_4, false, "debug", 'd', no_argument, NULL, NULL, NULL,
Chris Lattner24943d22010-06-08 16:52:24 +000065 "Tells the debugger to print out extra information for debugging itself." },
66
Jim Ingham34e9a982010-06-15 18:47:14 +000067 { LLDB_OPT_SET_3 | LLDB_OPT_SET_4, false, "source", 's', required_argument, NULL, NULL, "<file>",
Chris Lattner24943d22010-06-08 16:52:24 +000068 "Tells the debugger to read in and execute the file <file>, which should contain lldb commands." },
69
Jim Ingham34e9a982010-06-15 18:47:14 +000070 { LLDB_OPT_SET_3, false, "file", 'f', required_argument, NULL, NULL, "<filename>",
71 "Tells the debugger to use the file <filename> as the program to be debugged." },
72
73 { LLDB_OPT_SET_4, false, "crash-log", 'c', required_argument, NULL, NULL, "<file>",
Chris Lattner24943d22010-06-08 16:52:24 +000074 "Load executable images from a crash log for symbolication." },
75
76 { 0, false, NULL, 0, 0, NULL, NULL, NULL, NULL }
77};
78
79
80Driver::Driver () :
81 SBBroadcaster ("Driver"),
82 m_editline_pty (),
83 m_editline_slave_fh (NULL),
84 m_editline_reader (),
85 m_io_channel_ap (),
86 m_option_data (),
87 m_waiting_for_command (false)
88{
89}
90
91Driver::~Driver ()
92{
93}
94
95void
96Driver::CloseIOChannelFile ()
97{
98 // Write and End of File sequence to the file descriptor to ensure any
99 // read functions can exit.
100 char eof_str[] = "\x04";
101 ::write (m_editline_pty.GetMasterFileDescriptor(), eof_str, strlen(eof_str));
102
103 m_editline_pty.CloseMasterFileDescriptor();
104
105 if (m_editline_slave_fh)
106 {
107 ::fclose (m_editline_slave_fh);
108 m_editline_slave_fh = NULL;
109 }
110}
111
112// This function takes INDENT, which tells how many spaces to output at the front of each line; SPACES, which is
113// a string that is output_max_columns long, containing spaces; and TEXT, which is the text that is to be output.
114// It outputs the text, on multiple lines if necessary, to RESULT, with INDENT spaces at the front of each line. It
115// breaks lines on spaces, tabs or newlines, shortening the line if necessary to not break in the middle of a word.
116// It assumes that each output line should contain a maximum of OUTPUT_MAX_COLUMNS characters.
117
118void
119OutputFormattedUsageText (FILE *out, int indent, char *spaces, const char *text, int output_max_columns)
120{
121 int len = strlen (text);
122 std::string text_string (text);
123 std::string spaces_string (spaces);
124
125 // Force indentation to be reasonable.
126 if (indent >= output_max_columns)
127 indent = 0;
128
129 // Will it all fit on one line?
130
131 if (len + indent < output_max_columns)
132 // Output as a single line
133 fprintf (out, "%s%s\n", spaces_string.substr (0, indent).c_str(), text);
134 else
135 {
136 // We need to break it up into multiple lines.
137 int text_width = output_max_columns - indent - 1;
138 int start = 0;
139 int end = start;
140 int final_end = len;
141 int sub_len;
142
143 while (end < final_end)
144 {
145 // Dont start the 'text' on a space, since we're already outputting the indentation.
146 while ((start < final_end) && (text[start] == ' '))
147 start++;
148
149 end = start + text_width;
150 if (end > final_end)
151 end = final_end;
152 else
153 {
154 // If we're not at the end of the text, make sure we break the line on white space.
155 while (end > start
156 && text[end] != ' ' && text[end] != '\t' && text[end] != '\n')
157 end--;
158 }
159 sub_len = end - start;
160 std::string substring = text_string.substr (start, sub_len);
161 fprintf (out, "%s%s\n", spaces_string.substr(0, indent).c_str(), substring.c_str());
162 start = end + 1;
163 }
164 }
165}
166
167void
168ShowUsage (FILE *out, lldb::OptionDefinition *option_table, Driver::OptionData data)
169{
170 uint32_t screen_width = 80;
171 uint32_t indent_level = 0;
172 const char *name = "lldb";
173 char spaces[screen_width+1];
174 uint32_t i;
Jim Ingham34e9a982010-06-15 18:47:14 +0000175
Chris Lattner24943d22010-06-08 16:52:24 +0000176 for (i = 0; i < screen_width; ++i)
177 spaces[i] = ' ';
178 spaces[i] = '\n';
179
180 std::string spaces_string (spaces);
181
182 fprintf (out, "\nUsage:\n\n");
183
184 indent_level += 2;
185
186
187 // First, show each usage level set of options, e.g. <cmd> [options-for-level-0]
188 // <cmd> [options-for-level-1]
189 // etc.
190
Chris Lattner24943d22010-06-08 16:52:24 +0000191 uint32_t num_options;
Jim Ingham34e9a982010-06-15 18:47:14 +0000192 uint32_t num_option_sets = 0;
193
194 for (num_options = 0; option_table[num_options].long_option != NULL; ++num_options)
Chris Lattner24943d22010-06-08 16:52:24 +0000195 {
Jim Ingham34e9a982010-06-15 18:47:14 +0000196 uint32_t this_usage_mask = option_table[num_options].usage_mask;
197 if (this_usage_mask == LLDB_OPT_SET_ALL)
Chris Lattner24943d22010-06-08 16:52:24 +0000198 {
Jim Ingham34e9a982010-06-15 18:47:14 +0000199 if (num_option_sets == 0)
200 num_option_sets = 1;
Chris Lattner24943d22010-06-08 16:52:24 +0000201 }
202 else
203 {
Jim Ingham34e9a982010-06-15 18:47:14 +0000204 for (int j = 0; j < LLDB_MAX_NUM_OPTION_SETS; j++)
205 {
206 if (this_usage_mask & 1 << j)
207 {
208 if (num_option_sets <= j)
209 num_option_sets = j + 1;
210 }
211 }
212 }
213 }
214
215 for (uint32_t opt_set = 0; opt_set < num_option_sets; opt_set++)
216 {
217 uint32_t opt_set_mask;
218
219 opt_set_mask = 1 << opt_set;
220
221 if (opt_set > 0)
222 fprintf (out, "\n");
223 fprintf (out, "%s%s", spaces_string.substr(0, indent_level).c_str(), name);
224
225 for (uint32_t i = 0; i < num_options; ++i)
226 {
227 if (option_table[i].usage_mask & opt_set_mask)
228 {
229 if (option_table[i].required)
230 {
231 if (option_table[i].option_has_arg == required_argument)
232 fprintf (out, " -%c %s", option_table[i].short_option, option_table[i].argument_name);
233 else if (option_table[i].option_has_arg == optional_argument)
234 fprintf (out, " -%c [%s]", option_table[i].short_option, option_table[i].argument_name);
235 else
236 fprintf (out, " -%c", option_table[i].short_option);
237 }
238 else
239 {
240 if (option_table[i].option_has_arg == required_argument)
241 fprintf (out, " [-%c %s]", option_table[i].short_option, option_table[i].argument_name);
242 else if (option_table[i].option_has_arg == optional_argument)
243 fprintf (out, " [-%c [%s]]", option_table[i].short_option, option_table[i].argument_name);
244 else
245 fprintf (out, " [-%c]", option_table[i].short_option);
246 }
247 }
Chris Lattner24943d22010-06-08 16:52:24 +0000248 }
249 }
250
251 fprintf (out, "\n\n");
252
253 // Now print out all the detailed information about the various options: long form, short form and help text:
254 // -- long_name <argument>
255 // - short <argument>
256 // help text
257
258 // This variable is used to keep track of which options' info we've printed out, because some options can be in
259 // more than one usage level, but we only want to print the long form of its information once.
260
261 Driver::OptionData::OptionSet options_seen;
262 Driver::OptionData::OptionSet::iterator pos;
263
264 indent_level += 5;
265
Jim Ingham34e9a982010-06-15 18:47:14 +0000266 for (uint32_t i = 0; i < num_options; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +0000267 {
268 // Only print this option if we haven't already seen it.
269 pos = options_seen.find (option_table[i].short_option);
270 if (pos == options_seen.end())
271 {
272 options_seen.insert (option_table[i].short_option);
273 fprintf (out, "%s-%c ", spaces_string.substr(0, indent_level).c_str(), option_table[i].short_option);
274 if (option_table[i].argument_name != NULL)
275 fprintf (out, "%s", option_table[i].argument_name);
276 fprintf (out, "\n");
277 fprintf (out, "%s--%s ", spaces_string.substr(0, indent_level).c_str(), option_table[i].long_option);
278 if (option_table[i].argument_name != NULL)
279 fprintf (out, "%s", option_table[i].argument_name);
280 fprintf (out, "\n");
281 indent_level += 5;
282 OutputFormattedUsageText (out, indent_level, spaces, option_table[i].usage_text, screen_width);
283 indent_level -= 5;
284 fprintf (out, "\n");
285 }
286 }
287
288 indent_level -= 5;
289
290 fprintf (out, "\n%s('%s <filename>' also works, to specify the file to be debugged.)\n\n",
291 spaces_string.substr(0, indent_level).c_str(), name);
292}
293
294void
295BuildGetOptTable (lldb::OptionDefinition *expanded_option_table, struct option **getopt_table, int num_options)
296{
297 if (num_options == 0)
298 return;
299
300 uint32_t i;
301 uint32_t j;
302 std::bitset<256> option_seen;
303
304 for (i = 0, j = 0; i < num_options; ++i)
305 {
306 char short_opt = expanded_option_table[i].short_option;
307
308 if (option_seen.test(short_opt) == false)
309 {
310 (*getopt_table)[j].name = expanded_option_table[i].long_option;
311 (*getopt_table)[j].has_arg = expanded_option_table[i].option_has_arg;
312 (*getopt_table)[j].flag = NULL;
313 (*getopt_table)[j].val = expanded_option_table[i].short_option;
314 option_seen.set(short_opt);
315 ++j;
316 }
317 }
318
319 (*getopt_table)[j].name = NULL;
320 (*getopt_table)[j].has_arg = 0;
321 (*getopt_table)[j].flag = NULL;
322 (*getopt_table)[j].val = 0;
323
324}
325
326SBError
327ParseOptions (Driver::OptionData &data, int argc, const char **argv)
328{
329 SBError error;
330 std::string option_string;
331 struct option *long_options = NULL;
332 int num_options;
333
334 for (num_options = 0; g_options[num_options].long_option != NULL; ++num_options);
335
336 if (num_options == 0)
337 {
338 if (argc > 1)
339 error.SetErrorStringWithFormat ("invalid number of options");
340 return error;
341 }
342
343 long_options = (struct option *) malloc ((num_options + 1) * sizeof (struct option));
344
345 BuildGetOptTable (g_options, &long_options, num_options);
346
347 if (long_options == NULL)
348 {
349 error.SetErrorStringWithFormat ("invalid long options");
350 return error;
351 }
352
353 // Build the option_string argument for call to getopt_long.
354
355 for (int i = 0; long_options[i].name != NULL; ++i)
356 {
357 if (long_options[i].flag == NULL)
358 {
359 option_string.push_back ((char) long_options[i].val);
360 switch (long_options[i].has_arg)
361 {
362 default:
363 case no_argument:
364 break;
365 case required_argument:
366 option_string.push_back (':');
367 break;
368 case optional_argument:
369 option_string.append ("::");
370 break;
371 }
372 }
373 }
374
375 // Prepare for & make calls to getopt_long.
Eli Friedmanef2bc872010-06-13 19:18:49 +0000376#if __GLIBC__
377 optind = 0;
378#else
Chris Lattner24943d22010-06-08 16:52:24 +0000379 optreset = 1;
380 optind = 1;
Eli Friedmanef2bc872010-06-13 19:18:49 +0000381#endif
Chris Lattner24943d22010-06-08 16:52:24 +0000382 int val;
383 while (1)
384 {
385 int long_options_index = -1;
386 val = ::getopt_long (argc, (char * const *) argv, option_string.c_str(), long_options, &long_options_index);
387
388 if (val == -1)
389 break;
390 else if (val == '?')
391 {
392 data.m_print_help = true;
393 error.SetErrorStringWithFormat ("unknown or ambiguous option");
394 break;
395 }
396 else if (val == 0)
397 continue;
398 else
399 {
400 data.m_seen_options.insert ((char) val);
401 if (long_options_index == -1)
402 {
403 for (int i = 0;
404 long_options[i].name || long_options[i].has_arg || long_options[i].flag || long_options[i].val;
405 ++i)
406 {
407 if (long_options[i].val == val)
408 {
409 long_options_index = i;
410 break;
411 }
412 }
413 }
414
415 if (long_options_index >= 0)
416 {
417 error = Driver::SetOptionValue (long_options_index,
418 long_options[long_options_index].has_arg == no_argument ? NULL : optarg,
419 data);
420 }
421 else
422 {
423 error.SetErrorStringWithFormat ("invalid option with value %i", val);
424 }
425 if (error.Fail())
426 break;
427 }
428 }
429
430 return error;
431}
432
433Driver::OptionData::OptionData () :
434 m_filename(),
435 m_script_lang (lldb::eScriptLanguageDefault),
436 m_source_command_files (),
437 m_debug_mode (false),
438 m_print_help (false),
439 m_print_version (false)
440
441{
442}
443
444Driver::OptionData::~OptionData ()
445{
446}
447
448void
449Driver::OptionData::Clear ()
450{
451 m_filename.clear ();
452 m_script_lang = lldb::eScriptLanguageDefault;
453 m_source_command_files.clear ();
454 m_debug_mode = false;
455 m_print_help = false;
456 m_print_version = false;
457}
458
459SBError
460Driver::SetOptionValue (int option_idx, const char *option_arg, Driver::OptionData &option_data)
461{
462 SBError error;
463 const char short_option = (char) g_options[option_idx].short_option;
464
465 switch (short_option)
466 {
467 case 'h':
468 option_data.m_print_help = true;
469 break;
470
471 case 'v':
472 option_data.m_print_version = true;
473 break;
474
475 case 'c':
476 option_data.m_crash_log = option_arg;
477 break;
478
479 case 'f':
480 {
481 SBFileSpec file(option_arg);
482 if (file.Exists())
483 option_data.m_filename = option_arg;
484 else
485 error.SetErrorStringWithFormat("file specified in --file (-f) option doesn't exist: '%s'", option_arg);
486 }
487 break;
488
489 case 'a':
490 if (!SBDebugger::SetDefaultArchitecture (option_arg))
491 error.SetErrorStringWithFormat("invalid architecture in the -a or --arch option: '%s'", option_arg);
492 break;
493
494 case 'l':
495 option_data.m_script_lang = SBDebugger::GetScriptingLanguage (option_arg);
496 break;
497
498 case 'd':
499 option_data.m_debug_mode = true;
500 break;
501
502 case 's':
503 {
504 SBFileSpec file(option_arg);
505 if (file.Exists())
506 option_data.m_source_command_files.push_back (option_arg);
507 else
508 error.SetErrorStringWithFormat("file specified in --source (-s) option doesn't exist: '%s'", option_arg);
509 }
510 break;
511
512 default:
513 option_data.m_print_help = true;
514 error.SetErrorStringWithFormat ("unrecognized option %c", short_option);
515 break;
516 }
517
518 return error;
519}
520
521void
522Driver::ResetOptionValues ()
523{
524 m_option_data.Clear ();
525}
526
527const char *
528Driver::GetFilename() const
529{
530 if (m_option_data.m_filename.empty())
531 return NULL;
532 return m_option_data.m_filename.c_str();
533}
534
535const char *
536Driver::GetCrashLogFilename() const
537{
538 if (m_option_data.m_crash_log.empty())
539 return NULL;
540 return m_option_data.m_crash_log.c_str();
541}
542
543lldb::ScriptLanguage
544Driver::GetScriptLanguage() const
545{
546 return m_option_data.m_script_lang;
547}
548
549size_t
550Driver::GetNumSourceCommandFiles () const
551{
552 return m_option_data.m_source_command_files.size();
553}
554
555const char *
556Driver::GetSourceCommandFileAtIndex (uint32_t idx) const
557{
558 if (idx < m_option_data.m_source_command_files.size())
559 return m_option_data.m_source_command_files[idx].c_str();
560 return NULL;
561}
562
563bool
564Driver::GetDebugMode() const
565{
566 return m_option_data.m_debug_mode;
567}
568
569
570// Check the arguments that were passed to this program to make sure they are valid and to get their
571// argument values (if any). Return a boolean value indicating whether or not to start up the full
572// debugger (i.e. the Command Interpreter) or not. Return FALSE if the arguments were invalid OR
573// if the user only wanted help or version information.
574
575bool
576Driver::ParseArgs (int argc, const char *argv[], FILE *out_fh, FILE *err_fh)
577{
578 bool valid = true;
579
580 ResetOptionValues ();
581
Jim Ingham34e9a982010-06-15 18:47:14 +0000582 SBCommandReturnObject result;
Chris Lattner24943d22010-06-08 16:52:24 +0000583
Jim Ingham34e9a982010-06-15 18:47:14 +0000584 SBError error = ParseOptions (m_option_data, argc, argv);
585 if (error.Fail())
586 {
587 const char *error_cstr = error.GetCString ();
588 if (error_cstr)
589 ::fprintf (err_fh, "error: %s\n", error_cstr);
590 valid = false;
591 }
592
593 // If there is a trailing argument, it is the filename.
594 if (optind == argc - 1)
595 {
596 if (m_option_data.m_filename.empty())
Chris Lattner24943d22010-06-08 16:52:24 +0000597 {
Jim Ingham34e9a982010-06-15 18:47:14 +0000598 m_option_data.m_filename = argv[optind];
Chris Lattner24943d22010-06-08 16:52:24 +0000599 }
Jim Ingham34e9a982010-06-15 18:47:14 +0000600 else
601 {
602 ::fprintf (err_fh, "error: don't provide a file both on in the -f option and as an argument.");
603 valid = false;
604 }
605
Chris Lattner24943d22010-06-08 16:52:24 +0000606 }
Jim Ingham34e9a982010-06-15 18:47:14 +0000607 else if (optind < argc - 1)
608 {
609 // Trailing extra arguments...
610 ::fprintf (err_fh, "error: trailing extra arguments - only one the filename is allowed.");
611 valid = false;
612
613 }
614
615 if (!valid || m_option_data.m_print_help)
Chris Lattner24943d22010-06-08 16:52:24 +0000616 {
617 ShowUsage (out_fh, g_options, m_option_data);
618 valid = false;
619 }
620 else if (m_option_data.m_print_version)
621 {
622 ::fprintf (out_fh, "%s\n", SBDebugger::GetVersionString());
623 valid = false;
624 }
625 else if (! m_option_data.m_crash_log.empty())
626 {
627 // Handle crash log stuff here.
628 }
629 else
630 {
631 // All other combinations are valid; do nothing more here.
632 }
633
634 return valid;
635}
636
637void
638Driver::GetProcessSTDOUT ()
639{
640 // The process has stuff waiting for stdout; get it and write it out to the appropriate place.
641 char stdio_buffer[1024];
642 size_t len;
643 while ((len = SBDebugger::GetCurrentTarget().GetProcess().GetSTDOUT (stdio_buffer, sizeof (stdio_buffer))) > 0)
644 m_io_channel_ap->OutWrite (stdio_buffer, len);
645}
646
647void
648Driver::GetProcessSTDERR ()
649{
650 // The process has stuff waiting for stderr; get it and write it out to the appropriate place.
651 char stdio_buffer[1024];
652 size_t len;
653 while ((len = SBDebugger::GetCurrentTarget().GetProcess().GetSTDERR (stdio_buffer, sizeof (stdio_buffer))) > 0)
654 m_io_channel_ap->ErrWrite (stdio_buffer, len);
655}
656
657void
658Driver::UpdateCurrentThread ()
659{
660 using namespace lldb;
661 SBProcess process(SBDebugger::GetCurrentTarget().GetProcess());
662 if (process.IsValid())
663 {
664 SBThread curr_thread (process.GetCurrentThread());
665 SBThread thread;
666 StopReason curr_thread_stop_reason = eStopReasonInvalid;
667 curr_thread_stop_reason = curr_thread.GetStopReason();
668
669 if (!curr_thread.IsValid() ||
670 curr_thread_stop_reason == eStopReasonInvalid ||
671 curr_thread_stop_reason == eStopReasonNone)
672 {
673 // Prefer a thread that has just completed its plan over another thread as current thread.
674 SBThread plan_thread;
675 SBThread other_thread;
676 const size_t num_threads = process.GetNumThreads();
677 size_t i;
678 for (i = 0; i < num_threads; ++i)
679 {
680 thread = process.GetThreadAtIndex(i);
681 StopReason thread_stop_reason = thread.GetStopReason();
682 switch (thread_stop_reason)
683 {
684 default:
685 case eStopReasonInvalid:
686 case eStopReasonNone:
687 break;
688
689 case eStopReasonTrace:
690 case eStopReasonBreakpoint:
691 case eStopReasonWatchpoint:
692 case eStopReasonSignal:
693 case eStopReasonException:
694 if (!other_thread.IsValid())
695 other_thread = thread;
696 break;
697 case eStopReasonPlanComplete:
698 if (!plan_thread.IsValid())
699 plan_thread = thread;
700 break;
701 }
702 }
703 if (plan_thread.IsValid())
704 process.SetCurrentThread (plan_thread);
705 else if (other_thread.IsValid())
706 process.SetCurrentThread (other_thread);
707 else
708 {
709 if (curr_thread.IsValid())
710 thread = curr_thread;
711 else
712 thread = process.GetThreadAtIndex(0);
713
714 if (thread.IsValid())
715 process.SetCurrentThread (thread);
716 }
717 }
718 }
719}
720
721
722// This function handles events that were broadcast by the process.
723void
724Driver::HandleProcessEvent (const SBEvent &event)
725{
726 using namespace lldb;
727 const uint32_t event_type = event.GetType();
728
729 if (event_type & SBProcess::eBroadcastBitSTDOUT)
730 {
731 // The process has stdout available, get it and write it out to the
732 // appropriate place.
733 GetProcessSTDOUT ();
734 }
735 else if (event_type & SBProcess::eBroadcastBitSTDERR)
736 {
737 // The process has stderr available, get it and write it out to the
738 // appropriate place.
739 GetProcessSTDERR ();
740 }
741 else if (event_type & SBProcess::eBroadcastBitStateChanged)
742 {
743 // Drain all stout and stderr so we don't see any output come after
744 // we print our prompts
745 GetProcessSTDOUT ();
746 GetProcessSTDERR ();
747
748 // Something changed in the process; get the event and report the process's current status and location to
749 // the user.
750 StateType event_state = SBProcess::GetStateFromEvent (event);
751 if (event_state == eStateInvalid)
752 return;
753
754 SBProcess process (SBProcess::GetProcessFromEvent (event));
755 assert (process.IsValid());
756
757 switch (event_state)
758 {
759 case eStateInvalid:
760 case eStateUnloaded:
761 case eStateAttaching:
762 case eStateLaunching:
763 case eStateStepping:
764 case eStateDetached:
765 {
766 char message[1024];
767 int message_len = ::snprintf (message, sizeof(message), "Process %d %s\n", process.GetProcessID(),
768 SBDebugger::StateAsCString (event_state));
769 m_io_channel_ap->OutWrite(message, message_len);
770 }
771 break;
772
773 case eStateRunning:
774 // Don't be chatty when we run...
775 break;
776
777 case eStateExited:
Jim Ingham41313fc2010-06-18 01:23:09 +0000778 SBDebugger::HandleCommand("process status");
Chris Lattner24943d22010-06-08 16:52:24 +0000779 m_io_channel_ap->RefreshPrompt();
780 break;
781
782 case eStateStopped:
783 case eStateCrashed:
784 case eStateSuspended:
785 // Make sure the program hasn't been auto-restarted:
786 if (SBProcess::GetRestartedFromEvent (event))
787 {
788 // FIXME: Do we want to report this, or would that just be annoyingly chatty?
789 char message[1024];
790 int message_len = ::snprintf (message, sizeof(message), "Process %d stopped and was programmatically restarted.\n",
791 process.GetProcessID());
792 m_io_channel_ap->OutWrite(message, message_len);
793 }
794 else
795 {
796 UpdateCurrentThread ();
Jim Ingham41313fc2010-06-18 01:23:09 +0000797 SBDebugger::HandleCommand("process status");
Chris Lattner24943d22010-06-08 16:52:24 +0000798 m_io_channel_ap->RefreshPrompt();
799 }
800 break;
801 }
802 }
803}
804
805// This function handles events broadcast by the IOChannel (HasInput, UserInterrupt, or ThreadShouldExit).
806
807bool
808Driver::HandleIOEvent (const SBEvent &event)
809{
810 bool quit = false;
811
812 const uint32_t event_type = event.GetType();
813
814 if (event_type & IOChannel::eBroadcastBitHasUserInput)
815 {
816 // We got some input (i.e. a command string) from the user; pass it off to the command interpreter for
817 // handling.
818
819 const char *command_string = SBEvent::GetCStringFromEvent(event);
820 if (command_string == NULL)
821 command_string == "";
822 SBCommandReturnObject result;
823 if (SBDebugger::GetCommandInterpreter().HandleCommand (command_string, result, true) != lldb::eReturnStatusQuit)
824 {
825 m_io_channel_ap->ErrWrite (result.GetError(), result.GetErrorSize());
826 m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize());
827 }
828 // We are done getting and running our command, we can now clear the
829 // m_waiting_for_command so we can get another one.
830 m_waiting_for_command = false;
831
832 // If our editline input reader is active, it means another input reader
833 // got pushed onto the input reader and caused us to become deactivated.
834 // When the input reader above us gets popped, we will get re-activated
835 // and our prompt will refresh in our callback
836 if (m_editline_reader.IsActive())
837 {
838 ReadyForCommand ();
839 }
840 }
841 else if (event_type & IOChannel::eBroadcastBitUserInterrupt)
842 {
843 // This is here to handle control-c interrupts from the user. It has not yet really been implemented.
844 // TO BE DONE: PROPERLY HANDLE CONTROL-C FROM USER
845 //m_io_channel_ap->CancelInput();
846 // Anything else? Send Interrupt to process?
847 }
848 else if ((event_type & IOChannel::eBroadcastBitThreadShouldExit) ||
849 (event_type & IOChannel::eBroadcastBitThreadDidExit))
850 {
851 // If the IOChannel thread is trying to go away, then it is definitely
852 // time to end the debugging session.
853 quit = true;
854 }
855
856 return quit;
857}
858
859
860//struct CrashImageInfo
861//{
862// std::string path;
863// VMRange text_range;
864// UUID uuid;
865//};
866//
867//void
868//Driver::ParseCrashLog (const char *crash_log)
869//{
870// printf("Parsing crash log: %s\n", crash_log);
871//
872// char image_path[PATH_MAX];
873// std::vector<CrashImageInfo> crash_infos;
874// if (crash_log && crash_log[0])
875// {
876// FileSpec crash_log_file (crash_log);
877// STLStringArray crash_log_lines;
878// if (crash_log_file.ReadFileLines (crash_log_lines))
879// {
880// const size_t num_crash_log_lines = crash_log_lines.size();
881// size_t i;
882// for (i=0; i<num_crash_log_lines; ++i)
883// {
884// const char *line = crash_log_lines[i].c_str();
885// if (strstr (line, "Code Type:"))
886// {
887// char arch_string[256];
888// if (sscanf(line, "%s", arch_string))
889// {
890// if (strcmp(arch_string, "X86-64"))
891// lldb::GetDefaultArchitecture ().SetArch ("x86_64");
892// else if (strcmp(arch_string, "X86"))
893// lldb::GetDefaultArchitecture ().SetArch ("i386");
894// else
895// {
896// ArchSpec arch(arch_string);
897// if (arch.IsValid ())
898// lldb::GetDefaultArchitecture () = arch;
899// else
900// fprintf(stderr, "Unrecognized architecture: %s\n", arch_string);
901// }
902// }
903// }
904// else
905// if (strstr(line, "Path:"))
906// {
907// const char *p = line + strlen("Path:");
908// while (isspace(*p))
909// ++p;
910//
911// m_option_data.m_filename.assign (p);
912// }
913// else
914// if (strstr(line, "Binary Images:"))
915// {
916// while (++i < num_crash_log_lines)
917// {
918// if (crash_log_lines[i].empty())
919// break;
920//
921// line = crash_log_lines[i].c_str();
922// uint64_t text_start_addr;
923// uint64_t text_end_addr;
924// char uuid_cstr[64];
925// int bytes_consumed_before_uuid = 0;
926// int bytes_consumed_after_uuid = 0;
927//
928// int items_parsed = ::sscanf (line,
929// "%llx - %llx %*s %*s %*s %n%s %n",
930// &text_start_addr,
931// &text_end_addr,
932// &bytes_consumed_before_uuid,
933// uuid_cstr,
934// &bytes_consumed_after_uuid);
935//
936// if (items_parsed == 3)
937// {
938//
939// CrashImageInfo info;
940// info.text_range.SetBaseAddress(text_start_addr);
941// info.text_range.SetEndAddress(text_end_addr);
942//
943// if (uuid_cstr[0] == '<')
944// {
945// if (info.uuid.SetfromCString (&uuid_cstr[1]) == 0)
946// info.uuid.Clear();
947//
948// ::strncpy (image_path, line + bytes_consumed_after_uuid, sizeof(image_path));
949// }
950// else
951// {
952// ::strncpy (image_path, line + bytes_consumed_before_uuid, sizeof(image_path));
953// }
954//
955// info.path = image_path;
956//
957// crash_infos.push_back (info);
958//
959// info.uuid.GetAsCString(uuid_cstr, sizeof(uuid_cstr));
960//
961// printf("0x%16.16llx - 0x%16.16llx <%s> %s\n",
962// text_start_addr,
963// text_end_addr,
964// uuid_cstr,
965// image_path);
966// }
967// }
968// }
969// }
970// }
971//
972// if (crash_infos.size())
973// {
974// SBTarget target (SBDebugger::CreateTarget (crash_infos.front().path.c_str(),
975// lldb::GetDefaultArchitecture().AsCString (),
976// false));
977// if (target.IsValid())
978// {
979//
980// }
981// }
982// }
983//}
984//
985
986void
987Driver::MasterThreadBytesReceived (void *baton, const void *src, size_t src_len)
988{
989 Driver *driver = (Driver*)baton;
990 driver->GetFromMaster ((const char *)src, src_len);
991}
992
993void
994Driver::GetFromMaster (const char *src, size_t src_len)
995{
996 // Echo the characters back to the Debugger's stdout, that way if you
997 // type characters while a command is running, you'll see what you've typed.
998 FILE *out_fh = SBDebugger::GetOutputFileHandle();
999 if (out_fh)
1000 ::fwrite (src, 1, src_len, out_fh);
1001}
1002
1003size_t
1004Driver::EditLineInputReaderCallback
1005(
1006 void *baton,
1007 SBInputReader *reader,
1008 InputReaderAction notification,
1009 const char *bytes,
1010 size_t bytes_len
1011)
1012{
1013 Driver *driver = (Driver *)baton;
1014
1015 switch (notification)
1016 {
1017 case eInputReaderActivate:
1018 break;
1019
1020 case eInputReaderReactivate:
1021 driver->ReadyForCommand();
1022 break;
1023
1024 case eInputReaderDeactivate:
1025 break;
1026
1027 case eInputReaderGotToken:
1028 write (driver->m_editline_pty.GetMasterFileDescriptor(), bytes, bytes_len);
1029 break;
1030
1031 case eInputReaderDone:
1032 break;
1033 }
1034 return bytes_len;
1035}
1036
1037void
1038Driver::MainLoop ()
1039{
1040 char error_str[1024];
1041 if (m_editline_pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY, error_str, sizeof(error_str)) == false)
1042 {
1043 ::fprintf (stderr, "error: failed to open driver pseudo terminal : %s", error_str);
1044 exit(1);
1045 }
1046 else
1047 {
1048 const char *driver_slave_name = m_editline_pty.GetSlaveName (error_str, sizeof(error_str));
1049 if (driver_slave_name == NULL)
1050 {
1051 ::fprintf (stderr, "error: failed to get slave name for driver pseudo terminal : %s", error_str);
1052 exit(2);
1053 }
1054 else
1055 {
1056 m_editline_slave_fh = ::fopen (driver_slave_name, "r+");
1057 if (m_editline_slave_fh == NULL)
1058 {
1059 SBError error;
1060 error.SetErrorToErrno();
1061 ::fprintf (stderr, "error: failed to get open slave for driver pseudo terminal : %s",
1062 error.GetCString());
1063 exit(3);
1064 }
1065
1066 ::setbuf (m_editline_slave_fh, NULL);
1067 }
1068 }
1069
1070
1071 // struct termios stdin_termios;
1072
1073 if (::tcgetattr(STDIN_FILENO, &g_old_stdin_termios) == 0)
1074 atexit (reset_stdin_termios);
1075
1076 ::setbuf (stdin, NULL);
1077 ::setbuf (stdout, NULL);
1078
1079 SBDebugger::SetErrorFileHandle (stderr, false);
1080 SBDebugger::SetOutputFileHandle (stdout, false);
1081 SBDebugger::SetInputFileHandle (stdin, true);
1082
1083 // You have to drain anything that comes to the master side of the PTY. master_out_comm is
1084 // for that purpose. The reason you need to do this is a curious reason... editline will echo
1085 // characters to the PTY when it gets characters while el_gets is not running, and then when
1086 // you call el_gets (or el_getc) it will try to reset the terminal back to raw mode which blocks
1087 // if there are unconsumed characters in the out buffer.
1088 // However, you don't need to do anything with the characters, since editline will dump these
1089 // unconsumed characters after printing the prompt again in el_gets.
1090
1091 SBCommunication master_out_comm("driver.editline");
1092 master_out_comm.AdoptFileDesriptor(m_editline_pty.GetMasterFileDescriptor(), false);
1093 master_out_comm.SetReadThreadBytesReceivedCallback(Driver::MasterThreadBytesReceived, this);
1094
1095 if (master_out_comm.ReadThreadStart () == false)
1096 {
1097 ::fprintf (stderr, "error: failed to start master out read thread");
1098 exit(5);
1099 }
1100
1101// const char *crash_log = GetCrashLogFilename();
1102// if (crash_log)
1103// {
1104// ParseCrashLog (crash_log);
1105// }
1106//
1107 SBCommandInterpreter sb_interpreter = SBDebugger::GetCommandInterpreter();
1108
1109 m_io_channel_ap.reset (new IOChannel(m_editline_slave_fh, stdout, stderr, this));
1110
1111 struct winsize window_size;
1112 if (isatty (STDIN_FILENO)
1113 && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0)
1114 {
1115 char buffer[25];
1116
1117 sprintf (buffer, "set term-width %d", window_size.ws_col);
1118 SBDebugger::HandleCommand ((const char *) buffer);
1119 }
1120
1121 // Since input can be redirected by the debugger, we must insert our editline
1122 // input reader in the queue so we know when our reader should be active
1123 // and so we can receive bytes only when we are supposed to.
1124 SBError err (m_editline_reader.Initialize (Driver::EditLineInputReaderCallback, // callback
1125 this, // baton
1126 eInputReaderGranularityByte, // token_size
1127 NULL, // end token - NULL means never done
1128 NULL, // prompt - taken care of elsewhere
1129 false)); // echo input - don't need Debugger
1130 // to do this, we handle it elsewhere
1131
1132 if (err.Fail())
1133 {
1134 ::fprintf (stderr, "error: %s", err.GetCString());
1135 exit (6);
1136 }
1137
1138 SBDebugger::PushInputReader (m_editline_reader);
1139
1140 SBListener listener(SBDebugger::GetListener());
1141 if (listener.IsValid())
1142 {
1143
1144 listener.StartListeningForEvents (*m_io_channel_ap,
1145 IOChannel::eBroadcastBitHasUserInput |
1146 IOChannel::eBroadcastBitUserInterrupt |
1147 IOChannel::eBroadcastBitThreadShouldExit |
1148 IOChannel::eBroadcastBitThreadDidStart |
1149 IOChannel::eBroadcastBitThreadDidExit);
1150
1151 if (m_io_channel_ap->Start ())
1152 {
1153 bool iochannel_thread_exited = false;
1154
1155 listener.StartListeningForEvents (sb_interpreter.GetBroadcaster(),
1156 SBCommandInterpreter::eBroadcastBitQuitCommandReceived);
1157
1158 // Before we handle any options from the command line, we parse the
1159 // .lldbinit file in the user's home directory.
1160 SBCommandReturnObject result;
1161 sb_interpreter.SourceInitFileInHomeDirectory(result);
1162 if (GetDebugMode())
1163 {
1164 result.PutError (SBDebugger::GetErrorFileHandle());
1165 result.PutOutput (SBDebugger::GetOutputFileHandle());
1166 }
1167
1168 // Now we handle options we got from the command line
1169 char command_string[PATH_MAX * 2];
1170 const size_t num_source_command_files = GetNumSourceCommandFiles();
1171 if (num_source_command_files > 0)
1172 {
1173 for (size_t i=0; i < num_source_command_files; ++i)
1174 {
1175 const char *command_file = GetSourceCommandFileAtIndex(i);
1176 ::snprintf (command_string, sizeof(command_string), "source '%s'", command_file);
1177 SBDebugger::GetCommandInterpreter().HandleCommand (command_string, result, false);
1178 if (GetDebugMode())
1179 {
1180 result.PutError (SBDebugger::GetErrorFileHandle());
1181 result.PutOutput (SBDebugger::GetOutputFileHandle());
1182 }
1183 }
1184 }
1185
1186 if (!m_option_data.m_filename.empty())
1187 {
1188 char arch_name[64];
1189 if (SBDebugger::GetDefaultArchitecture (arch_name, sizeof (arch_name)))
1190 ::snprintf (command_string, sizeof (command_string), "file --arch=%s '%s'", arch_name,
1191 m_option_data.m_filename.c_str());
1192 else
1193 ::snprintf (command_string, sizeof(command_string), "file '%s'", m_option_data.m_filename.c_str());
1194
1195 SBDebugger::HandleCommand (command_string);
1196 }
1197
1198 // Now that all option parsing is done, we try and parse the .lldbinit
1199 // file in the current working directory
1200 sb_interpreter.SourceInitFileInCurrentWorkingDirectory (result);
1201 if (GetDebugMode())
1202 {
1203 result.PutError(SBDebugger::GetErrorFileHandle());
1204 result.PutOutput(SBDebugger::GetOutputFileHandle());
1205 }
1206
1207 SBEvent event;
1208
1209 // Make sure the IO channel is started up before we try to tell it we
1210 // are ready for input
1211 listener.WaitForEventForBroadcasterWithType (UINT32_MAX,
1212 *m_io_channel_ap,
1213 IOChannel::eBroadcastBitThreadDidStart,
1214 event);
1215
1216 ReadyForCommand ();
1217
1218 bool done = false;
1219 while (!done)
1220 {
1221 listener.WaitForEvent (UINT32_MAX, event);
1222 if (event.IsValid())
1223 {
1224 if (event.GetBroadcaster().IsValid())
1225 {
1226 uint32_t event_type = event.GetType();
1227 if (event.BroadcasterMatchesRef (*m_io_channel_ap))
1228 {
1229 if ((event_type & IOChannel::eBroadcastBitThreadShouldExit) ||
1230 (event_type & IOChannel::eBroadcastBitThreadDidExit))
1231 {
1232 done = true;
1233 if (event_type & IOChannel::eBroadcastBitThreadDidExit)
1234 iochannel_thread_exited = true;
1235 break;
1236 }
1237 else
1238 done = HandleIOEvent (event);
1239 }
1240 else if (event.BroadcasterMatchesRef (SBDebugger::GetCurrentTarget().GetProcess().GetBroadcaster()))
1241 {
1242 HandleProcessEvent (event);
1243 }
1244 else if (event.BroadcasterMatchesRef (sb_interpreter.GetBroadcaster()))
1245 {
1246 if (event_type & SBCommandInterpreter::eBroadcastBitQuitCommandReceived)
1247 done = true;
1248 }
1249 }
1250 }
1251 }
1252
1253 reset_stdin_termios ();
1254
1255 CloseIOChannelFile ();
1256
1257 if (!iochannel_thread_exited)
1258 {
1259 SBEvent event;
1260 listener.GetNextEventForBroadcasterWithType (*m_io_channel_ap,
1261 IOChannel::eBroadcastBitThreadDidExit,
1262 event);
1263 if (!event.IsValid())
1264 {
1265 // Send end EOF to the driver file descriptor
1266 m_io_channel_ap->Stop();
1267 }
1268 }
1269
1270 SBProcess process = SBDebugger::GetCurrentTarget().GetProcess();
1271 if (process.IsValid())
1272 process.Destroy();
1273 }
1274 }
1275}
1276
1277
1278void
1279Driver::ReadyForCommand ()
1280{
1281 if (m_waiting_for_command == false)
1282 {
1283 m_waiting_for_command = true;
1284 BroadcastEventByType (Driver::eBroadcastBitReadyForInput, true);
1285 }
1286}
1287
1288
1289int
1290main (int argc, char const *argv[])
1291{
1292
1293 SBDebugger::Initialize();
1294
1295 SBHostOS::ThreadCreated ("[main]");
1296
1297 // Do a little setup on the debugger before we get going
1298 SBDebugger::SetAsync(true);
1299 Driver driver;
1300
1301 bool valid_args = driver.ParseArgs (argc, argv, stdout, stderr);
1302 if (valid_args)
1303 {
1304 driver.MainLoop ();
1305 }
1306
1307 SBDebugger::Terminate();
1308 return 0;
1309}