From: Simon Marchi <simark@simark.ca>
To: Jan Vrany <jan.vrany@fit.cvut.cz>,
"gdb@sourceware.org" <gdb@sourceware.org>
Cc: "Joel Brobecker" <brobecker@adacore.com>,
"Tom Tromey" <tom@tromey.com>,
"André Pönitz" <apoenitz@t-online.de>,
"Jonah Graham" <jonah@kichwacoders.com>
Subject: Re: MI3 and async notifications
Date: Wed, 19 Jun 2019 15:29:00 -0000 [thread overview]
Message-ID: <d56154b8-3495-e185-68bc-3e6e05a5f148@simark.ca> (raw)
In-Reply-To: <70be86e627f6ec578217f01df9af914080b181c2.camel@fit.cvut.cz>
On 2019-06-18 4:38 p.m., Jan Vrany wrote:
> Hi,
>
>> 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
> processing
> 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?
Hi Jan,
Thanks for the detailed explanation.
I am not in your shoes, so I might have a wrong picture of the situation, but this doesn't
sound really complicated. Isn't "synthesizing" an event from the command result just calling
the same function as you do when getting a =breakpoint-created. Or am I missing something?
I don't really understand the difference between external and internal observers (that's
probably specific to your design). Specifically, I don't see what's the difference between
a "real" event that would come from GDB, versus an synthetic event that you would have
injected in your system from the -break-insert response.
Let's say you do get async events for breakpoints you create with -break-insert, then you would
forward these events to all these observers? So in the case where you generate these events
yourself based on the -break-insert response, why shouldn't you also send them to all observers?
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? 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).
>> 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 :-)
We'll see once we understand each other better :).
>> 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
What I am worried about is that doing a change like this has a pretty big cost for on all frontends
that have this currently implemented, so it needs to have a pretty strong justification. It's not just
moving the data fields a little bit, or adding something that everybody else can ignore, it would require
a significant flow change. A frontend that is just interested in setting a breakpoint and getting the
result of that (i.e. the simple case) now needs to do something non-trivial: send the command, listen for
an event, store it somewhere, handle it when receiving the ^done corresponding to the command. This
brings some concurrency/race condition problems that are just not there in the request-response scheme.
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.
Simon
next prev parent reply other threads:[~2019-06-19 15:29 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-06-10 21:19 Jan Vrany
2019-06-10 23:23 ` Jonah Graham
2019-06-11 8:50 ` Jan Vrany
2019-06-11 13:37 ` Jonah Graham
2019-07-05 20:00 ` Pedro Alves
2019-07-05 21:58 ` Jonah Graham
2019-06-15 14:34 ` Tom Tromey
2019-06-17 10:53 ` Jan Vrany
2019-06-17 12:11 ` Jonah Graham
2019-06-17 12:14 ` Joel Brobecker
2019-06-17 12:26 ` Jonah Graham
2019-06-17 12:56 ` Joel Brobecker
2019-06-17 13:12 ` Jan Vrany
2019-06-17 13:23 ` Jonah Graham
2019-06-17 20:45 ` Joel Brobecker
2019-06-17 20:58 ` Jan Vrany
2019-06-17 21:50 ` Jonah Graham
2019-06-17 13:12 ` Jonah Graham
2019-06-17 19:52 ` André Pönitz
2019-06-18 3:14 ` Simon Marchi
2019-06-18 20:38 ` Jan Vrany
2019-06-19 15:29 ` Simon Marchi [this message]
2019-06-19 20:58 ` Jan Vrany
2019-06-20 15:31 ` Simon Marchi
2019-06-20 20:46 ` Jan Vrany
2019-07-05 19:35 ` Pedro Alves
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=d56154b8-3495-e185-68bc-3e6e05a5f148@simark.ca \
--to=simark@simark.ca \
--cc=apoenitz@t-online.de \
--cc=brobecker@adacore.com \
--cc=gdb@sourceware.org \
--cc=jan.vrany@fit.cvut.cz \
--cc=jonah@kichwacoders.com \
--cc=tom@tromey.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).