This is the mail archive of the
gdb@sourceware.org
mailing list for the GDB project.
[remote protocol] Notification packets for non-stop mode
- From: Pedro Alves <pedro at codesourcery dot com>
- To: gdb at sourceware dot org
- Date: Tue, 15 Jul 2008 23:02:53 +0100
- Subject: [remote protocol] Notification packets for non-stop mode
Hi,
Long story short:
Attached there's a proposal to add out of band notification support
to the remote protocol, useful in several scenarios. Specifically,
we're interested in adding remote protocol support for non-stop mode
on top of them.
-----
Long story:
As discussed a bit on the no-ack mode thread, we're working on
adding remote protocol support for non-stop debugging.
In the standard remote protocol, the stub reports stops in reply
to GDB's resume commands. That is, for example,
--> vCont
<-- T05
That is, stop replies, are, as they're name implies, replies to
GDB's commands.
This is adjusted to the all-stop behavior, which was the only
mode GDB operated until, until recently, when we the non-stop
mode as added.
In non-stop mode, however, threads can be stepped, left running,
stopped, independently of each other. GDB wants to be acknowledged
of stops at any time. E.g., what we want is something conceptually
similar to this (ignore vConts not being aggregated in a
single request) :
--> vCont;s:1
<-- OK
--> vCont;c:2
<-- OK
--> vCont;c:3
<-- OK
<-- T05;thread:1 (single-step complete)
<-- T05;thread:2 (thread 2 hits a break)
<-- T05;thread:3 (... and thread 3 hits another break)
This assumes the stub replies back the thread state changes as
they happen. The alternative of having GDB poll the remote side
for changes, has too much overhead associated to be considered.
Of course, the example above was a simplification. Shortly
after handling the first stop event (single-step complete), GDB
will want to issue requests on the stopped thread, most likely
register reads, memory reads/writes, breakpoint removals.
These can and will happen approximately simultaneously with
the other stop notifications that follow.
There is a problem with that, related to remote protocol
acknowledgements. As Daniel explained here:
http://sourceware.org/ml/gdb/2008-07/msg00097.html
... and I quote him:
"The current GDB protocol has very simple state. At any moment, it is
either GDB's turn or the remote's turn to send events. Both sides
never simultaneously think they have the token. Sometimes neither
side thinks they have the token - either when a message is on the
wire, or else when a message has been lost. Normally a timeout comes
to the rescue.
Non-stop is incompatible with this. GDB can have the normal protocol
token, for instance if it is about to send a memory read. At the same
time the debug agent can send packets. This has to be the case;
otherwise GDB would have to frequently poll for state changes, which
would introduce too much overhead and traffic.
The result of this is that the acks become ambiguous in the presence
of an unreliable or antagonistically delayed transport. For instance,
if GDB sends a memory write, the stub acks it, the stub replies with
OK, and then GDB's ack is delayed. Existing implementations of the
protocol will resend the OK in this case, assuming the message was
lost - from stub side that's indistinguishable from ack lost. GDB's
long-delayed ACK arrives on the stub at the same time the OK arrives
at GDB. GDB must ack again - it doesn't know whether the first ack
ever made it through, and if it doesn't ack now then the stub might
keep resending that OK until it gets through. So now GDB sends an
ack. Simultaneously the stub sends a stop reply indicating that some
other thread has stopped. When it receives the ack, it thinks GDB saw
the stop reply and does not resend it. But GDB hasn't seen it yet,
and if it is dropped the conversation is now out of sync. GDB will
hang around waiting for an event that has already been reported."
The issue above centers all around remote protocol acks. Our initial
way around it, was to simply disable acks altogheter. Although
still useful to do that when the transport is reliable, even in all-stop
mode, this had the disadvantage of requiring more effort and layers
to enable non-stop in non-reliable transports, like serial debugging.
An alternative, which we believe is the right direction, is to implement
out of band notifications. These are special packets, similar, bug
distinguishable from other packets, but which do not require
acknowledgement. Of course, since they are unreliable in nature,
any mechanism loss intolerant implemented on top of them should
handle notification loss in another form.
These out of band notifications aren't actually something new to us. Jim
Blandy here at CodeSourcery had already implemented this notification
support for something else -- namely, progress reporting for flash writing,
which can be a lengthy operation. Something similar to:
%Progress:part:while:message_string
The mechanism we're proposing is extensible, and somewhat independant
of non-stop mode, hence we're posting it separately.
Attached is a specification for notification packets, on which
we're planning to build stop notifications similar to:
%Stop:T0503:deadbeef;thread:1
Naturally, GDB can't afford to lose stop notifications, and non-stop
will require more changes than this. We'll address all of that in
a follow up proposal for non-stop remote protocol extensions.
Please don't feel too attached to the actual stop notification shown
above, as that can be changed independently of the base
notification mechanism.
We'd very much like to hear comments on the approach taken.
--
Pedro Alves
gdb/doc/
2008-07-15 Jim Blandy <jimb@codesourcery.com>
* doc/gdb.texinfo (Notification Packets): New section.
(Remote Protocol): Update menu.
(Overview): Mention exception for notification packets.
---
gdb/doc/gdb.texinfo | 49 +++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 47 insertions(+), 2 deletions(-)
Index: src/gdb/doc/gdb.texinfo
===================================================================
--- src.orig/gdb/doc/gdb.texinfo 2008-07-15 18:16:16.000000000 +0100
+++ src/gdb/doc/gdb.texinfo 2008-07-15 18:23:10.000000000 +0100
@@ -23770,6 +23770,7 @@ Show the current setting of the target w
* Tracepoint Packets::
* Host I/O Packets::
* Interrupts::
+* Notification Packets::
* Examples::
* File-I/O Remote Protocol Extension::
* Library List Format::
@@ -23790,8 +23791,9 @@ transmitted and received data, respectiv
@cindex protocol, @value{GDBN} remote serial
@cindex serial protocol, @value{GDBN} remote
@cindex remote serial protocol
-All @value{GDBN} commands and responses (other than acknowledgments) are
-sent as a @var{packet}. A @var{packet} is introduced with the character
+All @value{GDBN} commands and responses (other than acknowledgments
+and notifications, @pxref{Notification Packets}) are sent as a
+@var{packet}. A @var{packet} is introduced with the character
@samp{$}, the actual @var{packet-data}, and the terminating character
@samp{#} followed by a two-digit @var{checksum}:
@@ -25614,6 +25616,49 @@ Reply Packets (@pxref{Stop Reply Packets
of successfully stopping the program. Interrupts received while the
program is stopped will be discarded.
+
+@node Notification Packets
+@section Notification Packets
+@cindex notification packets
+@cindex packets, notification
+@cindex notifications
+
+The @value{GDBN} remote serial protocol includes @dfn{notifications},
+packets that require no acknowledgement. Both the GDB and the stub
+may send notifications (although the only notifications defined at
+present are sent by the stub). Notifications carry information
+without incurring the round-trip latency of an acknowledgement, and so
+are useful for low-impact communications where occasional packet loss
+is not a problem.
+
+A notification packet has the form @samp{% @var{data} #
+@var{checksum}}, where @var{data} is the content of the notification,
+and @var{checksum} is a checksum of @var{data}, computed and formatted
+as for ordinary @value{GDBN} packets. A notification's @var{data}
+never contains @samp{$}, @samp{%} or @samp{#} characters. Upon
+receiving a notification, the recipient sends no @samp{+} or @samp{-}
+to acknowledge the notification's receipt or to report its corruption.
+
+Every notification's @var{data} begins with a name, which contains no
+colon characters, followed by a colon character.
+
+Recipients should silently ignore corrupted notifications and
+notifications they do not understand. Recipients should restart
+timeout periods on receipt of a well-formed notification, whether or
+not they understand it.
+
+Senders should only send the notifications described here when this
+protocol description specifies that they are permitted. In the
+future, we may extend the protocol to permit existing notifications in
+new contexts; this rule helps older senders avoid confusing newer
+recipients.
+
+(Older versions of @value{GDBN} ignore bytes received until they see
+the @samp{$} byte that begins an ordinary packet, so new stubs may
+transmit notifications without fear of confusing older clients. There
+are no notifications defined for GDB to send at the moment, but we
+assume that most older stubs would ignore them, as well.)
+
@node Examples
@section Examples