diff --git a/gdbserver/README b/gdbserver/README index 5b47510c3e3..e7e99ec7988 100644 --- a/gdbserver/README +++ b/gdbserver/README @@ -125,8 +125,9 @@ Then start GDB (preferably in a different screen or window) and use the Repeat the same sequence of user commands to GDB that you gave in the original debug session. GDB should not be able to tell that it is talking -to GDBreplay rather than a real target, all other things being equal. Note -that GDBreplay echos the command lines to stderr, as well as the contents of -the packets it sends and receives. The last command echoed by GDBreplay is -the next command that needs to be typed to GDB to continue the session in -sync with the original session. +to GDBreplay rather than a real target, all other things being equal. + +As GDBreplay communicates with GDB, it outputs only the commands +it expects from GDB. The --debug-logging option turns printing the +remotelogfile to stderr on. GDBreplay then echos the command lines +to stderr, as well as the contents of the packets it sends and receives. diff --git a/gdbserver/gdbreplay.cc b/gdbserver/gdbreplay.cc index 7ef52b82d0b..a2c77ce9588 100644 --- a/gdbserver/gdbreplay.cc +++ b/gdbserver/gdbreplay.cc @@ -68,6 +68,9 @@ typedef int socklen_t; static int remote_desc_in; static int remote_desc_out; +/* When true all packets are printed to stderr as they are handled by + gdbreplay. */ +bool debug_logging = false; static void sync_error (FILE *fp, const char *desc, int expect, int got) @@ -261,13 +264,13 @@ remote_open (const char *name) } static int -logchar (FILE *fp) +logchar (FILE *fp, bool print) { int ch; int ch2; ch = fgetc (fp); - if (ch != '\r') + if (ch != '\r' && (print || debug_logging)) { fputc (ch, stderr); fflush (stderr); @@ -284,16 +287,22 @@ logchar (FILE *fp) ungetc (ch, fp); ch = '\r'; } - fputc (ch == EOL ? '\n' : '\r', stderr); - fflush (stderr); + if (print || debug_logging) + { + fputc (ch == EOL ? '\n' : '\r', stderr); + fflush (stderr); + } break; case '\n': ch = EOL; break; case '\\': ch = fgetc (fp); - fputc (ch, stderr); - fflush (stderr); + if (print || debug_logging) + { + fputc (ch, stderr); + fflush (stderr); + } switch (ch) { case '\\': @@ -318,14 +327,28 @@ logchar (FILE *fp) break; case 'x': ch2 = fgetc (fp); - fputc (ch2, stderr); - fflush (stderr); + if (print || debug_logging) + { + fputc (ch2, stderr); + fflush (stderr); + } ch = fromhex (ch2) << 4; ch2 = fgetc (fp); - fputc (ch2, stderr); - fflush (stderr); + if (print || debug_logging) + { + fputc (ch2, stderr); + fflush (stderr); + } ch |= fromhex (ch2); break; + case 'c': + fputc (ch, stderr); + fflush (stderr); + break; + case 'E': + fputc (ch, stderr); + fflush (stderr); + break; default: /* Treat any other char as just itself */ break; @@ -356,14 +379,14 @@ expect (FILE *fp) int fromlog; int fromgdb; - if ((fromlog = logchar (fp)) != ' ') + if ((fromlog = logchar (fp, false)) != ' ') { sync_error (fp, "Sync error during gdb read of leading blank", ' ', fromlog); } do { - fromlog = logchar (fp); + fromlog = logchar (fp, false); if (fromlog == EOL) break; fromgdb = gdbchar (remote_desc_in); @@ -388,12 +411,12 @@ play (FILE *fp) int fromlog; char ch; - if ((fromlog = logchar (fp)) != ' ') + if ((fromlog = logchar (fp, false)) != ' ') { sync_error (fp, "Sync error skipping blank during write to gdb", ' ', fromlog); } - while ((fromlog = logchar (fp)) != EOL) + while ((fromlog = logchar (fp, false)) != EOL) { ch = fromlog; if (write (remote_desc_out, &ch, 1) != 1) @@ -428,11 +451,12 @@ captured_main (int argc, char *argv[]) { FILE *fp; int ch, optc; - enum opts { OPT_VERSION = 1, OPT_HELP }; + enum opts { OPT_VERSION = 1, OPT_HELP, OPT_LOGGING }; static struct option longopts[] = { {"version", no_argument, nullptr, OPT_VERSION}, {"help", no_argument, nullptr, OPT_HELP}, + {"debug-logging", no_argument, nullptr, OPT_LOGGING}, {nullptr, no_argument, nullptr, 0} }; @@ -446,6 +470,9 @@ captured_main (int argc, char *argv[]) case OPT_HELP: gdbreplay_usage (stdout); exit (0); + case OPT_LOGGING: + debug_logging = true; + break; } } @@ -460,7 +487,7 @@ captured_main (int argc, char *argv[]) perror_with_name (argv[optind]); } remote_open (argv[optind + 1]); - while ((ch = logchar (fp)) != EOF) + while ((ch = logchar (fp, false)) != EOF) { switch (ch) { @@ -473,8 +500,18 @@ captured_main (int argc, char *argv[]) play (fp); break; case 'c': - /* Command executed by gdb */ - while ((ch = logchar (fp)) != EOL); + /* We want to always print the command executed by GDB. */ + if (!debug_logging) + { + fprintf (stderr, "\n"); + fprintf (stderr, "Command expected from GDB:\n"); + } + while ((ch = logchar (fp, true)) != EOL); + break; + case 'E': + if (!debug_logging) + fprintf (stderr, "E"); + while ((ch = logchar (fp, true)) != EOL); break; } }