diff options
author | Fred Fish <fnf@specifix.com> | 1996-01-24 21:30:37 +0000 |
---|---|---|
committer | Fred Fish <fnf@specifix.com> | 1996-01-24 21:30:37 +0000 |
commit | e8f1ad9a8b8548dbc79c01b3df218ff2a97f1c05 (patch) | |
tree | db230c832d5d2ec58b5e123a58512b7d56bf0d1a /gdb/serial.c | |
parent | 76e45938c3dbf2a25eb273bfcd3aa4961585dd5e (diff) | |
download | gdb-e8f1ad9a8b8548dbc79c01b3df218ff2a97f1c05.zip gdb-e8f1ad9a8b8548dbc79c01b3df218ff2a97f1c05.tar.gz gdb-e8f1ad9a8b8548dbc79c01b3df218ff2a97f1c05.tar.bz2 |
* NEWS: Make note of new record and replay feature for
remote debug sessions.
* serial.c (gdbcmd.h): Include.
(serial_logfile, serial_logfp, serial_reading, serial_writing):
Define here, for remote debug session logging.
(serial_log_command, serial_logchar, serial_write, serial_readchar):
New functions for remote debug session logging.
(serial_open): Open remote debug session log file when needed.
(serial_close): Close remote debug session log file when needed.
(_initialize_serial): Add set/show commands for name of remote
debug session log file.
* serial.h (serial_readchar): Declare
(SERIAL_READCHAR): Call serial_readchar().
(SERIAL_WRITE): Call serial_write().
(serial_close): Declare as extern.
(serial_logfile, serial_logfp): Declare.
* top.c (execute_command): Declare serial_logfp. Log user command
in remote debug session log if log file is open.
* remote-array.c (array_wait): #ifdef out echo to gdb_stdout.
(array_read_inferior_memory): Rewrite to fix memory overwrite bug.
* remote-array.c (SREC_SIZE): Remove, duplicates define in
monitor.h.
* remote-array.c (hexchars, hex2mem): Remove, unused.
* gdbserver/low-linux.c (store_inferior_registers): Remove
unnecessary extern declaration of registers[].
* gdbserver/Makefile.in (all): Add gdbreplay.
* gdbserver/gdbreplay.c: New file.
* gdbserver/README: Give example of recording a remote
debug session with gdb and then replaying it with gdbreplay.
Diffstat (limited to 'gdb/serial.c')
-rw-r--r-- | gdb/serial.c | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/gdb/serial.c b/gdb/serial.c index 72bfc50..c984d7a 100644 --- a/gdb/serial.c +++ b/gdb/serial.c @@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "defs.h" #include "serial.h" #include "gdb_string.h" +#include "gdbcmd.h" /* Linked list of serial I/O handlers */ @@ -33,6 +34,110 @@ static serial_t last_serial_opened = NULL; static serial_t scb_base; +/* Non-NULL gives filename which contains a recording of the remote session, + suitable for playback by gdbserver. */ + +char *serial_logfile = NULL; +FILE *serial_logfp = NULL; + + +static int serial_reading = 0; +static int serial_writing = 0; + +void +serial_log_command (cmd) + const char *cmd; +{ + if (serial_reading || serial_writing) + { + fputc ('\n', serial_logfp); + serial_reading = 0; + serial_writing = 0; + } + fprintf (serial_logfp, "c %s\n", cmd); + /* Make sure that the log file is as up-to-date as possible, + in case we are getting ready to dump core or something. */ + fflush (serial_logfp); +} + +static void +serial_logchar (ch) + int ch; +{ + switch (ch) + { + case '\\': fputs ("\\\\", serial_logfp); break; + case '\b': fputs ("\\b", serial_logfp); break; + case '\f': fputs ("\\f", serial_logfp); break; + case '\n': fputs ("\\n", serial_logfp); break; + case '\r': fputs ("\\r", serial_logfp); break; + case '\t': fputs ("\\t", serial_logfp); break; + case '\v': fputs ("\\v", serial_logfp); break; + default: fprintf (serial_logfp, isprint (ch) ? "%c" : "\\x%02x", ch & 0xFF); break; + } +} + +int +serial_write (scb, str, len) + serial_t scb; + const char *str; + int len; +{ + int count; + + if (serial_logfp != NULL) + { + if (serial_reading) + { + fputc ('\n', serial_logfp); + serial_reading = 0; + } + if (!serial_writing) + { + serial_logchar ('w'); + serial_logchar (' '); + serial_writing = 1; + } + for (count = 0; count < len; count++) + { + serial_logchar (str[count]); + } + /* Make sure that the log file is as up-to-date as possible, + in case we are getting ready to dump core or something. */ + fflush (serial_logfp); + } + return (scb -> ops -> write (scb, str, len)); +} + +int +serial_readchar (scb, timeout) + serial_t scb; + int timeout; +{ + int ch; + + ch = scb -> ops -> readchar (scb, timeout); + if (serial_logfp != NULL) + { + if (serial_writing) + { + fputc ('\n', serial_logfp); + serial_writing = 0; + } + if (!serial_reading) + { + serial_logchar ('r'); + serial_logchar (' '); + serial_reading = 1; + } + serial_logchar (ch); + /* Make sure that the log file is as up-to-date as possible, + in case we are getting ready to dump core or something. */ + fflush (serial_logfp); + } + return (ch); +} + static struct serial_ops * serial_interface_lookup (name) char *name; @@ -102,6 +207,15 @@ serial_open (name) last_serial_opened = scb; + if (serial_logfile != NULL) + { + serial_logfp = fopen (serial_logfile, "w"); + if (serial_logfp == NULL) + { + perror_with_name (serial_logfile); + } + } + return scb; } @@ -152,6 +266,18 @@ serial_close(scb, really_close) last_serial_opened = NULL; + if (serial_logfp) + { + if (serial_reading || serial_writing) + { + fputc ('\n', serial_logfp); + serial_reading = 0; + serial_writing = 0; + } + fclose (serial_logfp); + serial_logfp = NULL; + } + /* This is bogus. It's not our fault if you pass us a bad scb...! Rob, you should fix your code instead. */ @@ -346,4 +472,12 @@ _initialize_serial () "Connect the terminal directly up to the command monitor.\n\ Use <CR>~. or <CR>~^D to break out."); #endif /* 0 */ + + add_show_from_set (add_set_cmd ("remotelogfile", no_class, + var_filename, (char *)&serial_logfile, + "Set filename for remote session recording.\n\ +This file is used to record the remote session for future playback\n\ +by gdbserver.", &setlist), + &showlist); + } |