gdb/doc/
authorSandra Loosemore <sandra@codesourcery.com>
Tue, 12 Aug 2008 15:18:31 +0000 (15:18 +0000)
committerSandra Loosemore <sandra@codesourcery.com>
Tue, 12 Aug 2008 15:18:31 +0000 (15:18 +0000)
2008-08-12  Sandra Loosemore  <sandra@codesourcery.com>

* gdb.texinfo (Remote Configuration): Document set remote noack-packet.
(Remote Protocol): Add Packet Acknowledgment to menu.
(Overview): Mention +/- can be disabled, and point to new section
where this is discussed in detail.
(General Query Packets): Document QStartNoAckMode packet, and
corresponding qSupported reply.
(Packet Acknowledgment): New section.

gdb/
2008-08-12  Pedro Alves  <pedro@codesourcery.com>

Add no-ack mode to the remote protocol --- optionally stop ACKing
packets and responses when we have a reliable communication
medium.

Based on Apple's GDB, by Jason Molenda <jmolenda@apple.com>

* remote.c (struct remote_state): Add noack_mode field.
(PACKET_QStartNoAckMode): New.
(remote_start_remote): Don't any outstanding packet here.
(remote_open_1): Clear noack_mode.  Ack any outstanding packet
here.  Activate noack mode if requested.
(remote_protocol_features): Add QStartNoAckMode.
(remote_open_1):
(putpkt_binary): Don't send ack in noack mode.
(read_frame): Don't recompute the checksum in noack mode.
(getpkt_sane): Skip sending ack if in noack mode.
(_initialize_remote): Add set/show remote noack mode.
* NEWS:  Note the new features.

gdb/gdbserver/
2008-08-12  Pedro Alves  <pedro@codesourcery.com>

* remote-utils.c (noack_mode, transport_is_reliable): New globals.
(remote_open): Set or clear transport_is_reliable.
(putpkt_binary): Don't expect acks in noack mode.
(getpkt): Don't send ack/nac in noack mode.
* server.c (handle_general_set): Handle QStartNoAckMode.
(handle_query): If connected by tcp pass QStartNoAckMode+ in
qSupported.
(main): Reset noack_mode on every connection.
* server.h (noack_mode): Declare.

gdb/ChangeLog
gdb/NEWS
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/gdbserver/ChangeLog
gdb/gdbserver/remote-utils.c
gdb/gdbserver/server.c
gdb/gdbserver/server.h
gdb/remote.c

index d7f071b..f734aed 100644 (file)
@@ -1,3 +1,24 @@
+2008-08-12  Pedro Alves  <pedro@codesourcery.com>
+
+       Add no-ack mode to the remote protocol --- optionally stop ACKing
+       packets and responses when we have a reliable communication
+       medium.
+
+       Based on Apple's GDB, by Jason Molenda <jmolenda@apple.com>
+
+       * remote.c (struct remote_state): Add noack_mode field.
+       (PACKET_QStartNoAckMode): New.
+       (remote_start_remote): Don't any outstanding packet here.
+       (remote_open_1): Clear noack_mode.  Ack any outstanding packet
+       here.  Activate noack mode if requested.
+       (remote_protocol_features): Add QStartNoAckMode.
+       (remote_open_1):
+       (putpkt_binary): Don't send ack in noack mode.
+       (read_frame): Don't recompute the checksum in noack mode.
+       (getpkt_sane): Skip sending ack if in noack mode.
+       (_initialize_remote): Add set/show remote noack mode.
+       * NEWS:  Note the new features.
+
 2008-08-11  Kevin Buettner  <kevinb@redhat.com>
 
        * rs6000-tdep.c (BL_MASK, BL_INSTRUCTION, BL_DISPLACEMENT_MASK):
index eb2e280..b7ef61c 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -22,6 +22,11 @@ completions will be "f1" and "f2".
 qSearch:memory:
   Search memory for a sequence of bytes.
 
