124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- Driver.cpp ----------------------------------------------*- C++ -*-===// 224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// The LLVM Compiler Infrastructure 424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This file is distributed under the University of Illinois Open Source 624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// License. See LICENSE.TXT for details. 724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===// 924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "Driver.h" 1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <getopt.h> 1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <libgen.h> 1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <sys/ioctl.h> 1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <termios.h> 1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <unistd.h> 17f2f321d826c21c674ca5787b18e8b3e0edaa214bEli Friedman#include <string.h> 18f2f321d826c21c674ca5787b18e8b3e0edaa214bEli Friedman#include <stdlib.h> 19f2f321d826c21c674ca5787b18e8b3e0edaa214bEli Friedman#include <limits.h> 20d6e167d0fe8666347554226424bb39e36686e0d6Eli Friedman#include <fcntl.h> 215f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea#include <inttypes.h> 2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <string> 2424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "IOChannel.h" 2628e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham#include "lldb/API/SBBreakpoint.h" 27f2f321d826c21c674ca5787b18e8b3e0edaa214bEli Friedman#include "lldb/API/SBCommandInterpreter.h" 28f2f321d826c21c674ca5787b18e8b3e0edaa214bEli Friedman#include "lldb/API/SBCommandReturnObject.h" 29f2f321d826c21c674ca5787b18e8b3e0edaa214bEli Friedman#include "lldb/API/SBCommunication.h" 30f2f321d826c21c674ca5787b18e8b3e0edaa214bEli Friedman#include "lldb/API/SBDebugger.h" 31f2f321d826c21c674ca5787b18e8b3e0edaa214bEli Friedman#include "lldb/API/SBEvent.h" 32f2f321d826c21c674ca5787b18e8b3e0edaa214bEli Friedman#include "lldb/API/SBHostOS.h" 33f2f321d826c21c674ca5787b18e8b3e0edaa214bEli Friedman#include "lldb/API/SBListener.h" 342e8cb8a7342a2ea672792067d712a794e215a3a7Jim Ingham#include "lldb/API/SBStream.h" 35f2f321d826c21c674ca5787b18e8b3e0edaa214bEli Friedman#include "lldb/API/SBTarget.h" 36f2f321d826c21c674ca5787b18e8b3e0edaa214bEli Friedman#include "lldb/API/SBThread.h" 37f2f321d826c21c674ca5787b18e8b3e0edaa214bEli Friedman#include "lldb/API/SBProcess.h" 3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb; 4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic void reset_stdin_termios (); 427cd8cd51421be28c7c615e141e87cf53bf2e21a0Greg Claytonstatic bool g_old_stdin_termios_is_valid = false; 4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic struct termios g_old_stdin_termios; 4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 45b8314fe67960cfcc5d9e9232be4c1914c9ef0ce3Caroline Ticestatic char *g_debugger_name = (char *) ""; 46c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Ticestatic Driver *g_driver = NULL; 47b8314fe67960cfcc5d9e9232be4c1914c9ef0ce3Caroline Tice 4824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// In the Driver::MainLoop, we change the terminal settings. This function is 4924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// added as an atexit handler to make sure we clean them up. 5024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic void 5124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerreset_stdin_termios () 5224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 537cd8cd51421be28c7c615e141e87cf53bf2e21a0Greg Clayton if (g_old_stdin_termios_is_valid) 547cd8cd51421be28c7c615e141e87cf53bf2e21a0Greg Clayton { 557cd8cd51421be28c7c615e141e87cf53bf2e21a0Greg Clayton g_old_stdin_termios_is_valid = false; 567cd8cd51421be28c7c615e141e87cf53bf2e21a0Greg Clayton ::tcsetattr (STDIN_FILENO, TCSANOW, &g_old_stdin_termios); 577cd8cd51421be28c7c615e141e87cf53bf2e21a0Greg Clayton } 5824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 5924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 60b344843f75ef893762c93fd0a22d2d45712ce74dGreg Claytontypedef struct 6124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 62b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton uint32_t usage_mask; // Used to mark options that can be used together. If (1 << n & usage_mask) != 0 63b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton // then this option belongs to option set n. 64b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton bool required; // This option is required (in the current usage level) 65b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton const char * long_option; // Full name for this option. 666475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton int short_option; // Single character for this option. 67b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton int option_has_arg; // no_argument, required_argument or optional_argument 685e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton uint32_t completion_type; // Cookie the option class can use to do define the argument completion. 69b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton lldb::CommandArgumentType argument_type; // Type of argument this option takes 70b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton const char * usage_text; // Full text explaining what this options does and what (if any) argument to 71b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton // pass it. 72b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton} OptionDefinition; 73b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton 7483dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham#define LLDB_3_TO_5 LLDB_OPT_SET_3|LLDB_OPT_SET_4|LLDB_OPT_SET_5 7583dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham#define LLDB_4_TO_5 LLDB_OPT_SET_4|LLDB_OPT_SET_5 7683dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham 77b344843f75ef893762c93fd0a22d2d45712ce74dGreg Claytonstatic OptionDefinition g_options[] = 78b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton{ 79f99355834bee84e48e2b6205ed13d307faa74405Filipe Cabecinhas { LLDB_OPT_SET_1, true , "help" , 'h', no_argument , 0, eArgTypeNone, 80dbcf98c194742f911c963854084c66aa49a5e513Jim Ingham "Prints out the usage information for the LLDB debugger." }, 81f99355834bee84e48e2b6205ed13d307faa74405Filipe Cabecinhas { LLDB_OPT_SET_2, true , "version" , 'v', no_argument , 0, eArgTypeNone, 82dbcf98c194742f911c963854084c66aa49a5e513Jim Ingham "Prints out the current version number of the LLDB debugger." }, 83f99355834bee84e48e2b6205ed13d307faa74405Filipe Cabecinhas { LLDB_OPT_SET_3, true , "arch" , 'a', required_argument, 0, eArgTypeArchitecture, 84dbcf98c194742f911c963854084c66aa49a5e513Jim Ingham "Tells the debugger to use the specified architecture when starting and running the program. <architecture> must " 85dbcf98c194742f911c963854084c66aa49a5e513Jim Ingham "be one of the architectures for which the program was compiled." }, 86f99355834bee84e48e2b6205ed13d307faa74405Filipe Cabecinhas { LLDB_OPT_SET_3, true , "file" , 'f', required_argument, 0, eArgTypeFilename, 87dbcf98c194742f911c963854084c66aa49a5e513Jim Ingham "Tells the debugger to use the file <filename> as the program to be debugged." }, 887b771d2bc07469dfad2828cfb0bbd21713304810Jason Molenda { LLDB_OPT_SET_3, false, "core" , 'c', required_argument, 0, eArgTypeFilename, 896c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen "Tells the debugger to use the fullpath to <path> as the core file." }, 90f99355834bee84e48e2b6205ed13d307faa74405Filipe Cabecinhas { LLDB_OPT_SET_4, true , "attach-name" , 'n', required_argument, 0, eArgTypeProcessName, 91dbcf98c194742f911c963854084c66aa49a5e513Jim Ingham "Tells the debugger to attach to a process with the given name." }, 92f99355834bee84e48e2b6205ed13d307faa74405Filipe Cabecinhas { LLDB_OPT_SET_4, true , "wait-for" , 'w', no_argument , 0, eArgTypeNone, 93dbcf98c194742f911c963854084c66aa49a5e513Jim Ingham "Tells the debugger to wait for a process with the given pid or name to launch before attaching." }, 94f99355834bee84e48e2b6205ed13d307faa74405Filipe Cabecinhas { LLDB_OPT_SET_5, true , "attach-pid" , 'p', required_argument, 0, eArgTypePid, 95dbcf98c194742f911c963854084c66aa49a5e513Jim Ingham "Tells the debugger to attach to a process with the given pid." }, 96f99355834bee84e48e2b6205ed13d307faa74405Filipe Cabecinhas { LLDB_3_TO_5, false, "script-language", 'l', required_argument, 0, eArgTypeScriptLang, 97dbcf98c194742f911c963854084c66aa49a5e513Jim Ingham "Tells the debugger to use the specified scripting language for user-defined scripts, rather than the default. " 98dbcf98c194742f911c963854084c66aa49a5e513Jim Ingham "Valid scripting languages that can be specified include Python, Perl, Ruby and Tcl. Currently only the Python " 99dbcf98c194742f911c963854084c66aa49a5e513Jim Ingham "extensions have been implemented." }, 100f99355834bee84e48e2b6205ed13d307faa74405Filipe Cabecinhas { LLDB_3_TO_5, false, "debug" , 'd', no_argument , 0, eArgTypeNone, 101dbcf98c194742f911c963854084c66aa49a5e513Jim Ingham "Tells the debugger to print out extra information for debugging itself." }, 102f99355834bee84e48e2b6205ed13d307faa74405Filipe Cabecinhas { LLDB_3_TO_5, false, "source" , 's', required_argument, 0, eArgTypeFilename, 103dbcf98c194742f911c963854084c66aa49a5e513Jim Ingham "Tells the debugger to read in and execute the file <file>, which should contain lldb commands." }, 104f99355834bee84e48e2b6205ed13d307faa74405Filipe Cabecinhas { LLDB_3_TO_5, false, "editor" , 'e', no_argument , 0, eArgTypeNone, 105dbcf98c194742f911c963854084c66aa49a5e513Jim Ingham "Tells the debugger to open source files using the host's \"external editor\" mechanism." }, 106f99355834bee84e48e2b6205ed13d307faa74405Filipe Cabecinhas { LLDB_3_TO_5, false, "no-lldbinit" , 'x', no_argument , 0, eArgTypeNone, 107dbcf98c194742f911c963854084c66aa49a5e513Jim Ingham "Do not automatically parse any '.lldbinit' files." }, 10817d5a0358d60922707fdab6ec9c3251ca44dd614Michael Sartain { LLDB_3_TO_5, false, "no-use-colors" , 'o', no_argument , 0, eArgTypeNone, 10917d5a0358d60922707fdab6ec9c3251ca44dd614Michael Sartain "Do not use colors." }, 11017d5a0358d60922707fdab6ec9c3251ca44dd614Michael Sartain { LLDB_OPT_SET_6, true , "python-path" , 'P', no_argument , 0, eArgTypeNone, 111aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham "Prints out the path to the lldb.py file for this version of lldb." }, 112f99355834bee84e48e2b6205ed13d307faa74405Filipe Cabecinhas { 0, false, NULL , 0 , 0 , 0, eArgTypeNone, NULL } 11324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}; 11424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 11583dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Inghamstatic const uint32_t last_option_set_with_args = 2; 11624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 11724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDriver::Driver () : 11824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SBBroadcaster ("Driver"), 119558dd5bc8b25722fa5b5106586b97ecf99e0026eJim Ingham m_debugger (SBDebugger::Create(false)), 12024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_editline_pty (), 12124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_editline_slave_fh (NULL), 12224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_editline_reader (), 12324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_io_channel_ap (), 12424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_option_data (), 1254084fe70b71aef8d9d90186f9f54cd8a4d4c6861Greg Clayton m_executing_user_command (false), 12609eb052b6340c2e0b7062cbba72f71db960c61caDaniel Malea m_waiting_for_command (false), 12709eb052b6340c2e0b7062cbba72f71db960c61caDaniel Malea m_done(false) 12824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 129421ca5014ea0e163998b9a8e0d777d3adb5c872eGreg Clayton // We want to be able to handle CTRL+D in the terminal to have it terminate 130421ca5014ea0e163998b9a8e0d777d3adb5c872eGreg Clayton // certain input 131421ca5014ea0e163998b9a8e0d777d3adb5c872eGreg Clayton m_debugger.SetCloseInputOnEOF (false); 132b8314fe67960cfcc5d9e9232be4c1914c9ef0ce3Caroline Tice g_debugger_name = (char *) m_debugger.GetInstanceName(); 133b8314fe67960cfcc5d9e9232be4c1914c9ef0ce3Caroline Tice if (g_debugger_name == NULL) 134b8314fe67960cfcc5d9e9232be4c1914c9ef0ce3Caroline Tice g_debugger_name = (char *) ""; 135c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice g_driver = this; 13624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 13724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 13824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDriver::~Driver () 13924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 140c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice g_driver = NULL; 141c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice g_debugger_name = NULL; 14224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 14324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 14424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 14524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDriver::CloseIOChannelFile () 14624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 1475d44dcc0f5558db037d13ebf4e772c9a8fb673cfJohnny Chen // Write an End of File sequence to the file descriptor to ensure any 14824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // read functions can exit. 14924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner char eof_str[] = "\x04"; 15024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::write (m_editline_pty.GetMasterFileDescriptor(), eof_str, strlen(eof_str)); 15124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 15224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_editline_pty.CloseMasterFileDescriptor(); 15324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 15424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (m_editline_slave_fh) 15524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 15624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::fclose (m_editline_slave_fh); 15724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_editline_slave_fh = NULL; 15824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 15924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 16024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 16154e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton// This function takes INDENT, which tells how many spaces to output at the front 16254e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton// of each line; TEXT, which is the text that is to be output. It outputs the 16354e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton// text, on multiple lines if necessary, to RESULT, with INDENT spaces at the 16454e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton// front of each line. It breaks lines on spaces, tabs or newlines, shortening 16554e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton// the line if necessary to not break in the middle of a word. It assumes that 16654e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton// each output line should contain a maximum of OUTPUT_MAX_COLUMNS characters. 16724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 16824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 16954e7afa84d945f9137f9372ecde432f9e1a702fcGreg ClaytonOutputFormattedUsageText (FILE *out, int indent, const char *text, int output_max_columns) 17024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 17124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner int len = strlen (text); 17224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner std::string text_string (text); 17324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 17424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Force indentation to be reasonable. 17524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (indent >= output_max_columns) 17624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner indent = 0; 17724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 17824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Will it all fit on one line? 17924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 18024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (len + indent < output_max_columns) 18124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Output as a single line 18254e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton fprintf (out, "%*s%s\n", indent, "", text); 18324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 18424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 18524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // We need to break it up into multiple lines. 18624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner int text_width = output_max_columns - indent - 1; 18724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner int start = 0; 18824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner int end = start; 18924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner int final_end = len; 19024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner int sub_len; 19124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 19224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner while (end < final_end) 19324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 19424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Dont start the 'text' on a space, since we're already outputting the indentation. 19524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner while ((start < final_end) && (text[start] == ' ')) 19624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner start++; 19724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 19824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner end = start + text_width; 19924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (end > final_end) 20024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner end = final_end; 20124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 20224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 20324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // If we're not at the end of the text, make sure we break the line on white space. 20424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner while (end > start 20524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner && text[end] != ' ' && text[end] != '\t' && text[end] != '\n') 20624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner end--; 20724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 20824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner sub_len = end - start; 20924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner std::string substring = text_string.substr (start, sub_len); 21054e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton fprintf (out, "%*s%s\n", indent, "", substring.c_str()); 21124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner start = end + 1; 21224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 21324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 21424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 21524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 21624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 217b344843f75ef893762c93fd0a22d2d45712ce74dGreg ClaytonShowUsage (FILE *out, OptionDefinition *option_table, Driver::OptionData data) 21824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 21924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t screen_width = 80; 22024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t indent_level = 0; 22124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const char *name = "lldb"; 22234e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham 22324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner fprintf (out, "\nUsage:\n\n"); 22424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 22524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner indent_level += 2; 22624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 22724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 22824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // First, show each usage level set of options, e.g. <cmd> [options-for-level-0] 22924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // <cmd> [options-for-level-1] 23024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // etc. 23124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 23224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t num_options; 23334e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham uint32_t num_option_sets = 0; 23434e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham 23534e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham for (num_options = 0; option_table[num_options].long_option != NULL; ++num_options) 23624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 23734e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham uint32_t this_usage_mask = option_table[num_options].usage_mask; 23834e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham if (this_usage_mask == LLDB_OPT_SET_ALL) 23924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 24034e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham if (num_option_sets == 0) 24134e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham num_option_sets = 1; 24224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 24334e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham else 24424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 24554e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton for (uint32_t j = 0; j < LLDB_MAX_NUM_OPTION_SETS; j++) 24634e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham { 24734e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham if (this_usage_mask & 1 << j) 24834e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham { 24934e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham if (num_option_sets <= j) 25034e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham num_option_sets = j + 1; 25134e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham } 25234e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham } 25324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 25434e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham } 25534e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham 25634e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham for (uint32_t opt_set = 0; opt_set < num_option_sets; opt_set++) 25734e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham { 25834e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham uint32_t opt_set_mask; 25934e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham 26034e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham opt_set_mask = 1 << opt_set; 26134e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham 26234e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham if (opt_set > 0) 26334e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham fprintf (out, "\n"); 26454e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton fprintf (out, "%*s%s", indent_level, "", name); 2656ae254432fed5ba37a8114e8a51702accaae5bb9Jim Ingham bool is_help_line = false; 26634e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham 26734e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham for (uint32_t i = 0; i < num_options; ++i) 26824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 26934e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham if (option_table[i].usage_mask & opt_set_mask) 27034e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham { 2714d6675c8e1cab6360f59865229835ae137d6f68aCaroline Tice CommandArgumentType arg_type = option_table[i].argument_type; 272aa378b1f53f8b557ceab403e31e6c9ef9a20b77dGreg Clayton const char *arg_name = SBCommandInterpreter::GetArgumentTypeAsCString (arg_type); 2736ae254432fed5ba37a8114e8a51702accaae5bb9Jim Ingham // This is a bit of a hack, but there's no way to say certain options don't have arguments yet... 2746ae254432fed5ba37a8114e8a51702accaae5bb9Jim Ingham // so we do it by hand here. 2756ae254432fed5ba37a8114e8a51702accaae5bb9Jim Ingham if (option_table[i].short_option == 'h') 2766ae254432fed5ba37a8114e8a51702accaae5bb9Jim Ingham is_help_line = true; 2776ae254432fed5ba37a8114e8a51702accaae5bb9Jim Ingham 27834e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham if (option_table[i].required) 27934e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham { 28034e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham if (option_table[i].option_has_arg == required_argument) 281aa378b1f53f8b557ceab403e31e6c9ef9a20b77dGreg Clayton fprintf (out, " -%c <%s>", option_table[i].short_option, arg_name); 28234e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham else if (option_table[i].option_has_arg == optional_argument) 283aa378b1f53f8b557ceab403e31e6c9ef9a20b77dGreg Clayton fprintf (out, " -%c [<%s>]", option_table[i].short_option, arg_name); 28434e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham else 28534e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham fprintf (out, " -%c", option_table[i].short_option); 28634e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham } 28734e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham else 28834e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham { 28934e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham if (option_table[i].option_has_arg == required_argument) 290aa378b1f53f8b557ceab403e31e6c9ef9a20b77dGreg Clayton fprintf (out, " [-%c <%s>]", option_table[i].short_option, arg_name); 29134e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham else if (option_table[i].option_has_arg == optional_argument) 292aa378b1f53f8b557ceab403e31e6c9ef9a20b77dGreg Clayton fprintf (out, " [-%c [<%s>]]", option_table[i].short_option, arg_name); 29334e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham else 29434e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham fprintf (out, " [-%c]", option_table[i].short_option); 29534e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham } 29634e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham } 29724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 29883dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham if (!is_help_line && (opt_set <= last_option_set_with_args)) 2996ae254432fed5ba37a8114e8a51702accaae5bb9Jim Ingham fprintf (out, " [[--] <PROGRAM-ARG-1> [<PROGRAM_ARG-2> ...]]"); 30024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 30124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 30224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner fprintf (out, "\n\n"); 30324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 30424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Now print out all the detailed information about the various options: long form, short form and help text: 30524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // -- long_name <argument> 30624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // - short <argument> 30724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // help text 30824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 30924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // This variable is used to keep track of which options' info we've printed out, because some options can be in 31024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // more than one usage level, but we only want to print the long form of its information once. 31124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 31224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Driver::OptionData::OptionSet options_seen; 31324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Driver::OptionData::OptionSet::iterator pos; 31424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 31524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner indent_level += 5; 31624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 31734e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham for (uint32_t i = 0; i < num_options; ++i) 31824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 31924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Only print this option if we haven't already seen it. 32024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner pos = options_seen.find (option_table[i].short_option); 32124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (pos == options_seen.end()) 32224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 3234d6675c8e1cab6360f59865229835ae137d6f68aCaroline Tice CommandArgumentType arg_type = option_table[i].argument_type; 324aa378b1f53f8b557ceab403e31e6c9ef9a20b77dGreg Clayton const char *arg_name = SBCommandInterpreter::GetArgumentTypeAsCString (arg_type); 3254d6675c8e1cab6360f59865229835ae137d6f68aCaroline Tice 32624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner options_seen.insert (option_table[i].short_option); 32754e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton fprintf (out, "%*s-%c ", indent_level, "", option_table[i].short_option); 3284d6675c8e1cab6360f59865229835ae137d6f68aCaroline Tice if (arg_type != eArgTypeNone) 329aa378b1f53f8b557ceab403e31e6c9ef9a20b77dGreg Clayton fprintf (out, "<%s>", arg_name); 33024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner fprintf (out, "\n"); 33154e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton fprintf (out, "%*s--%s ", indent_level, "", option_table[i].long_option); 3324d6675c8e1cab6360f59865229835ae137d6f68aCaroline Tice if (arg_type != eArgTypeNone) 333aa378b1f53f8b557ceab403e31e6c9ef9a20b77dGreg Clayton fprintf (out, "<%s>", arg_name); 33424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner fprintf (out, "\n"); 33524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner indent_level += 5; 33654e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton OutputFormattedUsageText (out, indent_level, option_table[i].usage_text, screen_width); 33724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner indent_level -= 5; 33824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner fprintf (out, "\n"); 33924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 34024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 34124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 34224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner indent_level -= 5; 34324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 344cf0de2677d7c01d9117c782f67b85fa29d115c2aJim Ingham fprintf (out, "\n%*s(If you don't provide -f then the first argument will be the file to be debugged" 345cf0de2677d7c01d9117c782f67b85fa29d115c2aJim Ingham "\n%*s so '%s -- <filename> [<ARG1> [<ARG2>]]' also works." 346cf0de2677d7c01d9117c782f67b85fa29d115c2aJim Ingham "\n%*s Remember to end the options with \"--\" if any of your arguments have a \"-\" in them.)\n\n", 347cf0de2677d7c01d9117c782f67b85fa29d115c2aJim Ingham indent_level, "", 348cf0de2677d7c01d9117c782f67b85fa29d115c2aJim Ingham indent_level, "", 349cf0de2677d7c01d9117c782f67b85fa29d115c2aJim Ingham name, 350cf0de2677d7c01d9117c782f67b85fa29d115c2aJim Ingham indent_level, ""); 35124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 35224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 35324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 354b344843f75ef893762c93fd0a22d2d45712ce74dGreg ClaytonBuildGetOptTable (OptionDefinition *expanded_option_table, std::vector<struct option> &getopt_table, 355bd5c63ef58a9ebed5b458ddbb77eb334b84787bdCaroline Tice uint32_t num_options) 35624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 35724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (num_options == 0) 35824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return; 35924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 36024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t i; 36124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t j; 36224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner std::bitset<256> option_seen; 36324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 364bd5c63ef58a9ebed5b458ddbb77eb334b84787bdCaroline Tice getopt_table.resize (num_options + 1); 365bd5c63ef58a9ebed5b458ddbb77eb334b84787bdCaroline Tice 36624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner for (i = 0, j = 0; i < num_options; ++i) 36754e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton { 36824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner char short_opt = expanded_option_table[i].short_option; 36954e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton 37024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (option_seen.test(short_opt) == false) 37154e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton { 372bd5c63ef58a9ebed5b458ddbb77eb334b84787bdCaroline Tice getopt_table[j].name = expanded_option_table[i].long_option; 373bd5c63ef58a9ebed5b458ddbb77eb334b84787bdCaroline Tice getopt_table[j].has_arg = expanded_option_table[i].option_has_arg; 374bd5c63ef58a9ebed5b458ddbb77eb334b84787bdCaroline Tice getopt_table[j].flag = NULL; 375bd5c63ef58a9ebed5b458ddbb77eb334b84787bdCaroline Tice getopt_table[j].val = expanded_option_table[i].short_option; 37624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner option_seen.set(short_opt); 37724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ++j; 37854e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton } 37954e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton } 38024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 381bd5c63ef58a9ebed5b458ddbb77eb334b84787bdCaroline Tice getopt_table[j].name = NULL; 382bd5c63ef58a9ebed5b458ddbb77eb334b84787bdCaroline Tice getopt_table[j].has_arg = 0; 383bd5c63ef58a9ebed5b458ddbb77eb334b84787bdCaroline Tice getopt_table[j].flag = NULL; 384bd5c63ef58a9ebed5b458ddbb77eb334b84787bdCaroline Tice getopt_table[j].val = 0; 38524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 38624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 38724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 38863094e0bb161580564954dee512955c1c79d3476Greg ClaytonDriver::OptionData::OptionData () : 3894dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton m_args(), 39063094e0bb161580564954dee512955c1c79d3476Greg Clayton m_script_lang (lldb::eScriptLanguageDefault), 3916c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen m_core_file (), 39254e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton m_crash_log (), 39363094e0bb161580564954dee512955c1c79d3476Greg Clayton m_source_command_files (), 39463094e0bb161580564954dee512955c1c79d3476Greg Clayton m_debug_mode (false), 39554e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton m_print_version (false), 396aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham m_print_python_path (false), 39763094e0bb161580564954dee512955c1c79d3476Greg Clayton m_print_help (false), 39883dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham m_wait_for(false), 39983dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham m_process_name(), 40083dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham m_process_pid(LLDB_INVALID_PROCESS_ID), 40197c8957257a3e0b3ce6f46f8e5a28c965e30f357Daniel Dunbar m_use_external_editor(false), 402dbeb3e1e038a75f00fd565203839020e1d00a7c6Stephen Wilson m_seen_options() 40363094e0bb161580564954dee512955c1c79d3476Greg Clayton{ 40463094e0bb161580564954dee512955c1c79d3476Greg Clayton} 40563094e0bb161580564954dee512955c1c79d3476Greg Clayton 40663094e0bb161580564954dee512955c1c79d3476Greg ClaytonDriver::OptionData::~OptionData () 40763094e0bb161580564954dee512955c1c79d3476Greg Clayton{ 40863094e0bb161580564954dee512955c1c79d3476Greg Clayton} 40963094e0bb161580564954dee512955c1c79d3476Greg Clayton 41063094e0bb161580564954dee512955c1c79d3476Greg Claytonvoid 41163094e0bb161580564954dee512955c1c79d3476Greg ClaytonDriver::OptionData::Clear () 41263094e0bb161580564954dee512955c1c79d3476Greg Clayton{ 4134dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton m_args.clear (); 41463094e0bb161580564954dee512955c1c79d3476Greg Clayton m_script_lang = lldb::eScriptLanguageDefault; 41563094e0bb161580564954dee512955c1c79d3476Greg Clayton m_source_command_files.clear (); 41663094e0bb161580564954dee512955c1c79d3476Greg Clayton m_debug_mode = false; 41763094e0bb161580564954dee512955c1c79d3476Greg Clayton m_print_help = false; 41863094e0bb161580564954dee512955c1c79d3476Greg Clayton m_print_version = false; 419aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham m_print_python_path = false; 42074989e88af7e04f3fe0bb3a800163113d7e0ca12Jim Ingham m_use_external_editor = false; 42183dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham m_wait_for = false; 42283dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham m_process_name.erase(); 42383dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham m_process_pid = LLDB_INVALID_PROCESS_ID; 42463094e0bb161580564954dee512955c1c79d3476Greg Clayton} 42563094e0bb161580564954dee512955c1c79d3476Greg Clayton 42663094e0bb161580564954dee512955c1c79d3476Greg Claytonvoid 42763094e0bb161580564954dee512955c1c79d3476Greg ClaytonDriver::ResetOptionValues () 42863094e0bb161580564954dee512955c1c79d3476Greg Clayton{ 42963094e0bb161580564954dee512955c1c79d3476Greg Clayton m_option_data.Clear (); 43063094e0bb161580564954dee512955c1c79d3476Greg Clayton} 43163094e0bb161580564954dee512955c1c79d3476Greg Clayton 43263094e0bb161580564954dee512955c1c79d3476Greg Claytonconst char * 43363094e0bb161580564954dee512955c1c79d3476Greg ClaytonDriver::GetFilename() const 43463094e0bb161580564954dee512955c1c79d3476Greg Clayton{ 4354dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton if (m_option_data.m_args.empty()) 43663094e0bb161580564954dee512955c1c79d3476Greg Clayton return NULL; 4374dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton return m_option_data.m_args.front().c_str(); 43863094e0bb161580564954dee512955c1c79d3476Greg Clayton} 43963094e0bb161580564954dee512955c1c79d3476Greg Clayton 44063094e0bb161580564954dee512955c1c79d3476Greg Claytonconst char * 44163094e0bb161580564954dee512955c1c79d3476Greg ClaytonDriver::GetCrashLogFilename() const 44263094e0bb161580564954dee512955c1c79d3476Greg Clayton{ 44363094e0bb161580564954dee512955c1c79d3476Greg Clayton if (m_option_data.m_crash_log.empty()) 44463094e0bb161580564954dee512955c1c79d3476Greg Clayton return NULL; 44563094e0bb161580564954dee512955c1c79d3476Greg Clayton return m_option_data.m_crash_log.c_str(); 44663094e0bb161580564954dee512955c1c79d3476Greg Clayton} 44763094e0bb161580564954dee512955c1c79d3476Greg Clayton 44863094e0bb161580564954dee512955c1c79d3476Greg Claytonlldb::ScriptLanguage 44963094e0bb161580564954dee512955c1c79d3476Greg ClaytonDriver::GetScriptLanguage() const 45063094e0bb161580564954dee512955c1c79d3476Greg Clayton{ 45163094e0bb161580564954dee512955c1c79d3476Greg Clayton return m_option_data.m_script_lang; 45263094e0bb161580564954dee512955c1c79d3476Greg Clayton} 45363094e0bb161580564954dee512955c1c79d3476Greg Clayton 45463094e0bb161580564954dee512955c1c79d3476Greg Claytonsize_t 45563094e0bb161580564954dee512955c1c79d3476Greg ClaytonDriver::GetNumSourceCommandFiles () const 45663094e0bb161580564954dee512955c1c79d3476Greg Clayton{ 45763094e0bb161580564954dee512955c1c79d3476Greg Clayton return m_option_data.m_source_command_files.size(); 45863094e0bb161580564954dee512955c1c79d3476Greg Clayton} 45963094e0bb161580564954dee512955c1c79d3476Greg Clayton 46063094e0bb161580564954dee512955c1c79d3476Greg Claytonconst char * 46163094e0bb161580564954dee512955c1c79d3476Greg ClaytonDriver::GetSourceCommandFileAtIndex (uint32_t idx) const 46263094e0bb161580564954dee512955c1c79d3476Greg Clayton{ 46363094e0bb161580564954dee512955c1c79d3476Greg Clayton if (idx < m_option_data.m_source_command_files.size()) 46463094e0bb161580564954dee512955c1c79d3476Greg Clayton return m_option_data.m_source_command_files[idx].c_str(); 46563094e0bb161580564954dee512955c1c79d3476Greg Clayton return NULL; 46663094e0bb161580564954dee512955c1c79d3476Greg Clayton} 46763094e0bb161580564954dee512955c1c79d3476Greg Clayton 46863094e0bb161580564954dee512955c1c79d3476Greg Claytonbool 46963094e0bb161580564954dee512955c1c79d3476Greg ClaytonDriver::GetDebugMode() const 47063094e0bb161580564954dee512955c1c79d3476Greg Clayton{ 47163094e0bb161580564954dee512955c1c79d3476Greg Clayton return m_option_data.m_debug_mode; 47263094e0bb161580564954dee512955c1c79d3476Greg Clayton} 47363094e0bb161580564954dee512955c1c79d3476Greg Clayton 47463094e0bb161580564954dee512955c1c79d3476Greg Clayton 47563094e0bb161580564954dee512955c1c79d3476Greg Clayton// Check the arguments that were passed to this program to make sure they are valid and to get their 47663094e0bb161580564954dee512955c1c79d3476Greg Clayton// argument values (if any). Return a boolean value indicating whether or not to start up the full 47763094e0bb161580564954dee512955c1c79d3476Greg Clayton// debugger (i.e. the Command Interpreter) or not. Return FALSE if the arguments were invalid OR 47863094e0bb161580564954dee512955c1c79d3476Greg Clayton// if the user only wanted help or version information. 47963094e0bb161580564954dee512955c1c79d3476Greg Clayton 48024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerSBError 48163094e0bb161580564954dee512955c1c79d3476Greg ClaytonDriver::ParseArgs (int argc, const char *argv[], FILE *out_fh, bool &exit) 48224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 48363094e0bb161580564954dee512955c1c79d3476Greg Clayton ResetOptionValues (); 48463094e0bb161580564954dee512955c1c79d3476Greg Clayton 48563094e0bb161580564954dee512955c1c79d3476Greg Clayton SBCommandReturnObject result; 48663094e0bb161580564954dee512955c1c79d3476Greg Clayton 48724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SBError error; 48824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner std::string option_string; 48924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner struct option *long_options = NULL; 490bd5c63ef58a9ebed5b458ddbb77eb334b84787bdCaroline Tice std::vector<struct option> long_options_vector; 49154e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton uint32_t num_options; 49224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 49354e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton for (num_options = 0; g_options[num_options].long_option != NULL; ++num_options) 49454e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton /* Do Nothing. */; 49524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 49624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (num_options == 0) 49724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 49824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (argc > 1) 49924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner error.SetErrorStringWithFormat ("invalid number of options"); 50024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return error; 50124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 50224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 503bd5c63ef58a9ebed5b458ddbb77eb334b84787bdCaroline Tice BuildGetOptTable (g_options, long_options_vector, num_options); 50424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 505bd5c63ef58a9ebed5b458ddbb77eb334b84787bdCaroline Tice if (long_options_vector.empty()) 506bd5c63ef58a9ebed5b458ddbb77eb334b84787bdCaroline Tice long_options = NULL; 507bd5c63ef58a9ebed5b458ddbb77eb334b84787bdCaroline Tice else 508bd5c63ef58a9ebed5b458ddbb77eb334b84787bdCaroline Tice long_options = &long_options_vector.front(); 50924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 51024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (long_options == NULL) 51124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 51224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner error.SetErrorStringWithFormat ("invalid long options"); 51324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return error; 51424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 51524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 5163f2f741bb533b78e2fac5332c4698338ea2fd3acGreg Clayton // Build the option_string argument for call to getopt_long_only. 51724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 51824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner for (int i = 0; long_options[i].name != NULL; ++i) 51924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 52024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (long_options[i].flag == NULL) 52124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 52224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner option_string.push_back ((char) long_options[i].val); 52324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner switch (long_options[i].has_arg) 52424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 52524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner default: 52624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case no_argument: 52724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 52824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case required_argument: 52924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner option_string.push_back (':'); 53024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 53124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case optional_argument: 53224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner option_string.append ("::"); 53324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 53424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 53524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 53624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 53724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 538558dd5bc8b25722fa5b5106586b97ecf99e0026eJim Ingham // This is kind of a pain, but since we make the debugger in the Driver's constructor, we can't 539558dd5bc8b25722fa5b5106586b97ecf99e0026eJim Ingham // know at that point whether we should read in init files yet. So we don't read them in in the 540558dd5bc8b25722fa5b5106586b97ecf99e0026eJim Ingham // Driver constructor, then set the flags back to "read them in" here, and then if we see the 541558dd5bc8b25722fa5b5106586b97ecf99e0026eJim Ingham // "-n" flag, we'll turn it off again. Finally we have to read them in by hand later in the 542558dd5bc8b25722fa5b5106586b97ecf99e0026eJim Ingham // main loop. 543558dd5bc8b25722fa5b5106586b97ecf99e0026eJim Ingham 544558dd5bc8b25722fa5b5106586b97ecf99e0026eJim Ingham m_debugger.SkipLLDBInitFiles (false); 545558dd5bc8b25722fa5b5106586b97ecf99e0026eJim Ingham m_debugger.SkipAppInitFiles (false); 546558dd5bc8b25722fa5b5106586b97ecf99e0026eJim Ingham 5473f2f741bb533b78e2fac5332c4698338ea2fd3acGreg Clayton // Prepare for & make calls to getopt_long_only. 548ef2bc8787c6b12bd69dc45dd38ab2f1eb2673778Eli Friedman#if __GLIBC__ 549ef2bc8787c6b12bd69dc45dd38ab2f1eb2673778Eli Friedman optind = 0; 550ef2bc8787c6b12bd69dc45dd38ab2f1eb2673778Eli Friedman#else 55124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner optreset = 1; 55224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner optind = 1; 553ef2bc8787c6b12bd69dc45dd38ab2f1eb2673778Eli Friedman#endif 55424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner int val; 55524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner while (1) 55624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 55724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner int long_options_index = -1; 5583f2f741bb533b78e2fac5332c4698338ea2fd3acGreg Clayton val = ::getopt_long_only (argc, const_cast<char **>(argv), option_string.c_str(), long_options, &long_options_index); 55924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 56024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (val == -1) 56124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 56224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else if (val == '?') 56324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 56463094e0bb161580564954dee512955c1c79d3476Greg Clayton m_option_data.m_print_help = true; 56524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner error.SetErrorStringWithFormat ("unknown or ambiguous option"); 56624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 56724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 56824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else if (val == 0) 56924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner continue; 57024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 57124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 57263094e0bb161580564954dee512955c1c79d3476Greg Clayton m_option_data.m_seen_options.insert ((char) val); 57324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (long_options_index == -1) 57424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 57524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner for (int i = 0; 57624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner long_options[i].name || long_options[i].has_arg || long_options[i].flag || long_options[i].val; 57724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ++i) 57824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 57924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (long_options[i].val == val) 58024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 58124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner long_options_index = i; 58224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 58324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 58424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 58524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 58624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 58724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (long_options_index >= 0) 58824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 5896475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton const int short_option = g_options[long_options_index].short_option; 59024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 59163094e0bb161580564954dee512955c1c79d3476Greg Clayton switch (short_option) 59263094e0bb161580564954dee512955c1c79d3476Greg Clayton { 59363094e0bb161580564954dee512955c1c79d3476Greg Clayton case 'h': 59463094e0bb161580564954dee512955c1c79d3476Greg Clayton m_option_data.m_print_help = true; 59563094e0bb161580564954dee512955c1c79d3476Greg Clayton break; 59624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 59763094e0bb161580564954dee512955c1c79d3476Greg Clayton case 'v': 59863094e0bb161580564954dee512955c1c79d3476Greg Clayton m_option_data.m_print_version = true; 59963094e0bb161580564954dee512955c1c79d3476Greg Clayton break; 60024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 601aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham case 'P': 602aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham m_option_data.m_print_python_path = true; 603aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham break; 604aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham 60563094e0bb161580564954dee512955c1c79d3476Greg Clayton case 'c': 6066c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen { 6076c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen SBFileSpec file(optarg); 6086c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen if (file.Exists()) 6096c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen { 6106c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen m_option_data.m_core_file = optarg; 6116c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen } 6126c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen else 6136c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen error.SetErrorStringWithFormat("file specified in --core (-c) option doesn't exist: '%s'", optarg); 6146c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen } 61563094e0bb161580564954dee512955c1c79d3476Greg Clayton break; 6166c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen 61774989e88af7e04f3fe0bb3a800163113d7e0ca12Jim Ingham case 'e': 61874989e88af7e04f3fe0bb3a800163113d7e0ca12Jim Ingham m_option_data.m_use_external_editor = true; 61974989e88af7e04f3fe0bb3a800163113d7e0ca12Jim Ingham break; 620887aa2898314218406275a34cbec30c11cd00acdGreg Clayton 62183dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham case 'x': 622887aa2898314218406275a34cbec30c11cd00acdGreg Clayton m_debugger.SkipLLDBInitFiles (true); 623558dd5bc8b25722fa5b5106586b97ecf99e0026eJim Ingham m_debugger.SkipAppInitFiles (true); 624887aa2898314218406275a34cbec30c11cd00acdGreg Clayton break; 625887aa2898314218406275a34cbec30c11cd00acdGreg Clayton 62617d5a0358d60922707fdab6ec9c3251ca44dd614Michael Sartain case 'o': 62717d5a0358d60922707fdab6ec9c3251ca44dd614Michael Sartain m_debugger.SetUseColor (false); 62817d5a0358d60922707fdab6ec9c3251ca44dd614Michael Sartain break; 62917d5a0358d60922707fdab6ec9c3251ca44dd614Michael Sartain 63063094e0bb161580564954dee512955c1c79d3476Greg Clayton case 'f': 63163094e0bb161580564954dee512955c1c79d3476Greg Clayton { 63263094e0bb161580564954dee512955c1c79d3476Greg Clayton SBFileSpec file(optarg); 63363094e0bb161580564954dee512955c1c79d3476Greg Clayton if (file.Exists()) 6344dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton { 6354dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton m_option_data.m_args.push_back (optarg); 6364dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton } 637eddffe93d2c9ebb575e7b03fe1c5e71f9ecaf9f1Caroline Tice else if (file.ResolveExecutableLocation()) 638eddffe93d2c9ebb575e7b03fe1c5e71f9ecaf9f1Caroline Tice { 639eddffe93d2c9ebb575e7b03fe1c5e71f9ecaf9f1Caroline Tice char path[PATH_MAX]; 640ee6e790171b9a04023d0ea22603f0ac0ecb9a2c6Johnny Chen file.GetPath (path, sizeof(path)); 6414dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton m_option_data.m_args.push_back (path); 642eddffe93d2c9ebb575e7b03fe1c5e71f9ecaf9f1Caroline Tice } 64363094e0bb161580564954dee512955c1c79d3476Greg Clayton else 64463094e0bb161580564954dee512955c1c79d3476Greg Clayton error.SetErrorStringWithFormat("file specified in --file (-f) option doesn't exist: '%s'", optarg); 64563094e0bb161580564954dee512955c1c79d3476Greg Clayton } 64663094e0bb161580564954dee512955c1c79d3476Greg Clayton break; 64724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 64863094e0bb161580564954dee512955c1c79d3476Greg Clayton case 'a': 64963094e0bb161580564954dee512955c1c79d3476Greg Clayton if (!m_debugger.SetDefaultArchitecture (optarg)) 65063094e0bb161580564954dee512955c1c79d3476Greg Clayton error.SetErrorStringWithFormat("invalid architecture in the -a or --arch option: '%s'", optarg); 65163094e0bb161580564954dee512955c1c79d3476Greg Clayton break; 65224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 65363094e0bb161580564954dee512955c1c79d3476Greg Clayton case 'l': 65463094e0bb161580564954dee512955c1c79d3476Greg Clayton m_option_data.m_script_lang = m_debugger.GetScriptingLanguage (optarg); 65563094e0bb161580564954dee512955c1c79d3476Greg Clayton break; 65624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 65763094e0bb161580564954dee512955c1c79d3476Greg Clayton case 'd': 65863094e0bb161580564954dee512955c1c79d3476Greg Clayton m_option_data.m_debug_mode = true; 65963094e0bb161580564954dee512955c1c79d3476Greg Clayton break; 66024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 66183dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham case 'n': 66283dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham m_option_data.m_process_name = optarg; 66383dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham break; 66483dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham 66583dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham case 'w': 66683dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham m_option_data.m_wait_for = true; 66783dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham break; 66883dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham 66983dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham case 'p': 67083dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham { 67183dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham char *remainder; 67283dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham m_option_data.m_process_pid = strtol (optarg, &remainder, 0); 67383dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham if (remainder == optarg || *remainder != '\0') 67483dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham error.SetErrorStringWithFormat ("Could not convert process PID: \"%s\" into a pid.", 67583dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham optarg); 67683dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham } 67783dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham break; 67863094e0bb161580564954dee512955c1c79d3476Greg Clayton case 's': 67963094e0bb161580564954dee512955c1c79d3476Greg Clayton { 68063094e0bb161580564954dee512955c1c79d3476Greg Clayton SBFileSpec file(optarg); 68163094e0bb161580564954dee512955c1c79d3476Greg Clayton if (file.Exists()) 68263094e0bb161580564954dee512955c1c79d3476Greg Clayton m_option_data.m_source_command_files.push_back (optarg); 683eddffe93d2c9ebb575e7b03fe1c5e71f9ecaf9f1Caroline Tice else if (file.ResolveExecutableLocation()) 684eddffe93d2c9ebb575e7b03fe1c5e71f9ecaf9f1Caroline Tice { 685eddffe93d2c9ebb575e7b03fe1c5e71f9ecaf9f1Caroline Tice char final_path[PATH_MAX]; 686ee6e790171b9a04023d0ea22603f0ac0ecb9a2c6Johnny Chen file.GetPath (final_path, sizeof(final_path)); 687eddffe93d2c9ebb575e7b03fe1c5e71f9ecaf9f1Caroline Tice std::string path_str (final_path); 688eddffe93d2c9ebb575e7b03fe1c5e71f9ecaf9f1Caroline Tice m_option_data.m_source_command_files.push_back (path_str); 689eddffe93d2c9ebb575e7b03fe1c5e71f9ecaf9f1Caroline Tice } 69063094e0bb161580564954dee512955c1c79d3476Greg Clayton else 69163094e0bb161580564954dee512955c1c79d3476Greg Clayton error.SetErrorStringWithFormat("file specified in --source (-s) option doesn't exist: '%s'", optarg); 69263094e0bb161580564954dee512955c1c79d3476Greg Clayton } 69363094e0bb161580564954dee512955c1c79d3476Greg Clayton break; 69424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 69563094e0bb161580564954dee512955c1c79d3476Greg Clayton default: 69663094e0bb161580564954dee512955c1c79d3476Greg Clayton m_option_data.m_print_help = true; 69763094e0bb161580564954dee512955c1c79d3476Greg Clayton error.SetErrorStringWithFormat ("unrecognized option %c", short_option); 69863094e0bb161580564954dee512955c1c79d3476Greg Clayton break; 69963094e0bb161580564954dee512955c1c79d3476Greg Clayton } 70024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 70163094e0bb161580564954dee512955c1c79d3476Greg Clayton else 70224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 70363094e0bb161580564954dee512955c1c79d3476Greg Clayton error.SetErrorStringWithFormat ("invalid option with value %i", val); 70424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 70563094e0bb161580564954dee512955c1c79d3476Greg Clayton if (error.Fail()) 706bd5c63ef58a9ebed5b458ddbb77eb334b84787bdCaroline Tice { 70763094e0bb161580564954dee512955c1c79d3476Greg Clayton return error; 708bd5c63ef58a9ebed5b458ddbb77eb334b84787bdCaroline Tice } 70963094e0bb161580564954dee512955c1c79d3476Greg Clayton } 71024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 71134e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham 71263094e0bb161580564954dee512955c1c79d3476Greg Clayton if (error.Fail() || m_option_data.m_print_help) 71324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 71424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ShowUsage (out_fh, g_options, m_option_data); 7159caa94672c3a70e76316edfd29fa52d4a1ff6729Greg Clayton exit = true; 71624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 71724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else if (m_option_data.m_print_version) 71824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 71963094e0bb161580564954dee512955c1c79d3476Greg Clayton ::fprintf (out_fh, "%s\n", m_debugger.GetVersionString()); 72063094e0bb161580564954dee512955c1c79d3476Greg Clayton exit = true; 72124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 722aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham else if (m_option_data.m_print_python_path) 723aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham { 724aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham SBFileSpec python_file_spec = SBHostOS::GetLLDBPythonPath(); 725aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham if (python_file_spec.IsValid()) 726aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham { 727aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham char python_path[PATH_MAX]; 728aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham size_t num_chars = python_file_spec.GetPath(python_path, PATH_MAX); 729aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham if (num_chars < PATH_MAX) 730aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham { 731aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham ::fprintf (out_fh, "%s\n", python_path); 732aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham } 733aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham else 734aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham ::fprintf (out_fh, "<PATH TOO LONG>\n"); 735aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham } 736aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham else 737aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham ::fprintf (out_fh, "<COULD NOT FIND PATH>\n"); 738aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham exit = true; 739aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham } 74083dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham else if (m_option_data.m_process_name.empty() && m_option_data.m_process_pid == LLDB_INVALID_PROCESS_ID) 74124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 7424dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton // Any arguments that are left over after option parsing are for 7434dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton // the program. If a file was specified with -f then the filename 7444dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton // is already in the m_option_data.m_args array, and any remaining args 7454dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton // are arguments for the inferior program. If no file was specified with 7464dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton // -f, then what is left is the program name followed by any arguments. 7474dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton 7483f2f741bb533b78e2fac5332c4698338ea2fd3acGreg Clayton // Skip any options we consumed with getopt_long_only 7494dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton argc -= optind; 7504dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton argv += optind; 7514dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton 7524dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton if (argc > 0) 7534dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton { 7544dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton for (int arg_idx=0; arg_idx<argc; ++arg_idx) 7554dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton { 7564dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton const char *arg = argv[arg_idx]; 7574dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton if (arg) 7584dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton m_option_data.m_args.push_back (arg); 7594dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton } 7604dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton } 7614dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton 76224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 76383dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham else 76483dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham { 7653f2f741bb533b78e2fac5332c4698338ea2fd3acGreg Clayton // Skip any options we consumed with getopt_long_only 76683dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham argc -= optind; 7674a379b1194f3e6b308cd6e80b45d6ca5dd0aafd7Greg Clayton //argv += optind; // Commented out to keep static analyzer happy 76883dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham 76983dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham if (argc > 0) 77083dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham ::fprintf (out_fh, "Warning: program arguments are ignored when attaching.\n"); 77183dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham } 77224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 77363094e0bb161580564954dee512955c1c79d3476Greg Clayton return error; 77424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 77524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 776757500e29b7856823f2f4aedd30f206ec009147eCaroline Ticesize_t 77724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDriver::GetProcessSTDOUT () 77824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 77924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // The process has stuff waiting for stdout; get it and write it out to the appropriate place. 78024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner char stdio_buffer[1024]; 78124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner size_t len; 782757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice size_t total_bytes = 0; 783c833295baeec641086f536e78050388af36784f8Jim Ingham while ((len = m_debugger.GetSelectedTarget().GetProcess().GetSTDOUT (stdio_buffer, sizeof (stdio_buffer))) > 0) 784757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice { 7854084fe70b71aef8d9d90186f9f54cd8a4d4c6861Greg Clayton m_io_channel_ap->OutWrite (stdio_buffer, len, NO_ASYNC); 786757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice total_bytes += len; 787757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice } 788757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice return total_bytes; 78924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 79024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 791757500e29b7856823f2f4aedd30f206ec009147eCaroline Ticesize_t 79224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDriver::GetProcessSTDERR () 79324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 79424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // The process has stuff waiting for stderr; get it and write it out to the appropriate place. 79524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner char stdio_buffer[1024]; 79624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner size_t len; 797757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice size_t total_bytes = 0; 798c833295baeec641086f536e78050388af36784f8Jim Ingham while ((len = m_debugger.GetSelectedTarget().GetProcess().GetSTDERR (stdio_buffer, sizeof (stdio_buffer))) > 0) 799757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice { 8004084fe70b71aef8d9d90186f9f54cd8a4d4c6861Greg Clayton m_io_channel_ap->ErrWrite (stdio_buffer, len, NO_ASYNC); 801757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice total_bytes += len; 802757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice } 803757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice return total_bytes; 80424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 80524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 80624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 807c833295baeec641086f536e78050388af36784f8Jim InghamDriver::UpdateSelectedThread () 80824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 80924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner using namespace lldb; 810c833295baeec641086f536e78050388af36784f8Jim Ingham SBProcess process(m_debugger.GetSelectedTarget().GetProcess()); 81124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (process.IsValid()) 81224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 813c833295baeec641086f536e78050388af36784f8Jim Ingham SBThread curr_thread (process.GetSelectedThread()); 81424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SBThread thread; 81524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner StopReason curr_thread_stop_reason = eStopReasonInvalid; 81624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner curr_thread_stop_reason = curr_thread.GetStopReason(); 81724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 81824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (!curr_thread.IsValid() || 81924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner curr_thread_stop_reason == eStopReasonInvalid || 82024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner curr_thread_stop_reason == eStopReasonNone) 82124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 82224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Prefer a thread that has just completed its plan over another thread as current thread. 82324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SBThread plan_thread; 82424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SBThread other_thread; 82524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const size_t num_threads = process.GetNumThreads(); 82624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner size_t i; 82724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner for (i = 0; i < num_threads; ++i) 82824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 82924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner thread = process.GetThreadAtIndex(i); 83024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner StopReason thread_stop_reason = thread.GetStopReason(); 83124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner switch (thread_stop_reason) 83224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 83324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case eStopReasonInvalid: 83424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case eStopReasonNone: 83524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 83624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 83724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case eStopReasonTrace: 83824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case eStopReasonBreakpoint: 83924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case eStopReasonWatchpoint: 84024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case eStopReasonSignal: 84124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case eStopReasonException: 8420bce9a22354df3f00e68ffd912119a0741753b7fGreg Clayton case eStopReasonExec: 843278f16e1dd4097bf3dd12b0f63f1fac0f11c4006Andrew Kaylor case eStopReasonThreadExiting: 84424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (!other_thread.IsValid()) 84524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner other_thread = thread; 84624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 84724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case eStopReasonPlanComplete: 84824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (!plan_thread.IsValid()) 84924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner plan_thread = thread; 85024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 85124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 85224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 85324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (plan_thread.IsValid()) 854c833295baeec641086f536e78050388af36784f8Jim Ingham process.SetSelectedThread (plan_thread); 85524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else if (other_thread.IsValid()) 856c833295baeec641086f536e78050388af36784f8Jim Ingham process.SetSelectedThread (other_thread); 85724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 85824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 85924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (curr_thread.IsValid()) 86024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner thread = curr_thread; 86124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 86224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner thread = process.GetThreadAtIndex(0); 86324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 86424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (thread.IsValid()) 865c833295baeec641086f536e78050388af36784f8Jim Ingham process.SetSelectedThread (thread); 86624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 86724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 86824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 86924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 87024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 87128e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham// This function handles events that were broadcast by the process. 87228e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Inghamvoid 87328e23861bedbeb5e46be7d2af4c33bf5132422c6Jim InghamDriver::HandleBreakpointEvent (const SBEvent &event) 87428e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham{ 87528e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham using namespace lldb; 87628e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham const uint32_t event_type = SBBreakpoint::GetBreakpointEventTypeFromEvent (event); 87728e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham 87828e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham if (event_type & eBreakpointEventTypeAdded 87928e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham || event_type & eBreakpointEventTypeRemoved 88028e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham || event_type & eBreakpointEventTypeEnabled 88128e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham || event_type & eBreakpointEventTypeDisabled 88228e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham || event_type & eBreakpointEventTypeCommandChanged 88328e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham || event_type & eBreakpointEventTypeConditionChanged 88428e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham || event_type & eBreakpointEventTypeIgnoreChanged 88528e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham || event_type & eBreakpointEventTypeLocationsResolved) 88628e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham { 88728e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham // Don't do anything about these events, since the breakpoint commands already echo these actions. 88828e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham } 88928e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham else if (event_type & eBreakpointEventTypeLocationsAdded) 89028e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham { 89128e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham char message[256]; 89228e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham uint32_t num_new_locations = SBBreakpoint::GetNumBreakpointLocationsFromEvent(event); 89328e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham if (num_new_locations > 0) 89428e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham { 89528e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham SBBreakpoint breakpoint = SBBreakpoint::GetBreakpointFromEvent(event); 8964722b10307668368bf0f12fa6b8691e4f4cb5488Jim Ingham int message_len = ::snprintf (message, sizeof(message), "%d location%s added to breakpoint %d\n", 89728e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham num_new_locations, 89831f175eacd5b7bd82694726c22464d6e4a84d1d5Jason Molenda num_new_locations == 1 ? "" : "s", 89928e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham breakpoint.GetID()); 90028e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham m_io_channel_ap->OutWrite(message, message_len, ASYNC); 90128e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham } 90228e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham } 90328e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham else if (event_type & eBreakpointEventTypeLocationsRemoved) 90428e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham { 90528e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham // These locations just get disabled, not sure it is worth spamming folks about this on the command line. 90628e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham } 90728e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham else if (event_type & eBreakpointEventTypeLocationsResolved) 90828e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham { 90928e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham // This might be an interesting thing to note, but I'm going to leave it quiet for now, it just looked noisy. 91028e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham } 91128e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham} 91224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 91324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This function handles events that were broadcast by the process. 91424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 91524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDriver::HandleProcessEvent (const SBEvent &event) 91624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 91724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner using namespace lldb; 91824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const uint32_t event_type = event.GetType(); 91924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 92024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (event_type & SBProcess::eBroadcastBitSTDOUT) 92124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 92224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // The process has stdout available, get it and write it out to the 92324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // appropriate place. 9244a348081030cdd2af758fddc869518357d9befd3Caroline Tice GetProcessSTDOUT (); 92524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 92624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else if (event_type & SBProcess::eBroadcastBitSTDERR) 92724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 92824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // The process has stderr available, get it and write it out to the 92924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // appropriate place. 9304a348081030cdd2af758fddc869518357d9befd3Caroline Tice GetProcessSTDERR (); 93124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 93224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else if (event_type & SBProcess::eBroadcastBitStateChanged) 93324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 93424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Drain all stout and stderr so we don't see any output come after 93524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // we print our prompts 9364a348081030cdd2af758fddc869518357d9befd3Caroline Tice GetProcessSTDOUT (); 9374a348081030cdd2af758fddc869518357d9befd3Caroline Tice GetProcessSTDERR (); 93824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Something changed in the process; get the event and report the process's current status and location to 93924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // the user. 94024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner StateType event_state = SBProcess::GetStateFromEvent (event); 94124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (event_state == eStateInvalid) 94224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return; 94324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 94424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SBProcess process (SBProcess::GetProcessFromEvent (event)); 94524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner assert (process.IsValid()); 94624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 94724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner switch (event_state) 94824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 94924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case eStateInvalid: 95024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case eStateUnloaded: 951e71e258286a1713dbb2d366d8b81ff2f28e0216fGreg Clayton case eStateConnected: 95224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case eStateAttaching: 95324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case eStateLaunching: 95424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case eStateStepping: 95524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case eStateDetached: 95624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 95724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner char message[1024]; 9585f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea int message_len = ::snprintf (message, sizeof(message), "Process %" PRIu64 " %s\n", process.GetProcessID(), 95963094e0bb161580564954dee512955c1c79d3476Greg Clayton m_debugger.StateAsCString (event_state)); 9604a348081030cdd2af758fddc869518357d9befd3Caroline Tice m_io_channel_ap->OutWrite(message, message_len, ASYNC); 96124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 96224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 96324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 96424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case eStateRunning: 96524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Don't be chatty when we run... 96624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 96724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 96824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case eStateExited: 969757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice { 970757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice SBCommandReturnObject result; 971757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice m_debugger.GetCommandInterpreter().HandleCommand("process status", result, false); 9724a348081030cdd2af758fddc869518357d9befd3Caroline Tice m_io_channel_ap->ErrWrite (result.GetError(), result.GetErrorSize(), ASYNC); 9734a348081030cdd2af758fddc869518357d9befd3Caroline Tice m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize(), ASYNC); 974757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice } 97524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 97624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 97724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case eStateStopped: 97824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case eStateCrashed: 97924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case eStateSuspended: 98024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Make sure the program hasn't been auto-restarted: 98124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (SBProcess::GetRestartedFromEvent (event)) 98224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 98389e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham size_t num_reasons = SBProcess::GetNumRestartedReasonsFromEvent(event); 98489e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham if (num_reasons > 0) 98589e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham { 98624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // FIXME: Do we want to report this, or would that just be annoyingly chatty? 98789e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham if (num_reasons == 1) 98889e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham { 98989e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham char message[1024]; 99089e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham const char *reason = SBProcess::GetRestartedReasonAtIndexFromEvent (event, 0); 99189e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham int message_len = ::snprintf (message, sizeof(message), "Process %" PRIu64 " stopped and restarted: %s\n", 99289e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham process.GetProcessID(), reason ? reason : "<UNKNOWN REASON>"); 99389e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham m_io_channel_ap->OutWrite(message, message_len, ASYNC); 99489e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham } 99589e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham else 99689e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham { 99789e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham char message[1024]; 99889e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham int message_len = ::snprintf (message, sizeof(message), "Process %" PRIu64 " stopped and restarted, reasons:\n", 99924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner process.GetProcessID()); 100089e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham m_io_channel_ap->OutWrite(message, message_len, ASYNC); 100189e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham for (size_t i = 0; i < num_reasons; i++) 100289e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham { 100389e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham const char *reason = SBProcess::GetRestartedReasonAtIndexFromEvent (event, i); 100489e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham int message_len = ::snprintf(message, sizeof(message), "\t%s\n", reason ? reason : "<UNKNOWN REASON>"); 100589e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham m_io_channel_ap->OutWrite(message, message_len, ASYNC); 100689e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham } 100789e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham } 100889e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham } 100924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 101024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 101124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 1012f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham if (GetDebugger().GetSelectedTarget() == process.GetTarget()) 1013f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham { 1014f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham SBCommandReturnObject result; 1015f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham UpdateSelectedThread (); 1016f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham m_debugger.GetCommandInterpreter().HandleCommand("process status", result, false); 1017f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham m_io_channel_ap->ErrWrite (result.GetError(), result.GetErrorSize(), ASYNC); 1018f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize(), ASYNC); 1019f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham } 1020f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham else 1021f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham { 1022f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham SBStream out_stream; 1023f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham uint32_t target_idx = GetDebugger().GetIndexOfTarget(process.GetTarget()); 1024f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham if (target_idx != UINT32_MAX) 1025f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham out_stream.Printf ("Target %d: (", target_idx); 1026f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham else 1027f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham out_stream.Printf ("Target <unknown index>: ("); 1028f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham process.GetTarget().GetDescription (out_stream, eDescriptionLevelBrief); 1029f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham out_stream.Printf (") stopped.\n"); 1030f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham m_io_channel_ap->OutWrite (out_stream.GetData(), out_stream.GetSize(), ASYNC); 1031f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham } 103224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 103324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 103424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 103524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 103624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 103724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 103894a5d0de4433dce556db59758f3d6124eb0e1a2aJim Inghamvoid 103994a5d0de4433dce556db59758f3d6124eb0e1a2aJim InghamDriver::HandleThreadEvent (const SBEvent &event) 104094a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham{ 104194a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham // At present the only thread event we handle is the Frame Changed event, and all we do for that is just 104294a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham // reprint the thread status for that thread. 104394a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham using namespace lldb; 104494a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham const uint32_t event_type = event.GetType(); 10452e2812388b75d3c62c9518cc1a6550ce29325aa6Jim Ingham if (event_type == SBThread::eBroadcastBitStackChanged 10462e2812388b75d3c62c9518cc1a6550ce29325aa6Jim Ingham || event_type == SBThread::eBroadcastBitThreadSelected) 104794a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham { 104894a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham SBThread thread = SBThread::GetThreadFromEvent (event); 104994a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham if (thread.IsValid()) 105094a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham { 105194a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham SBStream out_stream; 105294a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham thread.GetStatus(out_stream); 105394a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham m_io_channel_ap->OutWrite (out_stream.GetData (), out_stream.GetSize (), ASYNC); 105494a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham } 105594a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham } 105694a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham} 105794a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham 105824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This function handles events broadcast by the IOChannel (HasInput, UserInterrupt, or ThreadShouldExit). 105924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 106024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool 106124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDriver::HandleIOEvent (const SBEvent &event) 106224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 106324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner bool quit = false; 106424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 106524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const uint32_t event_type = event.GetType(); 106624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 106724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (event_type & IOChannel::eBroadcastBitHasUserInput) 106824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 106924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // We got some input (i.e. a command string) from the user; pass it off to the command interpreter for 107024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // handling. 107124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 107224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const char *command_string = SBEvent::GetCStringFromEvent(event); 107324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (command_string == NULL) 107454e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton command_string = ""; 107524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SBCommandReturnObject result; 10762e8cb8a7342a2ea672792067d712a794e215a3a7Jim Ingham 1077845d6dac85acc72334aeef730f088168fe0eaf36Caroline Tice // We don't want the result to bypass the OutWrite function in IOChannel, as this can result in odd 1078845d6dac85acc72334aeef730f088168fe0eaf36Caroline Tice // output orderings and problems with the prompt. 10794084fe70b71aef8d9d90186f9f54cd8a4d4c6861Greg Clayton 10804084fe70b71aef8d9d90186f9f54cd8a4d4c6861Greg Clayton // Note that we are in the process of executing a command 10814084fe70b71aef8d9d90186f9f54cd8a4d4c6861Greg Clayton m_executing_user_command = true; 10824084fe70b71aef8d9d90186f9f54cd8a4d4c6861Greg Clayton 10832e8cb8a7342a2ea672792067d712a794e215a3a7Jim Ingham m_debugger.GetCommandInterpreter().HandleCommand (command_string, result, true); 10842e8cb8a7342a2ea672792067d712a794e215a3a7Jim Ingham 10854084fe70b71aef8d9d90186f9f54cd8a4d4c6861Greg Clayton // Note that we are back from executing a user command 10864084fe70b71aef8d9d90186f9f54cd8a4d4c6861Greg Clayton m_executing_user_command = false; 10874084fe70b71aef8d9d90186f9f54cd8a4d4c6861Greg Clayton 10884084fe70b71aef8d9d90186f9f54cd8a4d4c6861Greg Clayton // Display any STDOUT/STDERR _prior_ to emitting the command result text 10894084fe70b71aef8d9d90186f9f54cd8a4d4c6861Greg Clayton GetProcessSTDOUT (); 10904084fe70b71aef8d9d90186f9f54cd8a4d4c6861Greg Clayton GetProcessSTDERR (); 10914084fe70b71aef8d9d90186f9f54cd8a4d4c6861Greg Clayton 1092c2bc7944f7c2f10114426f447259a35acb0b1e18Enrico Granata const bool only_if_no_immediate = true; 1093c2bc7944f7c2f10114426f447259a35acb0b1e18Enrico Granata 10944084fe70b71aef8d9d90186f9f54cd8a4d4c6861Greg Clayton // Now emit the command output text from the command we just executed 1095b8fda50a3e97699af76a406f03d139ee1bd94d01Enrico Granata const size_t output_size = result.GetOutputSize(); 1096c2bc7944f7c2f10114426f447259a35acb0b1e18Enrico Granata if (output_size > 0) 1097c2bc7944f7c2f10114426f447259a35acb0b1e18Enrico Granata m_io_channel_ap->OutWrite (result.GetOutput(only_if_no_immediate), output_size, NO_ASYNC); 1098c2bc7944f7c2f10114426f447259a35acb0b1e18Enrico Granata 10994084fe70b71aef8d9d90186f9f54cd8a4d4c6861Greg Clayton // Now emit the command error text from the command we just executed 1100b8fda50a3e97699af76a406f03d139ee1bd94d01Enrico Granata const size_t error_size = result.GetErrorSize(); 1101c2bc7944f7c2f10114426f447259a35acb0b1e18Enrico Granata if (error_size > 0) 1102c2bc7944f7c2f10114426f447259a35acb0b1e18Enrico Granata m_io_channel_ap->OutWrite (result.GetError(only_if_no_immediate), error_size, NO_ASYNC); 1103845d6dac85acc72334aeef730f088168fe0eaf36Caroline Tice 110424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // We are done getting and running our command, we can now clear the 110524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // m_waiting_for_command so we can get another one. 110624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_waiting_for_command = false; 110724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 110824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // If our editline input reader is active, it means another input reader 110924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // got pushed onto the input reader and caused us to become deactivated. 111024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // When the input reader above us gets popped, we will get re-activated 111124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // and our prompt will refresh in our callback 111224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (m_editline_reader.IsActive()) 111324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 111424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ReadyForCommand (); 111524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 111624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 111724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else if (event_type & IOChannel::eBroadcastBitUserInterrupt) 111824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 111924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // This is here to handle control-c interrupts from the user. It has not yet really been implemented. 112024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // TO BE DONE: PROPERLY HANDLE CONTROL-C FROM USER 112124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //m_io_channel_ap->CancelInput(); 112224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Anything else? Send Interrupt to process? 112324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 112424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else if ((event_type & IOChannel::eBroadcastBitThreadShouldExit) || 112524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner (event_type & IOChannel::eBroadcastBitThreadDidExit)) 112624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 112724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // If the IOChannel thread is trying to go away, then it is definitely 112824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // time to end the debugging session. 112924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner quit = true; 113024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 113124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 113224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return quit; 113324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 113424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 113524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 113624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDriver::MasterThreadBytesReceived (void *baton, const void *src, size_t src_len) 113724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 113824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Driver *driver = (Driver*)baton; 113924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner driver->GetFromMaster ((const char *)src, src_len); 114024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 114124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 114224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 114324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDriver::GetFromMaster (const char *src, size_t src_len) 114424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 114524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Echo the characters back to the Debugger's stdout, that way if you 114624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // type characters while a command is running, you'll see what you've typed. 114763094e0bb161580564954dee512955c1c79d3476Greg Clayton FILE *out_fh = m_debugger.GetOutputFileHandle(); 114824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (out_fh) 114924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::fwrite (src, 1, src_len, out_fh); 115024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 115124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 115224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnersize_t 115324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDriver::EditLineInputReaderCallback 115424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner( 115524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner void *baton, 115624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SBInputReader *reader, 115724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner InputReaderAction notification, 115824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const char *bytes, 115924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner size_t bytes_len 116024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner) 116124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 116224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Driver *driver = (Driver *)baton; 116324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 116424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner switch (notification) 116524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 116624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case eInputReaderActivate: 116724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 116824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 116924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case eInputReaderReactivate: 11704084fe70b71aef8d9d90186f9f54cd8a4d4c6861Greg Clayton if (driver->m_executing_user_command == false) 11714084fe70b71aef8d9d90186f9f54cd8a4d4c6861Greg Clayton driver->ReadyForCommand(); 117224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 117324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 117424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case eInputReaderDeactivate: 117524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 11764a348081030cdd2af758fddc869518357d9befd3Caroline Tice 11774a348081030cdd2af758fddc869518357d9befd3Caroline Tice case eInputReaderAsynchronousOutputWritten: 11784a348081030cdd2af758fddc869518357d9befd3Caroline Tice if (driver->m_io_channel_ap.get() != NULL) 11794a348081030cdd2af758fddc869518357d9befd3Caroline Tice driver->m_io_channel_ap->RefreshPrompt(); 11804a348081030cdd2af758fddc869518357d9befd3Caroline Tice break; 118124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1182c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice case eInputReaderInterrupt: 1183c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice if (driver->m_io_channel_ap.get() != NULL) 1184c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice { 11855d90ade8e8e0d776fe8e1b9e88fc1c86d02e8e4eJim Ingham SBProcess process(driver->GetDebugger().GetSelectedTarget().GetProcess()); 11860d99969ff26d108ec04f8830913e41e7f151db56Jim Ingham if (!driver->m_io_channel_ap->EditLineHasCharacters() 11875d90ade8e8e0d776fe8e1b9e88fc1c86d02e8e4eJim Ingham && process.IsValid() 11885d90ade8e8e0d776fe8e1b9e88fc1c86d02e8e4eJim Ingham && (process.GetState() == lldb::eStateRunning || process.GetState() == lldb::eStateAttaching)) 11890d99969ff26d108ec04f8830913e41e7f151db56Jim Ingham { 11905d90ade8e8e0d776fe8e1b9e88fc1c86d02e8e4eJim Ingham process.SendAsyncInterrupt (); 11910d99969ff26d108ec04f8830913e41e7f151db56Jim Ingham } 11920d99969ff26d108ec04f8830913e41e7f151db56Jim Ingham else 11930d99969ff26d108ec04f8830913e41e7f151db56Jim Ingham { 11940d99969ff26d108ec04f8830913e41e7f151db56Jim Ingham driver->m_io_channel_ap->OutWrite ("^C\n", 3, NO_ASYNC); 11950d99969ff26d108ec04f8830913e41e7f151db56Jim Ingham // I wish I could erase the entire input line, but there's no public API for that. 11960d99969ff26d108ec04f8830913e41e7f151db56Jim Ingham driver->m_io_channel_ap->EraseCharsBeforeCursor(); 11970d99969ff26d108ec04f8830913e41e7f151db56Jim Ingham driver->m_io_channel_ap->RefreshPrompt(); 11980d99969ff26d108ec04f8830913e41e7f151db56Jim Ingham } 1199c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice } 1200c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice break; 1201c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice 1202c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice case eInputReaderEndOfFile: 1203c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice if (driver->m_io_channel_ap.get() != NULL) 1204c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice { 12054a348081030cdd2af758fddc869518357d9befd3Caroline Tice driver->m_io_channel_ap->OutWrite ("^D\n", 3, NO_ASYNC); 1206c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice driver->m_io_channel_ap->RefreshPrompt (); 1207c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice } 1208c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice write (driver->m_editline_pty.GetMasterFileDescriptor(), "quit\n", 5); 1209c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice break; 1210c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice 121124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case eInputReaderGotToken: 121224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner write (driver->m_editline_pty.GetMasterFileDescriptor(), bytes, bytes_len); 121324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 121424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 121524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case eInputReaderDone: 121624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 121724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 121824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return bytes_len; 121924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 122024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 122124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 122224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDriver::MainLoop () 122324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 122424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner char error_str[1024]; 122524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (m_editline_pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY, error_str, sizeof(error_str)) == false) 122624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 122724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::fprintf (stderr, "error: failed to open driver pseudo terminal : %s", error_str); 122824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner exit(1); 122924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 123024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 123124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 123224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const char *driver_slave_name = m_editline_pty.GetSlaveName (error_str, sizeof(error_str)); 123324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (driver_slave_name == NULL) 123424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 123524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::fprintf (stderr, "error: failed to get slave name for driver pseudo terminal : %s", error_str); 123624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner exit(2); 123724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 123824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 123924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 124024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_editline_slave_fh = ::fopen (driver_slave_name, "r+"); 124124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (m_editline_slave_fh == NULL) 124224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 124324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SBError error; 124424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner error.SetErrorToErrno(); 124524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::fprintf (stderr, "error: failed to get open slave for driver pseudo terminal : %s", 124624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner error.GetCString()); 124724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner exit(3); 124824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 124924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 125024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::setbuf (m_editline_slave_fh, NULL); 125124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 125224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 125324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 12544a348081030cdd2af758fddc869518357d9befd3Caroline Tice lldb_utility::PseudoTerminal editline_output_pty; 12554a348081030cdd2af758fddc869518357d9befd3Caroline Tice FILE *editline_output_slave_fh = NULL; 12564a348081030cdd2af758fddc869518357d9befd3Caroline Tice 12574a348081030cdd2af758fddc869518357d9befd3Caroline Tice if (editline_output_pty.OpenFirstAvailableMaster (O_RDWR|O_NOCTTY, error_str, sizeof (error_str)) == false) 12584a348081030cdd2af758fddc869518357d9befd3Caroline Tice { 12594a348081030cdd2af758fddc869518357d9befd3Caroline Tice ::fprintf (stderr, "error: failed to open output pseudo terminal : %s", error_str); 12604a348081030cdd2af758fddc869518357d9befd3Caroline Tice exit(1); 12614a348081030cdd2af758fddc869518357d9befd3Caroline Tice } 12624a348081030cdd2af758fddc869518357d9befd3Caroline Tice else 12634a348081030cdd2af758fddc869518357d9befd3Caroline Tice { 12644a348081030cdd2af758fddc869518357d9befd3Caroline Tice const char *output_slave_name = editline_output_pty.GetSlaveName (error_str, sizeof(error_str)); 12654a348081030cdd2af758fddc869518357d9befd3Caroline Tice if (output_slave_name == NULL) 12664a348081030cdd2af758fddc869518357d9befd3Caroline Tice { 12674a348081030cdd2af758fddc869518357d9befd3Caroline Tice ::fprintf (stderr, "error: failed to get slave name for output pseudo terminal : %s", error_str); 12684a348081030cdd2af758fddc869518357d9befd3Caroline Tice exit(2); 12694a348081030cdd2af758fddc869518357d9befd3Caroline Tice } 12704a348081030cdd2af758fddc869518357d9befd3Caroline Tice else 12714a348081030cdd2af758fddc869518357d9befd3Caroline Tice { 12724a348081030cdd2af758fddc869518357d9befd3Caroline Tice editline_output_slave_fh = ::fopen (output_slave_name, "r+"); 12734a348081030cdd2af758fddc869518357d9befd3Caroline Tice if (editline_output_slave_fh == NULL) 12744a348081030cdd2af758fddc869518357d9befd3Caroline Tice { 12754a348081030cdd2af758fddc869518357d9befd3Caroline Tice SBError error; 12764a348081030cdd2af758fddc869518357d9befd3Caroline Tice error.SetErrorToErrno(); 12774a348081030cdd2af758fddc869518357d9befd3Caroline Tice ::fprintf (stderr, "error: failed to get open slave for output pseudo terminal : %s", 12784a348081030cdd2af758fddc869518357d9befd3Caroline Tice error.GetCString()); 12794a348081030cdd2af758fddc869518357d9befd3Caroline Tice exit(3); 12804a348081030cdd2af758fddc869518357d9befd3Caroline Tice } 12814a348081030cdd2af758fddc869518357d9befd3Caroline Tice ::setbuf (editline_output_slave_fh, NULL); 12824a348081030cdd2af758fddc869518357d9befd3Caroline Tice } 12834a348081030cdd2af758fddc869518357d9befd3Caroline Tice } 128424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 128524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // struct termios stdin_termios; 128624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 128724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (::tcgetattr(STDIN_FILENO, &g_old_stdin_termios) == 0) 12887cd8cd51421be28c7c615e141e87cf53bf2e21a0Greg Clayton { 12897cd8cd51421be28c7c615e141e87cf53bf2e21a0Greg Clayton g_old_stdin_termios_is_valid = true; 129024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner atexit (reset_stdin_termios); 12917cd8cd51421be28c7c615e141e87cf53bf2e21a0Greg Clayton } 129224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 129324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::setbuf (stdin, NULL); 129424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::setbuf (stdout, NULL); 129524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 129663094e0bb161580564954dee512955c1c79d3476Greg Clayton m_debugger.SetErrorFileHandle (stderr, false); 129763094e0bb161580564954dee512955c1c79d3476Greg Clayton m_debugger.SetOutputFileHandle (stdout, false); 129863094e0bb161580564954dee512955c1c79d3476Greg Clayton m_debugger.SetInputFileHandle (stdin, true); 129974989e88af7e04f3fe0bb3a800163113d7e0ca12Jim Ingham 130074989e88af7e04f3fe0bb3a800163113d7e0ca12Jim Ingham m_debugger.SetUseExternalEditor(m_option_data.m_use_external_editor); 130124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 130224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // You have to drain anything that comes to the master side of the PTY. master_out_comm is 130324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // for that purpose. The reason you need to do this is a curious reason... editline will echo 130424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // characters to the PTY when it gets characters while el_gets is not running, and then when 130524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // you call el_gets (or el_getc) it will try to reset the terminal back to raw mode which blocks 130624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // if there are unconsumed characters in the out buffer. 130724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // However, you don't need to do anything with the characters, since editline will dump these 130824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // unconsumed characters after printing the prompt again in el_gets. 130924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1310eecb0f3b5021e37311f9588f14bcab38a35b8e9aGreg Clayton SBCommunication master_out_comm("driver.editline"); 1311eecb0f3b5021e37311f9588f14bcab38a35b8e9aGreg Clayton master_out_comm.SetCloseOnEOF (false); 131224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner master_out_comm.AdoptFileDesriptor(m_editline_pty.GetMasterFileDescriptor(), false); 131324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner master_out_comm.SetReadThreadBytesReceivedCallback(Driver::MasterThreadBytesReceived, this); 131424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 131524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (master_out_comm.ReadThreadStart () == false) 131624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 131724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::fprintf (stderr, "error: failed to start master out read thread"); 131824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner exit(5); 131924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 132024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 132163094e0bb161580564954dee512955c1c79d3476Greg Clayton SBCommandInterpreter sb_interpreter = m_debugger.GetCommandInterpreter(); 132224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 13234a348081030cdd2af758fddc869518357d9befd3Caroline Tice m_io_channel_ap.reset (new IOChannel(m_editline_slave_fh, editline_output_slave_fh, stdout, stderr, this)); 13244a348081030cdd2af758fddc869518357d9befd3Caroline Tice 13254a348081030cdd2af758fddc869518357d9befd3Caroline Tice SBCommunication out_comm_2("driver.editline_output"); 13264a348081030cdd2af758fddc869518357d9befd3Caroline Tice out_comm_2.SetCloseOnEOF (false); 13274a348081030cdd2af758fddc869518357d9befd3Caroline Tice out_comm_2.AdoptFileDesriptor (editline_output_pty.GetMasterFileDescriptor(), false); 13284a348081030cdd2af758fddc869518357d9befd3Caroline Tice out_comm_2.SetReadThreadBytesReceivedCallback (IOChannel::LibeditOutputBytesReceived, m_io_channel_ap.get()); 13294a348081030cdd2af758fddc869518357d9befd3Caroline Tice 13304a348081030cdd2af758fddc869518357d9befd3Caroline Tice if (out_comm_2.ReadThreadStart () == false) 13314a348081030cdd2af758fddc869518357d9befd3Caroline Tice { 13324a348081030cdd2af758fddc869518357d9befd3Caroline Tice ::fprintf (stderr, "error: failed to start libedit output read thread"); 13334a348081030cdd2af758fddc869518357d9befd3Caroline Tice exit (5); 13344a348081030cdd2af758fddc869518357d9befd3Caroline Tice } 13354a348081030cdd2af758fddc869518357d9befd3Caroline Tice 133624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 133724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner struct winsize window_size; 133824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (isatty (STDIN_FILENO) 133924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0) 134024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 13416e4c5ce0f697eb9899a54854a2a9004e961b0de2Caroline Tice if (window_size.ws_col > 0) 1342238c0a1e7b733cee539258faa656159c63f9e893Greg Clayton m_debugger.SetTerminalWidth (window_size.ws_col); 134324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 134424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 134524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Since input can be redirected by the debugger, we must insert our editline 134624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // input reader in the queue so we know when our reader should be active 134724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // and so we can receive bytes only when we are supposed to. 134863094e0bb161580564954dee512955c1c79d3476Greg Clayton SBError err (m_editline_reader.Initialize (m_debugger, 134963094e0bb161580564954dee512955c1c79d3476Greg Clayton Driver::EditLineInputReaderCallback, // callback 135024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner this, // baton 135124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner eInputReaderGranularityByte, // token_size 135224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner NULL, // end token - NULL means never done 135324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner NULL, // prompt - taken care of elsewhere 135424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner false)); // echo input - don't need Debugger 135524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // to do this, we handle it elsewhere 135624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 135724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (err.Fail()) 135824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 135924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ::fprintf (stderr, "error: %s", err.GetCString()); 136024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner exit (6); 136124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 136224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 136363094e0bb161580564954dee512955c1c79d3476Greg Clayton m_debugger.PushInputReader (m_editline_reader); 136424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 136563094e0bb161580564954dee512955c1c79d3476Greg Clayton SBListener listener(m_debugger.GetListener()); 136624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (listener.IsValid()) 136724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 136824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 136994a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham listener.StartListeningForEventClass(m_debugger, 137094a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham SBTarget::GetBroadcasterClassName(), 137194a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham SBTarget::eBroadcastBitBreakpointChanged); 137294a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham listener.StartListeningForEventClass(m_debugger, 137394a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham SBThread::GetBroadcasterClassName(), 13742e2812388b75d3c62c9518cc1a6550ce29325aa6Jim Ingham SBThread::eBroadcastBitStackChanged | 13752e2812388b75d3c62c9518cc1a6550ce29325aa6Jim Ingham SBThread::eBroadcastBitThreadSelected); 137624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner listener.StartListeningForEvents (*m_io_channel_ap, 137724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner IOChannel::eBroadcastBitHasUserInput | 137824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner IOChannel::eBroadcastBitUserInterrupt | 137924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner IOChannel::eBroadcastBitThreadShouldExit | 138024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner IOChannel::eBroadcastBitThreadDidStart | 138124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner IOChannel::eBroadcastBitThreadDidExit); 138224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 138324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (m_io_channel_ap->Start ()) 138424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 138524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner bool iochannel_thread_exited = false; 138624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 138724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner listener.StartListeningForEvents (sb_interpreter.GetBroadcaster(), 1388388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice SBCommandInterpreter::eBroadcastBitQuitCommandReceived | 1389388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice SBCommandInterpreter::eBroadcastBitAsynchronousOutputData | 1390388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice SBCommandInterpreter::eBroadcastBitAsynchronousErrorData); 139124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 139224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Before we handle any options from the command line, we parse the 139324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // .lldbinit file in the user's home directory. 139424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SBCommandReturnObject result; 139524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner sb_interpreter.SourceInitFileInHomeDirectory(result); 139624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (GetDebugMode()) 139724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 139863094e0bb161580564954dee512955c1c79d3476Greg Clayton result.PutError (m_debugger.GetErrorFileHandle()); 139963094e0bb161580564954dee512955c1c79d3476Greg Clayton result.PutOutput (m_debugger.GetOutputFileHandle()); 140024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 140124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 140224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Now we handle options we got from the command line 140324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner char command_string[PATH_MAX * 2]; 140424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const size_t num_source_command_files = GetNumSourceCommandFiles(); 14051581d7d8a976cc63ce44789c07b1b35a80786dfbEnrico Granata const bool dump_stream_only_if_no_immediate = true; 140624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (num_source_command_files > 0) 140724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 140824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner for (size_t i=0; i < num_source_command_files; ++i) 140924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 141024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const char *command_file = GetSourceCommandFileAtIndex(i); 14117c9842487cd2a61f12669624f4ba38bb5c8617eaJohnny Chen ::snprintf (command_string, sizeof(command_string), "command source '%s'", command_file); 141263094e0bb161580564954dee512955c1c79d3476Greg Clayton m_debugger.GetCommandInterpreter().HandleCommand (command_string, result, false); 141324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (GetDebugMode()) 141424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 141563094e0bb161580564954dee512955c1c79d3476Greg Clayton result.PutError (m_debugger.GetErrorFileHandle()); 141663094e0bb161580564954dee512955c1c79d3476Greg Clayton result.PutOutput (m_debugger.GetOutputFileHandle()); 141724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 14181581d7d8a976cc63ce44789c07b1b35a80786dfbEnrico Granata 14191581d7d8a976cc63ce44789c07b1b35a80786dfbEnrico Granata // if the command sourcing generated an error - dump the result object 1420c8aa9c9b5b9c584daa94cba7592bebea6ce6dfabEnrico Granata if (result.Succeeded() == false) 14211581d7d8a976cc63ce44789c07b1b35a80786dfbEnrico Granata { 14221581d7d8a976cc63ce44789c07b1b35a80786dfbEnrico Granata const size_t output_size = result.GetOutputSize(); 14231581d7d8a976cc63ce44789c07b1b35a80786dfbEnrico Granata if (output_size > 0) 14241581d7d8a976cc63ce44789c07b1b35a80786dfbEnrico Granata m_io_channel_ap->OutWrite (result.GetOutput(dump_stream_only_if_no_immediate), output_size, NO_ASYNC); 1425c8aa9c9b5b9c584daa94cba7592bebea6ce6dfabEnrico Granata const size_t error_size = result.GetErrorSize(); 1426c8aa9c9b5b9c584daa94cba7592bebea6ce6dfabEnrico Granata if (error_size > 0) 1427c8aa9c9b5b9c584daa94cba7592bebea6ce6dfabEnrico Granata m_io_channel_ap->OutWrite (result.GetError(dump_stream_only_if_no_immediate), error_size, NO_ASYNC); 14281581d7d8a976cc63ce44789c07b1b35a80786dfbEnrico Granata } 14291581d7d8a976cc63ce44789c07b1b35a80786dfbEnrico Granata 14301581d7d8a976cc63ce44789c07b1b35a80786dfbEnrico Granata result.Clear(); 143124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 143224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 143324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 14346c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen // Was there a core file specified? 14356c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen std::string core_file_spec(""); 14366c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen if (!m_option_data.m_core_file.empty()) 14376c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen core_file_spec.append("--core ").append(m_option_data.m_core_file); 14386c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen 14394dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton const size_t num_args = m_option_data.m_args.size(); 14404dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton if (num_args > 0) 144124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 144224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner char arch_name[64]; 144363094e0bb161580564954dee512955c1c79d3476Greg Clayton if (m_debugger.GetDefaultArchitecture (arch_name, sizeof (arch_name))) 14444dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton ::snprintf (command_string, 14454dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton sizeof (command_string), 14466c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen "target create --arch=%s %s \"%s\"", 14474dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton arch_name, 14486c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen core_file_spec.c_str(), 14494dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton m_option_data.m_args[0].c_str()); 145024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 14514dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton ::snprintf (command_string, 14524dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton sizeof(command_string), 14536c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen "target create %s \"%s\"", 14546c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen core_file_spec.c_str(), 14554dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton m_option_data.m_args[0].c_str()); 145624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 145763094e0bb161580564954dee512955c1c79d3476Greg Clayton m_debugger.HandleCommand (command_string); 14584dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton 14594dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton if (num_args > 1) 14604dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton { 1461abb3302051246273eb92cca203c9a1b9d9736e05Greg Clayton m_debugger.HandleCommand ("settings clear target.run-args"); 14624dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton char arg_cstr[1024]; 14634dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton for (size_t arg_idx = 1; arg_idx < num_args; ++arg_idx) 14644dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton { 146583dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham ::snprintf (arg_cstr, 146683dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham sizeof(arg_cstr), 1467abb3302051246273eb92cca203c9a1b9d9736e05Greg Clayton "settings append target.run-args \"%s\"", 146883dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham m_option_data.m_args[arg_idx].c_str()); 14694dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton m_debugger.HandleCommand (arg_cstr); 14704dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton } 14714dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton } 147224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 14736c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen else if (!core_file_spec.empty()) 14746c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen { 14756c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen ::snprintf (command_string, 14766c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen sizeof(command_string), 14776c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen "target create %s", 14786c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen core_file_spec.c_str()); 14796c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen m_debugger.HandleCommand (command_string);; 14806c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen } 148124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 148224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Now that all option parsing is done, we try and parse the .lldbinit 148324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // file in the current working directory 148424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner sb_interpreter.SourceInitFileInCurrentWorkingDirectory (result); 148524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (GetDebugMode()) 148624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 148763094e0bb161580564954dee512955c1c79d3476Greg Clayton result.PutError(m_debugger.GetErrorFileHandle()); 148863094e0bb161580564954dee512955c1c79d3476Greg Clayton result.PutOutput(m_debugger.GetOutputFileHandle()); 148924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 149024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 149124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SBEvent event; 149224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 149324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Make sure the IO channel is started up before we try to tell it we 149424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // are ready for input 149524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner listener.WaitForEventForBroadcasterWithType (UINT32_MAX, 149624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner *m_io_channel_ap, 149724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner IOChannel::eBroadcastBitThreadDidStart, 149824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner event); 149983dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham // If we were asked to attach, then do that here: 150083dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham // I'm going to use the command string rather than directly 150183dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham // calling the API's because then I don't have to recode the 150283dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham // event handling here. 150383dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham if (!m_option_data.m_process_name.empty() 150483dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham || m_option_data.m_process_pid != LLDB_INVALID_PROCESS_ID) 150583dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham { 150683dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham std::string command_str("process attach "); 150783dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham if (m_option_data.m_process_pid != LLDB_INVALID_PROCESS_ID) 150883dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham { 150983dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham command_str.append("-p "); 151083dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham char pid_buffer[32]; 15115f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea ::snprintf (pid_buffer, sizeof(pid_buffer), "%" PRIu64, m_option_data.m_process_pid); 151283dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham command_str.append(pid_buffer); 151383dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham } 151483dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham else 151583dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham { 151683dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham command_str.append("-n \""); 151783dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham command_str.append(m_option_data.m_process_name); 151883dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham command_str.push_back('\"'); 151983dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham if (m_option_data.m_wait_for) 152083dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham command_str.append(" -w"); 152183dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham } 152283dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham 152383dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham if (m_debugger.GetOutputFileHandle()) 152483dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham ::fprintf (m_debugger.GetOutputFileHandle(), 152583dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham "Attaching to process with:\n %s\n", 152683dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham command_str.c_str()); 152783dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham 152883dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham // Force the attach to be synchronous: 152983dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham bool orig_async = m_debugger.GetAsync(); 153083dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham m_debugger.SetAsync(true); 153183dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham m_debugger.HandleCommand(command_str.c_str()); 153283dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham m_debugger.SetAsync(orig_async); 153383dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham } 153483dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham 153524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ReadyForCommand (); 153624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1537f125250ba7bcaa2ea5ee95539a309e3fd2f8b5d7Greg Clayton while (!GetIsDone()) 153824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 153924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner listener.WaitForEvent (UINT32_MAX, event); 154024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (event.IsValid()) 154124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 154224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (event.GetBroadcaster().IsValid()) 154324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 154424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t event_type = event.GetType(); 154524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (event.BroadcasterMatchesRef (*m_io_channel_ap)) 154624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 154724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if ((event_type & IOChannel::eBroadcastBitThreadShouldExit) || 154824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner (event_type & IOChannel::eBroadcastBitThreadDidExit)) 154924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 1550f125250ba7bcaa2ea5ee95539a309e3fd2f8b5d7Greg Clayton SetIsDone(); 155124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (event_type & IOChannel::eBroadcastBitThreadDidExit) 155224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner iochannel_thread_exited = true; 155324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 155424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 1555f125250ba7bcaa2ea5ee95539a309e3fd2f8b5d7Greg Clayton { 1556f125250ba7bcaa2ea5ee95539a309e3fd2f8b5d7Greg Clayton if (HandleIOEvent (event)) 1557f125250ba7bcaa2ea5ee95539a309e3fd2f8b5d7Greg Clayton SetIsDone(); 1558f125250ba7bcaa2ea5ee95539a309e3fd2f8b5d7Greg Clayton } 155924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 156028e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham else if (SBProcess::EventIsProcessEvent (event)) 156124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 156224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner HandleProcessEvent (event); 156324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 156428e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham else if (SBBreakpoint::EventIsBreakpointEvent (event)) 156528e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham { 156628e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham HandleBreakpointEvent (event); 156728e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham } 156894a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham else if (SBThread::EventIsThreadEvent (event)) 156994a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham { 157094a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham HandleThreadEvent (event); 157194a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham } 157224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else if (event.BroadcasterMatchesRef (sb_interpreter.GetBroadcaster())) 157324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 1574f125250ba7bcaa2ea5ee95539a309e3fd2f8b5d7Greg Clayton // TODO: deprecate the eBroadcastBitQuitCommandReceived event 1575f125250ba7bcaa2ea5ee95539a309e3fd2f8b5d7Greg Clayton // now that we have SBCommandInterpreter::SetCommandOverrideCallback() 1576f125250ba7bcaa2ea5ee95539a309e3fd2f8b5d7Greg Clayton // that can take over a command 157724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (event_type & SBCommandInterpreter::eBroadcastBitQuitCommandReceived) 1578db9d6f47ab38e25c3efcbfa05780bf9a127fd259Greg Clayton { 1579f125250ba7bcaa2ea5ee95539a309e3fd2f8b5d7Greg Clayton SetIsDone(); 1580db9d6f47ab38e25c3efcbfa05780bf9a127fd259Greg Clayton } 1581388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice else if (event_type & SBCommandInterpreter::eBroadcastBitAsynchronousErrorData) 1582388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice { 1583388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice const char *data = SBEvent::GetCStringFromEvent (event); 1584388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice m_io_channel_ap->ErrWrite (data, strlen(data), ASYNC); 1585388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice } 1586388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice else if (event_type & SBCommandInterpreter::eBroadcastBitAsynchronousOutputData) 1587388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice { 1588388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice const char *data = SBEvent::GetCStringFromEvent (event); 1589388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice m_io_channel_ap->OutWrite (data, strlen(data), ASYNC); 1590388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice } 159124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 159224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 159324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 159424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 159524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 15963cc1b9c78b84a3796ecb7ba1f57335e952a4b746Michael Sartain master_out_comm.SetReadThreadBytesReceivedCallback(NULL, NULL); 15977cd8cd51421be28c7c615e141e87cf53bf2e21a0Greg Clayton master_out_comm.Disconnect(); 15983cc1b9c78b84a3796ecb7ba1f57335e952a4b746Michael Sartain master_out_comm.ReadThreadStop(); 15993cc1b9c78b84a3796ecb7ba1f57335e952a4b746Michael Sartain 16003cc1b9c78b84a3796ecb7ba1f57335e952a4b746Michael Sartain out_comm_2.SetReadThreadBytesReceivedCallback(NULL, NULL); 16017cd8cd51421be28c7c615e141e87cf53bf2e21a0Greg Clayton out_comm_2.Disconnect(); 16023cc1b9c78b84a3796ecb7ba1f57335e952a4b746Michael Sartain out_comm_2.ReadThreadStop(); 16033cc1b9c78b84a3796ecb7ba1f57335e952a4b746Michael Sartain 16043cc1b9c78b84a3796ecb7ba1f57335e952a4b746Michael Sartain editline_output_pty.CloseMasterFileDescriptor(); 16057cd8cd51421be28c7c615e141e87cf53bf2e21a0Greg Clayton reset_stdin_termios(); 16067cd8cd51421be28c7c615e141e87cf53bf2e21a0Greg Clayton fclose (stdin); 160724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 160824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner CloseIOChannelFile (); 160924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 161024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (!iochannel_thread_exited) 161124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 1612bef1583b89e73de77c8b0897fcf42b5b1fcabe4cGreg Clayton event.Clear(); 161324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner listener.GetNextEventForBroadcasterWithType (*m_io_channel_ap, 161424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner IOChannel::eBroadcastBitThreadDidExit, 161524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner event); 161624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (!event.IsValid()) 161724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 161824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Send end EOF to the driver file descriptor 161924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_io_channel_ap->Stop(); 162024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 162124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 162224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1623dbcf98c194742f911c963854084c66aa49a5e513Jim Ingham SBDebugger::Destroy (m_debugger); 162424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 162524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 162624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 162724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 162824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 162924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 163024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDriver::ReadyForCommand () 163124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 163224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (m_waiting_for_command == false) 163324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 163424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_waiting_for_command = true; 163524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner BroadcastEventByType (Driver::eBroadcastBitReadyForInput, true); 163624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 163724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 163824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 16392eaca13a907b3c2ce41602b646d073851dc696ebJim Inghamvoid 16402eaca13a907b3c2ce41602b646d073851dc696ebJim InghamDriver::ResizeWindow (unsigned short col) 16412eaca13a907b3c2ce41602b646d073851dc696ebJim Ingham{ 16422eaca13a907b3c2ce41602b646d073851dc696ebJim Ingham GetDebugger().SetTerminalWidth (col); 16432eaca13a907b3c2ce41602b646d073851dc696ebJim Ingham if (m_io_channel_ap.get() != NULL) 16442eaca13a907b3c2ce41602b646d073851dc696ebJim Ingham { 16452eaca13a907b3c2ce41602b646d073851dc696ebJim Ingham m_io_channel_ap->ElResize(); 16462eaca13a907b3c2ce41602b646d073851dc696ebJim Ingham } 16472eaca13a907b3c2ce41602b646d073851dc696ebJim Ingham} 164824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1649b8314fe67960cfcc5d9e9232be4c1914c9ef0ce3Caroline Ticevoid 1650b8314fe67960cfcc5d9e9232be4c1914c9ef0ce3Caroline Ticesigwinch_handler (int signo) 1651b8314fe67960cfcc5d9e9232be4c1914c9ef0ce3Caroline Tice{ 1652b8314fe67960cfcc5d9e9232be4c1914c9ef0ce3Caroline Tice struct winsize window_size; 1653b8314fe67960cfcc5d9e9232be4c1914c9ef0ce3Caroline Tice if (isatty (STDIN_FILENO) 1654b8314fe67960cfcc5d9e9232be4c1914c9ef0ce3Caroline Tice && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0) 1655b8314fe67960cfcc5d9e9232be4c1914c9ef0ce3Caroline Tice { 1656c76486cc024511ab8e96baea752e98f49c2b1da4Jim Ingham if ((window_size.ws_col > 0) && g_driver != NULL) 1657b8314fe67960cfcc5d9e9232be4c1914c9ef0ce3Caroline Tice { 16582eaca13a907b3c2ce41602b646d073851dc696ebJim Ingham g_driver->ResizeWindow (window_size.ws_col); 1659b8314fe67960cfcc5d9e9232be4c1914c9ef0ce3Caroline Tice } 1660b8314fe67960cfcc5d9e9232be4c1914c9ef0ce3Caroline Tice } 1661b8314fe67960cfcc5d9e9232be4c1914c9ef0ce3Caroline Tice} 1662b8314fe67960cfcc5d9e9232be4c1914c9ef0ce3Caroline Tice 1663c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Ticevoid 1664c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Ticesigint_handler (int signo) 1665c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice{ 1666c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice static bool g_interrupt_sent = false; 1667c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice if (g_driver) 1668c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice { 1669c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice if (!g_interrupt_sent) 1670c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice { 1671c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice g_interrupt_sent = true; 1672c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice g_driver->GetDebugger().DispatchInputInterrupt(); 1673c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice g_interrupt_sent = false; 1674c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice return; 1675c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice } 1676c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice } 1677c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice 1678c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice exit (signo); 1679c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice} 1680c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice 1681b1087a27f7babc43f332c9d49ac4554892133a41Jim Inghamvoid 1682b1087a27f7babc43f332c9d49ac4554892133a41Jim Inghamsigtstp_handler (int signo) 1683b1087a27f7babc43f332c9d49ac4554892133a41Jim Ingham{ 1684b1087a27f7babc43f332c9d49ac4554892133a41Jim Ingham g_driver->GetDebugger().SaveInputTerminalState(); 1685b1087a27f7babc43f332c9d49ac4554892133a41Jim Ingham signal (signo, SIG_DFL); 1686b1087a27f7babc43f332c9d49ac4554892133a41Jim Ingham kill (getpid(), signo); 1687b1087a27f7babc43f332c9d49ac4554892133a41Jim Ingham signal (signo, sigtstp_handler); 1688b1087a27f7babc43f332c9d49ac4554892133a41Jim Ingham} 1689b1087a27f7babc43f332c9d49ac4554892133a41Jim Ingham 1690b1087a27f7babc43f332c9d49ac4554892133a41Jim Inghamvoid 1691b1087a27f7babc43f332c9d49ac4554892133a41Jim Inghamsigcont_handler (int signo) 1692b1087a27f7babc43f332c9d49ac4554892133a41Jim Ingham{ 1693b1087a27f7babc43f332c9d49ac4554892133a41Jim Ingham g_driver->GetDebugger().RestoreInputTerminalState(); 1694b1087a27f7babc43f332c9d49ac4554892133a41Jim Ingham signal (signo, SIG_DFL); 1695b1087a27f7babc43f332c9d49ac4554892133a41Jim Ingham kill (getpid(), signo); 1696b1087a27f7babc43f332c9d49ac4554892133a41Jim Ingham signal (signo, sigcont_handler); 1697b1087a27f7babc43f332c9d49ac4554892133a41Jim Ingham} 1698b1087a27f7babc43f332c9d49ac4554892133a41Jim Ingham 169924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerint 1700b2b604f51ef03beb85d3c8d997ec25d85dea26faJim Inghammain (int argc, char const *argv[], const char *envp[]) 170124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 170224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SBDebugger::Initialize(); 170324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 170495e33b7b4b832ff5a8dfd0720fe6a100be894df6Greg Clayton SBHostOS::ThreadCreated ("<lldb.driver.main-thread>"); 170524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 170636f63a92bae332929e1a047b59ed6df651d8537fGreg Clayton signal (SIGPIPE, SIG_IGN); 1707b8314fe67960cfcc5d9e9232be4c1914c9ef0ce3Caroline Tice signal (SIGWINCH, sigwinch_handler); 1708c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice signal (SIGINT, sigint_handler); 1709b1087a27f7babc43f332c9d49ac4554892133a41Jim Ingham signal (SIGTSTP, sigtstp_handler); 1710b1087a27f7babc43f332c9d49ac4554892133a41Jim Ingham signal (SIGCONT, sigcont_handler); 1711b8314fe67960cfcc5d9e9232be4c1914c9ef0ce3Caroline Tice 171263094e0bb161580564954dee512955c1c79d3476Greg Clayton // Create a scope for driver so that the driver object will destroy itself 171363094e0bb161580564954dee512955c1c79d3476Greg Clayton // before SBDebugger::Terminate() is called. 171424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 171563094e0bb161580564954dee512955c1c79d3476Greg Clayton Driver driver; 171663094e0bb161580564954dee512955c1c79d3476Greg Clayton 171763094e0bb161580564954dee512955c1c79d3476Greg Clayton bool exit = false; 171863094e0bb161580564954dee512955c1c79d3476Greg Clayton SBError error (driver.ParseArgs (argc, argv, stdout, exit)); 171963094e0bb161580564954dee512955c1c79d3476Greg Clayton if (error.Fail()) 172063094e0bb161580564954dee512955c1c79d3476Greg Clayton { 172163094e0bb161580564954dee512955c1c79d3476Greg Clayton const char *error_cstr = error.GetCString (); 172263094e0bb161580564954dee512955c1c79d3476Greg Clayton if (error_cstr) 172363094e0bb161580564954dee512955c1c79d3476Greg Clayton ::fprintf (stderr, "error: %s\n", error_cstr); 172463094e0bb161580564954dee512955c1c79d3476Greg Clayton } 172563094e0bb161580564954dee512955c1c79d3476Greg Clayton else if (!exit) 172663094e0bb161580564954dee512955c1c79d3476Greg Clayton { 172763094e0bb161580564954dee512955c1c79d3476Greg Clayton driver.MainLoop (); 172863094e0bb161580564954dee512955c1c79d3476Greg Clayton } 172924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 173024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 173124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SBDebugger::Terminate(); 173224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return 0; 173324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 1734