Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [RFC] output remote protocol timestamps with "set debug remote"
@ 2008-11-14 23:21 Pedro Alves
  2008-11-19 11:37 ` Joel Brobecker
  2008-11-19 13:11 ` Daniel Jacobowitz
  0 siblings, 2 replies; 7+ messages in thread
From: Pedro Alves @ 2008-11-14 23:21 UTC (permalink / raw)
  To: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 1196 bytes --]

I've had a use for this more than once, but I never had it
in GDB proper --- always had to patch it first.  Sometimes, I'd
like to be able to easily ask a client to give us remote protocol
timestamps, to help diagnose timing issues on stubs we don't
have easy access to --- missing TCP_NODELAY, unwanted buffering,
really slow flash writing, etc., in such cases you'll easily
spot unusual > ms delays somewhere.

I'm making use of this:

 /* Debugging level.  0 is off, and non-zero values mean to print some debug
    information (higher values, more information).  */
 extern int remote_debug;

... to enable timestamps, you do "set debug remote 2".  level 1
still outputs the same as usual.

With acks:

 1226687336.526: Sending packet: $Xf7efde30,1:U#d8...
 1226687336.526: Ack

 1226687336.526: Packet received: OK

 1226687336.526: Sending packet: $X80484d5,1:�#57...
 1226687336.526: Ack

In no-ack mode (e.g., against current gdbserver):

 1226687726.796: Sending packet: $Xf7fdfe30,1:U#d9...
 1226687726.796: Packet received: OK

 1226687726.806: Sending packet: $X80484d5,1:�#57...
 1226687726.806: Packet received: OK

WDYT?

-- 
Pedro Alves

[-- Attachment #2: timings.diff --]
[-- Type: text/x-diff, Size: 2783 bytes --]

2008-11-14  Pedro Alves  <pedro@codesourcery.com>

	* remote.c (remote_vlog, remote_log): New.
	(putpkt_binary, getpkt_sane): Use remote_log.

---
 gdb/remote.c |   44 +++++++++++++++++++++++++++++++++++++-------
 1 file changed, 37 insertions(+), 7 deletions(-)

Index: src/gdb/remote.c
===================================================================
--- src.orig/gdb/remote.c	2008-08-14 23:39:56.000000000 +0100
+++ src/gdb/remote.c	2008-11-14 18:40:04.000000000 +0000
@@ -236,6 +236,37 @@ Controlling the remote inferior in async
 		    value);
 }
 
+/* See remote_log.  */
+
+static void
+remote_vlog (const char *what, va_list ap)
+{
+  if (remote_debug > 1)
+    {
+      struct timeval tv;
+
+      gettimeofday (&tv, NULL);
+      fprintf_unfiltered (gdb_stdlog, "\n%08ld.%03ld: ",
+			  tv.tv_sec, tv.tv_usec / 1000);
+    }
+
+  vfprintf_unfiltered (gdb_stdlog, what, ap);
+}
+
+/* Print WHAT to GDB_STDLOG.  If REMOTE_DEBUG is > 1 (e.g.,
+   with 'set debug remote 2'), also print the current timestamp.  */
+
+static void remote_log (const char *what, ...) ATTR_FORMAT (printf, 1, 2);
+
+static void
+remote_log (const char *what, ...)
+{
+  va_list ap;
+  va_start (ap, what);
+  remote_vlog (what, ap);
+  va_end (ap);
+}
+
 /* For "remote".  */
 
 static struct cmd_list_element *remote_cmdlist;