+QStartNoAckMode
+  Turn off `+'/`-' protocol acknowledgments to permit more efficient
+  operation over reliable transport links.  Use of this packet is
+  controlled by the `set remote noack-packet' command.
+
 * Removed remote protocol undocumented extension
 
   An undocumented extension to the remote protocol's `S' stop reply
@@ -62,6 +67,9 @@ have also been fixed.
   gdbserver executable to debug both 32-bit and 64-bit programs.
   (This requires gdbserver itself to be built as a 64-bit executable.)
 
+  - gdbserver uses the new noack protocol mode for TCP connections to
+  reduce communications latency, if also supported and enabled in GDB.
+
 * Python scripting
 
   GDB now has support for scripting using Python.  Whether this is
index 872fe60..7a434f3 100644 (file)
@@ -1,3 +1,13 @@
+2008-08-12  Sandra Loosemore  <sandra@codesourcery.com>
+
+       * gdb.texinfo (Remote Configuration): Document set remote noack-packet.
+       (Remote Protocol): Add Packet Acknowledgment to menu.
+       (Overview): Mention +/- can be disabled, and point to new section
+       where this is discussed in detail.
+       (General Query Packets): Document QStartNoAckMode packet, and
+       corresponding qSupported reply.
+       (Packet Acknowledgment): New section.
+
 2008-08-11  Sandra Loosemore  <sandra@codesourcery.com>
            Pedro Alves  <pedro@codesourcery.com>
 
index 72455f3..8cbef2f 100644 (file)
@@ -13949,6 +13949,10 @@ are:
 @item @code{hostio-unlink-packet}
 @tab @code{vFile:unlink}
 @tab @code{remote delete}
+
+@item @code{noack-packet}
+@tab @code{QStartNoAckMode}
+@tab Packet acknowledgment
 @end multitable
 
 @node Remote Stub
@@ -15631,7 +15635,7 @@ As usual, you can inquire about the @code{mipsfpu} variable with
 You can control the timeout used while waiting for a packet, in the MIPS
 remote protocol, with the @code{set timeout @var{seconds}} command.  The
 default is 5 seconds.  Similarly, you can control the timeout used while
