MI3 and async notifications

Jan Vrany jan.vrany@fit.cvut.cz
Tue Jun 18 20:38:00 GMT 2019


> I am skeptical about the complex logic you are talking about to handle both
> =breakpoint-created notifications and responses to the -break-insert.  Both contain pretty
> much the same information.  So rather than adding an option in GDB for emitting async
> notifications unconditionally, can't you just process both using the same function?  That
> doesn't really complicated, but maybe I am misunderstanding your problemi, in which case
> please expand.

OK, let me expand (hopefully not too much)

I have a (general purpose) library that provides higher-level interface
to GDB/MI. Strictly speaking, it is not bound to any particular UI frontend. 

This library essentially provides three things: 

(i) (supposedly) easy to use API to send MI commands, like: 

    gdb send: (GDBMI_break_insert arguments: { 'main' }) andWithResultDo:[ :result |
      result isSuccess ifTrue:[
        Stdout print: 'Breakpoint inserted'
      ] ifFalse:[
        Stderr print: 'Oops, something went wrong!'
    (sorry for bit arcane syntax, hope you can make sense of it)

(ii) provide object model of the debugger and its state (like, inferiors, their threads, 
     frames in thread, variables, registers, breakpoints) like: 
     "/ Prints the stack of first thread"
     gdb selectedInferior threads first stack do:[:frame|
       Stdout print: frame printString

     The idea is that if the inferior is stopped, the model is up-to-date, when it's running,
     then "reasonable up-to-date", no guarantees.

(iii) provide a way to get notified of changes, like:

     gdb when: GDBBreakpointModifiedEvent do: [:event |
       "/ something has changed, redraw the list to display
       "/ up-to-date information 
       breakpointListPane redraw.

     This is essential to build an UI on top of this library

All the above is API exposed to library user. This design has the advantages
of being flexible - users can issue commands on their own, I do not have to 
implement and maintain wrapping API rich enough to handle all cases - and
and  because is close to GDB/MI, I don't really need to document it in depth, looking to
GDB documentation gives you very good idea what how to use it. Reusing GDB events
to notify clients of my library has the same advantage - no need to implement my 
own event hierarchy and document them. 

But if I don't get events in cases when they're result of an MI command, the only
way I can think of handling it is to intercept command result event and:
 1) examine the result (and sometimes the originating command itself) and do the 
 2) synthesize an event as if it were send by gdb and push it back so it's delivered
    to users of the library - but in this case I have to make sure it is delivered only
    to "external" observers and not "internal" observers which are responsible of keeping
    the model up-to-date. 

Both steps have to cared for case-by-case (like, -break-insert response carries data
- the breakpoint inserted - while response to -gdb-set is plain ^done so in order to
update model I have to dig into the command itself, retrieve it's parameters and 
reconstruct data from there).

All this is indeed doable and in fact, I do this already for some commands to meet my 
need back then, but then I realized I need more of this and was thinking how to avoid
all that code. A quick experiment shows that always emitting a notification solves
most (all?) issues I experienced, which is why brought it here.

Does it make sense?

> It would be useful to have a very concrete use case where you could point out "see here,
> I am missing some info and a notification would be useful".  It could very well be that
> some notifications are just missing.  

To make me clear, I'm not saying that some information is missing, just that the way
it is delivered seem to be inconvenient given the way I use it. It may well be I use it
the wrong way :-)

> For example I would argue we are missing notifications
> if using two MI clients (through the new-ui command, although I don't remember if that's
> "officially" supported).  If one of the MI client inserts a breakpoint with -break-insert,
> the other one is not notified.  I would consider that a bug that the second client doesn't
> get a =breakpoint-created.

Yeah, having a second MI channel is a different story, I'm not considering this for now. 

> Also, I am a bit worried by a proposal in the thread, which would be to remove information
> from the -break-insert ^done response, arguing that the async notification would have already
> been emitted.  It is clear and unambiguous how to map a response to a request, but it would not
> be obvious to map an async notification to a request.  So it appears to me as a regression in
> functionality.

This is why I said that - for example - for -break-insert we need to respond with - at least - 
^done,bkpt-number=1. For some other. like -gdb-set I don't think we need to. 

Thanks! Jan

More information about the Gdb mailing list