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.
This commit is contained in:
Sandra Loosemore 2008-08-12 15:18:31 +00:00
parent b099ab9fcd
commit a6f3e723d3
9 changed files with 255 additions and 17 deletions

View 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):

View File

@ -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

View 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>

View 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

View 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.

View 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;

View 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:

View 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);

View 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;
}
@ -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