-waiting for an acknowledgement of a packet with the @code{set
+waiting for an acknowledgment of a packet with the @code{set
 retransmit-timeout @var{seconds}} command.  The default is 3 seconds.
 You can inspect both values with @code{show timeout} and @code{show
 retransmit-timeout}.  (These commands are @emph{only} available when
@@ -24144,6 +24148,7 @@ Show the current setting of the target wait timeout.
 * Tracepoint Packets::
 * Host I/O Packets::
 * Interrupts::
+* Packet Acknowledgment::
 * Examples::
 * File-I/O Remote Protocol Extension::
 * Library List Format::
@@ -24193,7 +24198,6 @@ That @var{sequence-id} was appended to the acknowledgment.  @value{GDBN}
 has never output @var{sequence-id}s.  Stubs that handle packets added
 since @value{GDBN} 5.0 must not accept @var{sequence-id}.
 
-@cindex acknowledgment, for @value{GDBN} remote
 When either the host or the target machine receives a packet, the first
 response expected is an acknowledgment: either @samp{+} (to indicate
 the package was received correctly) or @samp{-} (to request
@@ -24205,6 +24209,10 @@ retransmission):
 @end smallexample
 @noindent
 
+The @samp{+}/@samp{-} acknowledgments can be disabled
+once a connection is established.
+@xref{Packet Acknowledgment}, for details.
+
 The host (@value{GDBN}) sends @var{command}s, and the target (the
 debugging stub incorporated in your program) sends a @var{response}.  In
 the case of step and continue @var{command}s, the response is only sent
@@ -25259,6 +25267,23 @@ A badly formed request or an error was encountered while searching memory.
 An empty reply indicates that @samp{qSearch:memory} is not recognized.
 @end table
 
+@item QStartNoAckMode
+@cindex @samp{QStartNoAckMode} packet
+@anchor{QStartNoAckMode}
+Request that the remote stub disable the normal @samp{+}/@samp{-}
+protocol acknowledgments (@pxref{Packet Acknowledgment}).
+
+Reply:
+@table @samp
+@item OK
+The stub has switched to no-acknowledgment mode.
+@value{GDBN} acknowledges this reponse,
+but neither the stub nor @value{GDBN} shall send or expect further
+@samp{+}/@samp{-} acknowledgments in the current connection.
+@item
+An empty reply indicates that the stub does not support no-acknowledgment mode.
+@end table
+
 @item qSupported @r{[}:@var{gdbfeature} @r{[};@var{gdbfeature}@r{]}@dots{} @r{]}
 @cindex supported packets, remote query
 @cindex features of the remote protocol
@@ -25400,6 +25425,11 @@ These are the currently defined stub features and their properties:
 @tab @samp{-}
 @tab Yes
 
+@item @samp{QStartNoAckMode}
+@tab No
+@tab @samp{-}
+@tab Yes
+
 @end multitable
 
 These are the currently defined stub features, in more detail:
@@ -25444,6 +25474,10 @@ The remote stub understands the @samp{qXfer:spu:write} packet
 The remote stub understands the @samp{QPassSignals} packet
 (@pxref{QPassSignals}).
 
+@item QStartNoAckMode
+The remote stub understands the @samp{QStartNoAckMode} packet and
+prefers to operate in no-acknowledgment mode.  @xref{Packet Acknowledgment}.
+
 @end table
 
 @item qSymbol::
@@ -25988,6 +26022,50 @@ Reply Packets (@pxref{Stop Reply Packets}) to @value{GDBN} as a result
 of successfully stopping the program.  Interrupts received while the
 program is stopped will be discarded.
 
+@node Packet Acknowledgment
+@section Packet Acknowledgment
+
+@cindex acknowledgment, for @value{GDBN} remote
+@cindex packet acknowledgment, for @value{GDBN} remote
+By default, when either the host or the target machine receives a packet,
+the first response expected is an acknowledgment: either @samp{+} (to indicate
+the package was received correctly) or @samp{-} (to request retransmission).
+This mechanism allows the @value{GDBN} remote protocol to operate over
+unreliable transport mechanisms, such as a serial line.
+
+In cases where the transport mechanism is itself reliable (such as a pipe or
+TCP connection), the @samp{+}/@samp{-} acknowledgments are redundant.
+It may be desirable to disable them in that case to reduce communication
+overhead, or for other reasons.  This can be accomplished by means of the
+@samp{QStartNoAckMode} packet; @pxref{QStartNoAckMode}.
+
+When in no-acknowledgment mode, neither the stub nor @value{GDBN} shall send or
+expect @samp{+}/@samp{-} protocol acknowledgments.  The packet
+and response format still includes the normal checksum, as described in
+@ref{Overview}, but the checksum may be ignored by the receiver.
+
+If the stub supports @samp{QStartNoAckMode} and prefers to operate in
+no-acknowledgment mode, it should report that to @value{GDBN}
+by including @samp{QStartNoAckMode+} in its response to @samp{qSupported};
+@pxref{qSupported}.
+If @value{GDBN} also supports @samp{QStartNoAckMode} and it has not been
+disabled via the @code{set remote noack-packet off} command
+(@pxref{Remote Configuration}),
+@value{GDBN} may then send a @samp{QStartNoAckMode} packet to the stub.
+Only then may the stub actually turn off packet acknowledgments.
+@value{GDBN} sends a final @samp{+} acknowledgment of the stub's @samp{OK}
+response, which can be safely ignored by the stub.
+
+Note that @code{set remote noack-packet} command only affects negotiation
+between @value{GDBN} and the stub when subsequent connections are made;
+it does not affect the protocol acknowledgment state for any current
+connection.
+Since @samp{+}/@samp{-} acknowledgments are enabled by default when a
+new connection is established,
+there is also no protocol request to re-enable the acknowledgments
+for the current connection, once disabled.
+
+
 @node Examples
 @section Examples
 
index 8e61981..a4ea4be 100644 (file)
@@ -1,3 +1,15 @@
+2008-08-12  Pedro Alves  <pedro@codesourcery.com>
+
+       * remote-utils.c (noack_mode, transport_is_reliable): New globals.
+       (remote_open): Set or clear transport_is_reliable.
+       (putpkt_binary): Don't expect acks in noack mode.
+       (getpkt): Don't send ack/nac in noack mode.
+       * server.c (handle_general_set): Handle QStartNoAckMode.
+       (handle_query): If connected by tcp pass QStartNoAckMode+ in
+       qSupported.
+       (main): Reset noack_mode on every connection.
+       * server.h (noack_mode): Declare.
+
 2008-08-07  Ralf Wildenhues  <Ralf.Wildenhues@gmx.de>
 
        * Makefile.in (GDBREPLAY_OBS): New variable.
index e062be8..b5665f5 100644 (file)
@@ -99,6 +99,11 @@ static int remote_desc = INVALID_DESCRIPTOR;
 extern int using_threads;
 extern int debug_threads;
 
+/* If true, then GDB has requested noack mode.  */
+int noack_mode = 0;
+/* If true, then we tell GDB to use noack mode by default.  */
+int transport_is_reliable = 0;
+
 #ifdef USE_WIN32API
 # define read(fd, buf, len) recv (fd, (char *) buf, len, 0)
 # define write(fd, buf, len) send (fd, (char *) buf, len, 0)
@@ -181,6 +186,8 @@ remote_open (char *name)
 
       fprintf (stderr, "Remote debugging using %s\n", name);
 #endif /* USE_WIN32API */
+
+      transport_is_reliable = 0;
     }
   else
     {
@@ -267,6 +274,8 @@ remote_open (char *name)
       /* Convert IP address to string.  */
       fprintf (stderr, "Remote debugging from host %s\n", 
          inet_ntoa (sockaddr.sin_addr));
+
+      transport_is_reliable = 1;
     }
 
 #if defined(F_SETFL) && defined (FASYNC)
@@ -551,6 +560,17 @@ putpkt_binary (char *buf, int cnt)
          return -1;
        }
 
+      if (noack_mode)
+       {
+         /* Don't expect an ack then.  */
+         if (remote_debug)
+           {
+             fprintf (stderr, "putpkt (\"%s\"); [noack mode]\n", buf2);
+             fflush (stderr);
+           }
+         break;
+       }
+
       if (remote_debug)
        {
          fprintf (stderr, "putpkt (\"%s\"); [looking for ack]\n", buf2);
@@ -774,23 +794,34 @@ getpkt (char *buf)
       if (csum == (c1 << 4) + c2)
        break;
 
+      if (noack_mode)
+       {
+         fprintf (stderr, "Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s [no-ack-mode, Bad medium?]\n",
+                  (c1 << 4) + c2, csum, buf);
+         /* Not much we can do, GDB wasn't expecting an ack/nac.  */
+         break;
+       }
+
       fprintf (stderr, "Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
               (c1 << 4) + c2, csum, buf);
       write (remote_desc, "-", 1);
     }
 
-  if (remote_debug)
+  if (!noack_mode)
     {
-      fprintf (stderr, "getpkt (\"%s\");  [sending ack] \n", buf);
-      fflush (stderr);
-    }
+      if (remote_debug)
+       {
+         fprintf (stderr, "getpkt (\"%s\");  [sending ack] \n", buf);
+         fflush (stderr);
+       }
 
-  write (remote_desc, "+", 1);
+      write (remote_desc, "+", 1);
 
-  if (remote_debug)
-    {
-      fprintf (stderr, "[sent ack]\n");
-      fflush (stderr);
+      if (remote_debug)
+       {
+         fprintf (stderr, "[sent ack]\n");
+         fflush (stderr);
+       }
     }
 
   return bp - buf;
index 1fa1694..60df3d8 100644 (file)
@@ -270,6 +270,19 @@ handle_general_set (char *own_buf)
       return;
     }
 
+  if (strcmp (own_buf, "QStartNoAckMode") == 0)
+    {
+      if (remote_debug)
+       {
+         fprintf (stderr, "[noack mode enabled]\n");
+         fflush (stderr);
+       }
+
+      noack_mode = 1;
+      write_ok (own_buf);
+      return;
+    }
+
   /* Otherwise we didn't know what packet it was.  Say we didn't
      understand it.  */
   own_buf[0] = 0;
@@ -777,6 +790,8 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
         qXfer:feature:read at all, we will never be re-queried.  */
       strcat (own_buf, ";qXfer:features:read+");
 
+      if (transport_is_reliable)
+       strcat (own_buf, ";QStartNoAckMode+");
       return;
     }
 
@@ -1447,6 +1462,7 @@ main (int argc, char *argv[])
 
   while (1)
     {
+      noack_mode = 0;
       remote_open (port);
 
     restart:
index b519696..817b5c4 100644 (file)
@@ -175,6 +175,8 @@ extern void hostio_last_error_from_errno (char *own_buf);
 
 extern int remote_debug;
 extern int all_symbols_looked_up;
+extern int noack_mode;
+extern int transport_is_reliable;
 
 int putpkt (char *buf);
 int putpkt_binary (char *buf, int len);
index 2e626a9..2782d05 100644 (file)
@@ -274,6 +274,11 @@ struct remote_state
      skip calling getpkt.  This flag is set when BUF contains a
      stop reply packet and the target is not waiting.  */
   int cached_wait_status;
+
+  /* True, if in no ack mode.  That is, neither GDB nor the stub will
+     expect acks from each other.  The connection is assumed to be
+     reliable.  */
+  int noack_mode;
 };
 
 /* This data could be associated with a target, but we do not always
@@ -960,6 +965,7 @@ enum {
   PACKET_qSearch_memory,
   PACKET_vAttach,
   PACKET_vRun,
+  PACKET_QStartNoAckMode,
   PACKET_MAX
 };
 
@@ -2297,9 +2303,6 @@ remote_start_remote (struct ui_out *uiout, void *opaque)
 
   immediate_quit++;            /* Allow user to interrupt it.  */
 
-  /* Ack any packet which the remote side has already sent.  */
-  serial_write (remote_desc, "+", 1);
-
   /* Check whether the target is running now.  */
   putpkt ("?");
   getpkt (&rs->buf, &rs->buf_size, 0);
@@ -2557,6 +2560,8 @@ static struct protocol_feature remote_protocol_features[] = {
     PACKET_qXfer_spu_write },
   { "QPassSignals", PACKET_DISABLE, remote_supported_packet,
     PACKET_QPassSignals },
+  { "QStartNoAckMode", PACKET_DISABLE, remote_supported_packet,
+    PACKET_QStartNoAckMode },
 };
 
 static void
