[remote protocol] Notification packets for non-stop mode

Pedro Alves pedro@codesourcery.com
Tue Jul 15 22:03:00 GMT 2008


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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: notifications.diff
Type: text/x-diff
Size: 3711 bytes
Desc: not available
URL: <http://sourceware.org/pipermail/gdb/attachments/20080715/202e0b15/attachment.bin>


More information about the Gdb mailing list