@@ -4817,7 +4848,7 @@ putpkt_binary (char *buf, int cnt)
       if (remote_debug)
 	{
 	  *p = '\0';
-	  fprintf_unfiltered (gdb_stdlog, "Sending packet: ");
+	  remote_log ("Sending packet: ");
 	  fputstrn_unfiltered (buf2, p - buf2, 0, gdb_stdlog);
 	  fprintf_unfiltered (gdb_stdlog, "...");
 	  gdb_flush (gdb_stdlog);
@@ -4855,21 +4886,20 @@ putpkt_binary (char *buf, int cnt)
 	    {
 	    case '+':
 	      if (remote_debug)
-		fprintf_unfiltered (gdb_stdlog, "Ack\n");
+		remote_log ("Ack\n");
 	      return 1;
 	    case '-':
 	      if (remote_debug)
-		fprintf_unfiltered (gdb_stdlog, "Nak\n");
+		remote_log ("Nak\n");
 	    case SERIAL_TIMEOUT:
 	      tcount++;
 	      if (tcount > 3)
 		return 0;
+	      remote_log ("Retransmit\n");
 	      break;		/* Retransmit buffer.  */
 	    case '$':
 	      {
-	        if (remote_debug)
-		  fprintf_unfiltered (gdb_stdlog,
-				      "Packet instead of Ack, ignoring it\n");
+		remote_log ("Packet instead of Ack, ignoring it\n");
 		/* It's probably an old response sent because an ACK
 		   was lost.  Gobble up the packet and ack it so it
 		   doesn't get retransmitted when we resend this
@@ -5168,7 +5198,7 @@ getpkt_sane (char **buf, long *sizeof_bu
 	{
 	  if (remote_debug)
 	    {
-	      fprintf_unfiltered (gdb_stdlog, "Packet received: ");
+	      remote_log ("Packet received: ");
 	      fputstrn_unfiltered (*buf, val, 0, gdb_stdlog);
 	      fprintf_unfiltered (gdb_stdlog, "\n");
 	    }

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC] output remote protocol timestamps with "set debug remote"
  2008-11-14 23:21 [RFC] output remote protocol timestamps with "set debug remote" Pedro Alves
@ 2008-11-19 11:37 ` Joel Brobecker
  2008-11-22 15:31   ` Michael Snyder
  2008-11-19 13:11 ` Daniel Jacobowitz
  1 sibling, 1 reply; 7+ messages in thread
From: Joel Brobecker @ 2008-11-19 11:37 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

> ... to enable timestamps, you do "set debug remote 2".  level 1
> still outputs the same as usual.
[...]
> WDYT?

Sounds like a very useful feature to me. And since I was at it,
I had a quick look at the code, which looks fine. I'm in favor.

> 2008-11-14  Pedro Alves  <pedro@codesourcery.com>
> 
> 	* remote.c (remote_vlog, remote_log): New.
> 	(putpkt_binary, getpkt_sane): Use remote_log.

-- 
Joel


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC] output remote protocol timestamps with "set debug remote"
  2008-11-14 23:21 [RFC] output remote protocol timestamps with "set debug remote" Pedro Alves
  2008-11-19 11:37 ` Joel Brobecker
@ 2008-11-19 13:11 ` Daniel Jacobowitz
  2008-11-19 14:07   ` Pedro Alves
  1 sibling, 1 reply; 7+ messages in thread
From: Daniel Jacobowitz @ 2008-11-19 13:11 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

On Fri, Nov 14, 2008 at 06:50:28PM +0000, Pedro Alves wrote:
> I'm making use of this:
> 
>  /* Debugging level.  0 is off, and non-zero values mean to print some debug
>     information (higher values, more information).  */
>  extern int remote_debug;
> 
> ... to enable timestamps, you do "set debug remote 2".  level 1
> still outputs the same as usual.

It's such a good idea, that it's already there :-)  "set debug
timestamp".  However, I'd never tried it with remote; it clearly
does not work right for multiple printf calls in a single debugging
message.  I'd suggest fixing that, instead.


1227044669:904148 Sending packet: 1227044669:904155 $1227044669:904161
q1227044669:904166 S1227044669:904172 y1227044669:904177
m1227044669:904182 b1227044669:904188 o1227044669:904193
l1227044669:904198 :1227044669:904205 :1227044669:904211
#1227044669:904217 51227044669:904222 b1227044669:904228
...1227044669:904279 Ack

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC] output remote protocol timestamps with "set debug remote"
  2008-11-19 13:11 ` Daniel Jacobowitz
@ 2008-11-19 14:07   ` Pedro Alves
  2008-11-19 23:07     ` Daniel Jacobowitz
  0 siblings, 1 reply; 7+ messages in thread
From: Pedro Alves @ 2008-11-19 14:07 UTC (permalink / raw)
  To: gdb-patches; +Cc: Daniel Jacobowitz

[-- Attachment #1: Type: text/plain, Size: 1989 bytes --]

On Tuesday 18 November 2008 21:45:35, Daniel Jacobowitz wrote:
> On Fri, Nov 14, 2008 at 06:50:28PM +0000, Pedro Alves wrote:
> > I'm making use of this:
> > 
> >  /* Debugging level.  0 is off, and non-zero values mean to print some debug
> >     information (higher values, more information).  */
> >  extern int remote_debug;
> > 
> > ... to enable timestamps, you do "set debug remote 2".  level 1
> > still outputs the same as usual.
> 
> It's such a good idea, that it's already there :-)  "set debug
> timestamp".  However, I'd never tried it with remote; it clearly
> does not work right for multiple printf calls in a single debugging
> message.  I'd suggest fixing that, instead.

Ah, sneaky!  I missed that going in.

> 1227044669:904148 Sending packet: 1227044669:904155 $1227044669:904161
> q1227044669:904166 S1227044669:904172 y1227044669:904177
> m1227044669:904182 b1227044669:904188 o1227044669:904193
> l1227044669:904198 :1227044669:904205 :1227044669:904211
> #1227044669:904217 51227044669:904222 b1227044669:904228
> ...1227044669:904279 Ack

That attached patch make two changes to address this.

1) Makes sure that timestamped output always ends with a newline, so we
   get this,

  un-timestamped, like before, unchanged:

    Sending packet: $m80484d1,1#67... Packet received: 51

  and timestamped:

    1227058218:708583 Sending packet: $m80484d1,1#67...
    1227058218:708675 Packet received: 51

  [ If other output other than gdb_stdlog is mixed, then you still
  don't have the nice alignment, but, that doesn't seem as bad. ]

2) Makes sure a single fprintf_unfiltered is used to dump a packet,
   so we get a single timestamp for a packet, unlike your output
   above, where there's one timestamp per octet (that's from
   fputstrn_unfiltered ending up on fprintf_unfiltered once
   per char).

Something like this?

(I'm running it through the testsuite against gdbserver with
"set debug remote 1"/"set debug timestamp" just in case).

-- 
Pedro Alves

[-- Attachment #2: remote_timestamps.diff --]
[-- Type: text/x-diff, Size: 5520 bytes --]

2008-11-19  Pedro Alves  <pedro@codesourcery.com>

	* remote.c (escape_buffer): New.
	(putpkt_binary, read_frame, getpkt_or_notif_sane_1): Use it.  Make
	sure debug output printing a packet buffer goes through a single
	fprintf_unfiltered call.
	* utils.c (vfprintf_unfiltered): If outputting timestamps, end
	output with a newline if it wasn't going to already.

---
 gdb/remote.c |   81 ++++++++++++++++++++++++++++++++++++++++++++++-------------
 gdb/utils.c  |   13 ++++++++-
 2 files changed, 75 insertions(+), 19 deletions(-)

Index: src/gdb/remote.c
===================================================================
--- src.orig/gdb/remote.c	2008-11-19 01:41:52.000000000 +0000
+++ src/gdb/remote.c	2008-11-19 01:42:26.000000000 +0000
@@ -5847,6 +5847,28 @@ remote_send (char **buf,
     error (_("Remote failure reply: %s"), *buf);
 }
 
+/* Return a pointer to an xmalloc'ed string representing an escaped
+   version of BUF, of len N.  E.g. \n is converted to \\n, \t to \\t,
+   etc.  The caller is responsible for releasing the returned
+   memory.  */
+
+static char *
+escape_buffer (const char *buf, int n)
+{
+  struct cleanup *old_chain;
+  struct ui_file *stb;
+  char *str;
+  long length;
+
+  stb = mem_fileopen ();
+  old_chain = make_cleanup_ui_file_delete (stb);
+
+  fputstrn_unfiltered (buf, n, 0, stb);
+  str = ui_file_xstrdup (stb, &length);
+  do_cleanups (old_chain);
+  return str;
+}
+
 /* Display a null-terminated packet on stdout, for debugging, using C
    string notation.  */
 
@@ -5919,11 +5941,15 @@ putpkt_binary (char *buf, int cnt)
 
       if (remote_debug)
 	{
+	  struct cleanup *old_chain;
+	  char *str;
+
 	  *p = '\0';
-	  fprintf_unfiltered (gdb_stdlog, "Sending packet: ");
-	  fputstrn_unfiltered (buf2, p - buf2, 0, gdb_stdlog);
-	  fprintf_unfiltered (gdb_stdlog, "...");
+	  str = escape_buffer (buf2, p - buf2);
+	  old_chain = make_cleanup (xfree, str);
+	  fprintf_unfiltered (gdb_stdlog, "Sending packet: %s...", str);
 	  gdb_flush (gdb_stdlog);
+	  do_cleanups (old_chain);
 	}
       if (serial_write (remote_desc, buf2, p - buf2))
 	perror_with_name (_("putpkt: write failed"));
@@ -5997,9 +6023,15 @@ putpkt_binary (char *buf, int cnt)
 		  {
 		    if (remote_debug)
 		      {
-			fprintf_unfiltered (gdb_stdlog, "  Notification received: ");
-			fputstrn_unfiltered (rs->buf, val, 0, gdb_stdlog);
-			fprintf_unfiltered (gdb_stdlog, "\n");
+			struct cleanup *old_chain;
+			char *str;
+
+			str = escape_buffer (rs->buf, val);
+			old_chain = make_cleanup (xfree, str);
+			fprintf_unfiltered (gdb_stdlog,
+					    "  Notification received: %s\n",
+					    str);
+			do_cleanups (old_chain);
 		      }
 		    handle_notification (rs->buf, val);
 		    /* We're in sync now, rewait for the ack.  */
@@ -6163,11 +6195,16 @@ read_frame (char **buf_p,
 
 	    if (remote_debug)
 	      {
-		fprintf_filtered (gdb_stdlog,
-			      "Bad checksum, sentsum=0x%x, csum=0x%x, buf=",
-				  pktcsum, csum);
-		fputstrn_filtered (buf, bc, 0, gdb_stdlog);
-		fputs_filtered ("\n", gdb_stdlog);
+		struct cleanup *old_chain;
+		char *str;
+
+		str = escape_buffer (buf, bc);
+		old_chain = make_cleanup (xfree, str);
+		fprintf_unfiltered (gdb_stdlog,
+				    "\
+Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
+				    pktcsum, csum, str);
+		do_cleanups (old_chain);
 	      }
 	    /* Number of characters in buffer ignoring trailing
                NULL.  */
@@ -6340,9 +6377,13 @@ getpkt_or_notif_sane_1 (char **buf, long
 	{
 	  if (remote_debug)
 	    {
-	      fprintf_unfiltered (gdb_stdlog, "Packet received: ");
-	      fputstrn_unfiltered (*buf, val, 0, gdb_stdlog);
-	      fprintf_unfiltered (gdb_stdlog, "\n");
+	     struct cleanup *old_chain;
+	     char *str;
+
+	     str = escape_buffer (*buf, val);
+	     old_chain = make_cleanup (xfree, str);
+	     fprintf_unfiltered (gdb_stdlog, "Packet received: %s\n", str);
+	     do_cleanups (old_chain);
 	    }
 
 	  /* Skip the ack char if we're in no-ack mode.  */
@@ -6359,9 +6400,15 @@ getpkt_or_notif_sane_1 (char **buf, long
 
 	  if (remote_debug)
 	    {
-	      fprintf_unfiltered (gdb_stdlog, "  Notification received: ");
-	      fputstrn_unfiltered (*buf, val, 0, gdb_stdlog);
-	      fprintf_unfiltered (gdb_stdlog, "\n");
+	      struct cleanup *old_chain;
+	      char *str;
+
+	      str = escape_buffer (*buf, val);
+	      old_chain = make_cleanup (xfree, str);
+	      fprintf_unfiltered (gdb_stdlog,
+				  "  Notification received: %s\n",
+				  str);
+	      do_cleanups (old_chain);
 	    }
 
 	  handle_notification (*buf, val);
Index: src/gdb/utils.c
===================================================================
--- src.orig/gdb/utils.c	2008-11-19 01:41:52.000000000 +0000
+++ src/gdb/utils.c	2008-11-19 01:42:26.000000000 +0000
@@ -2286,13 +2286,22 @@ vfprintf_unfiltered (struct ui_file *str
     {
       struct timeval tm;
       char *timestamp;
+      int len, need_nl;
 
       gettimeofday (&tm, NULL);
-      timestamp = xstrprintf ("%ld:%ld ", (long) tm.tv_sec, (long) tm.tv_usec);
+
+      len = strlen (linebuffer);
+      need_nl = (len > 0 && linebuffer[len - 1] != '\n');
+
+      timestamp = xstrprintf ("%ld:%ld %s%s",
+			      (long) tm.tv_sec, (long) tm.tv_usec,
+			      linebuffer,
+			      need_nl ? "\n": "");
       make_cleanup (xfree, timestamp);
       fputs_unfiltered (timestamp, stream);
     }
-  fputs_unfiltered (linebuffer, stream);
+  else
+    fputs_unfiltered (linebuffer, stream);
   do_cleanups (old_cleanups);
 }
 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC] output remote protocol timestamps with "set debug remote"
  2008-11-19 14:07   ` Pedro Alves
@ 2008-11-19 23:07     ` Daniel Jacobowitz
  2008-11-20  1:46       ` Pedro Alves
  0 siblings, 1 reply; 7+ messages in thread
From: Daniel Jacobowitz @ 2008-11-19 23:07 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

On Wed, Nov 19, 2008 at 01:46:42AM +0000, Pedro Alves wrote:
> Something like this?

Looks good to me!

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC] output remote protocol timestamps with "set debug remote"
  2008-11-19 23:07     ` Daniel Jacobowitz
@ 2008-11-20  1:46       ` Pedro Alves
  0 siblings, 0 replies; 7+ messages in thread