@@ -2690,6 +2695,8 @@ static void
 remote_open_1 (char *name, int from_tty, struct target_ops *target, int extended_p)
 {
   struct remote_state *rs = get_remote_state ();
+  struct packet_config *noack_config;
+
   if (name == 0)
     error (_("To open a remote debug connection, you need to specify what\n"
           "serial device is attached to the remote system\n"
@@ -2771,6 +2778,7 @@ remote_open_1 (char *name, int from_tty, struct target_ops *target, int extended
      remote_query_supported or as they are needed.  */
   init_all_packet_configs ();
   rs->explicit_packet_size = 0;
+  rs->noack_mode = 0;
 
   general_thread = not_sent_ptid;
   continue_thread = not_sent_ptid;
@@ -2779,11 +2787,39 @@ remote_open_1 (char *name, int from_tty, struct target_ops *target, int extended
   use_threadinfo_query = 1;
   use_threadextra_query = 1;
 
+  /* Ack any packet which the remote side has already sent.  */
+  serial_write (remote_desc, "+", 1);
+
   /* The first packet we send to the target is the optional "supported
      packets" request.  If the target can answer this, it will tell us
      which later probes to skip.  */
   remote_query_supported ();
 
+  /* Next, we possibly activate noack mode.
+
+     If the QStartNoAckMode packet configuration is set to AUTO,
+     enable noack mode if the stub reported a wish for it with
+     qSupported.
+
+     If set to TRUE, then enable noack mode even if the stub didn't
+     report it in qSupported.  If the stub doesn't reply OK, the
+     session ends with an error.
+
+     If FALSE, then don't activate noack mode, regardless of what the
+     stub claimed should be the default with qSupported.  */
+
+  noack_config = &remote_protocol_packets[PACKET_QStartNoAckMode];
+
+  if (noack_config->detect == AUTO_BOOLEAN_TRUE
+      || (noack_config->detect == AUTO_BOOLEAN_AUTO
+         && noack_config->support == PACKET_ENABLE))
+    {
+      putpkt ("QStartNoAckMode");
+      getpkt (&rs->buf, &rs->buf_size, 0);
+      if (packet_ok (rs->buf, noack_config) == PACKET_OK)
+       rs->noack_mode = 1;
+    }
+
   /* Next, if the target can specify a description, read it.  We do
      this before anything involving memory or registers.  */
   target_find_description ();
@@ -4789,6 +4825,11 @@ putpkt_binary (char *buf, int cnt)
       if (serial_write (remote_desc, buf2, p - buf2))
        perror_with_name (_("putpkt: write failed"));
 
+      /* If this is a no acks version of the remote protocol, send the
+        packet and move on.  */
+      if (rs->noack_mode)
+        break;
+
       /* Read until either a timeout occurs (-2) or '+' is read.  */
       while (1)
        {
@@ -4865,6 +4906,7 @@ putpkt_binary (char *buf, int cnt)
        }
 #endif
     }
+  return 0;
 }
 
 /* Come here after finding the start of a frame when we expected an
@@ -4920,6 +4962,7 @@ read_frame (char **buf_p,
   long bc;
   int c;
   char *buf = *buf_p;
+  struct remote_state *rs = get_remote_state ();
 
   csum = 0;
   bc = 0;
@@ -4965,6 +5008,12 @@ read_frame (char **buf_p,
                return -1;
              }
 
+           /* Don't recompute the checksum; with no ack packets we
+              don't have any way to indicate a packet retransmission
+              is necessary.  */
+           if (rs->noack_mode)
+             return bc;
+
            pktcsum = (fromhex (check_0) << 4) | fromhex (check_1);
            if (csum == pktcsum)
               return bc;
@@ -5123,20 +5172,28 @@ getpkt_sane (char **buf, long *sizeof_buf, int forever)
              fputstrn_unfiltered (*buf, val, 0, gdb_stdlog);
              fprintf_unfiltered (gdb_stdlog, "\n");
            }
-         serial_write (remote_desc, "+", 1);
+
+         /* Skip the ack char if we're in no-ack mode.  */
+         if (!rs->noack_mode)
+           serial_write (remote_desc, "+", 1);
          return val;
        }
 
       /* Try the whole thing again.  */
     retry:
-      serial_write (remote_desc, "-", 1);
+      /* Skip the nack char if we're in no-ack mode.  */
+      if (!rs->noack_mode)
+       serial_write (remote_desc, "-", 1);
     }
 
   /* We have tried hard enough, and just can't receive the packet.
      Give up.  */
 
   printf_unfiltered (_("Ignoring packet error, continuing...\n"));
-  serial_write (remote_desc, "+", 1);
+
+  /* Skip the ack char if we're in no-ack mode.  */
+  if (!rs->noack_mode)
+    serial_write (remote_desc, "+", 1);
   return -1;
 }
 \f
@@ -7531,6 +7588,9 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
   add_packet_config_cmd (&remote_protocol_packets[PACKET_vRun],
                         "vRun", "run", 0);
 
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_QStartNoAckMode],
+                        "QStartNoAckMode", "noack", 0);
+
   /* Keep the old ``set remote Z-packet ...'' working.  Each individual
      Z sub-packet has its own set and show commands, but users may
      have sets to this variable in their .gdbinit files (or in their