Re: MI3 and async notifications

Simon Marchi
2019-06-20T15:31:46Z

On 2019-06-19 4:57 p.m., Jan Vrany wrote:
> But consider `set` CLI and `-gdb-set` MI commands:
>
> (gdb)
> set directories /foo/bar
> &"set directories /foo/bar\n"
> &"Warning: /foo/bar: No such file or directory.\n"
> =cmd-param-changed,param="directories",value="/foo/bar:$cdir:$cwd"
> ^done
> (gdb)
>
> and
>
> -gdb-set directories /baz/qux
> &"Warning: /baz/qux: No such file or directory.\n"
> ^done
>
> In this case. the response carries no data at all so in order to synthesize the event
> I need to look at the originating command and parse its arguments to pick the name and value.
> And as you can see above, the value parameter to the command is just "/foo/bar" while
> the value in the event is "/foo/bar:$cdir:$cwd" - another little thing to care about in this
> very case.
>
> Indeed, not a rocket science, but as you see, it requires to write a little specialized
> piece of code for "every" command (vs. not having to write anything at all if I'd get the event from
> GDB). Maybe the phrase "complex logic" was improper - complex in a way that each case has to be
> dealt with individually and if one forgets, the internal model can get out of sync.

For the -gdb-set case, this suggests that the ^done response should contain the new value. The reason
being that, as you have shown, GDB can massage it a little bit. Since the value can end up different
than what the frontend asked for, the frontend would need to be informed of the new/final value.

>> The observers wouldn't know whether it's a "real" event coming from GDB or one you created
>> yourself, so it shouldn't make any difference to them.
>>
>> Or (re-reading your message, I realized that this is what you might be trying to explain)
>> are you saying that your library is very low level, and that users of the library send
>> "-break-insert" on their own and your library just forwards the MI command to GDB, so your
>> library doesn't really know (unless it sniffs the user command) that a -break-insert
>> command has been issued?
>
> Precisely! The library does not really know and therefore would have to "sniff".
>
>> If so, that might explain my incomprehension. All the MI-handling
>> code I have been exposed to has been a bit more high level, where the user calls some
>> "breakInsert" function of the library. The library knows it's sending a -break-insert, so
>> it can easily handle the response however it wants (including generating a "breakpoint created"
>> event if it wants to).
>
> Yeah, I guess that's more common approach. I decided to make it more lower-level as this gives me
> more flexibility. Or so it looked back then :-)

Ok, then I understand how ugly it is to try to track the commands and their responses. I would tend to
say that it falls in the category "you're not using it the way it was intended to": you basically have
two or more interlocutors talking to GDB on the MI channel, whereas GDB expects to be talking to a single
interlocutor. And your two or more interlocutors are not aware of each other's actions.

It sounds like each "interlocutor" should have its own MI channel. Assuming the bug I mentioned earlier
is fixed (about cross-MI channel notifications not being sent), the internals of your library (which
maintains the model) would get notified whenever the user of your library creates a breakpoint with
-break-insert.

> Yes, I completely understand. This and this is a valid concern. I said it before - the last thing I want is to
> break other people's stuff "that works for decades" because of my obscure thing. If the decision out of this
> discussion is "no", I'll happily deal with it in my library. No problem whatsoever.
>
>>
>> So at least, if we end up choosing to unconditionally emit the =breakpoint-created event, I would prefer
>> keeping the -break-insert response as-is, for backwards compatibility (for existing frontends) and
>> simplicity (for basic use cases), even if it means there's some redundancy.
>>
>
> Yes, that was my original proposal, keep everything as it is, just to emit events in addition.
> Either unconditionally or only if mi-always-async is set (at the cost of having yet another option
> which is also far from ideal).

Ok, I had lost track of who suggested what in this long thread.

I am still unsure about emitting events unconditionally. For example: some frontends want to
insert "internal" breakpoints, which are breakpoints that are not going to be directly shown to
users. They send a -break-insert and decide that the breakpoint which results from this won't be
propagated to the UI. But breakpoint async events are propagated to the UI (presumably because
they originate from the user creating a breakpoint in the CLI). If GDB now emits an event for
the -break-insert breakpoint, the frontend can't know right away which future =breakpoint-created
event it should ignore. Again, it would need to buffer all =breakpoint-created events until it
gets the ^done, then let pass through all events except the one that matches the created breakpoint.

Simon