From: Pedro Alves @ 2008-11-20  1:46 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: gdb-patches

Thanks guys, I've checked it in.

-- 
Pedro Alves


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC] output remote protocol timestamps with "set debug remote"
  2008-11-19 11:37 ` Joel Brobecker
@ 2008-11-22 15:31   ` Michael Snyder
  0 siblings, 0 replies; 7+ messages in thread
From: Michael Snyder @ 2008-11-22 15:31 UTC (permalink / raw)
  To: Joel Brobecker; +Cc: Pedro Alves, gdb-patches

Joel Brobecker wrote:
>> ... to enable timestamps, you do "set debug remote 2".  level 1
>> still outputs the same as usual.
> [...]
>> WDYT?
> 
> Sounds like a very useful feature to me. And since I was at it,
> I had a quick look at the code, which looks fine. I'm in favor.

Me too.  My only question is, now that we're distinguishing
more than just "!=0", should we define some "verbosity levels"?


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2008-11-21 19:19 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-11-14 23:21 [RFC] output remote protocol timestamps with "set debug remote" Pedro Alves
2008-11-19 11:37 ` Joel Brobecker
2008-11-22 15:31   ` Michael Snyder
2008-11-19 13:11 ` Daniel Jacobowitz
2008-11-19 14:07   ` Pedro Alves
2008-11-19 23:07     ` Daniel Jacobowitz
2008-11-20  1:46       ` Pedro Alves

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox