Re: [RFC] canonical linespec and multiple breakpoints ...

Tom Tromey
2011-05-26T21:06:15Z

Tom> While looking into this area I made a list of difficulties and
Tom> considerations that I know of. I can write that up in a readable form
Tom> if you think that would help.

Eli> Please do, and thanks.

Here are the issues I know of. I am not convinced that there is any
good way to get all the desirable features into a single model, but I
welcome brainstorming to this end.

I'm sorry this is so disorganized. It resisted attempts by me to make
it more orderly. I can try to flesh out any pieces that don't make
sense, or come up with difficult scenarios when something isn't clear.

First, there really is a problem. I think it is worth pointing this
out. Currently, given an ambiguous linespec, GDB picks a winner. This
winner is unpredictable.

Right now only a `file:line' breakpoint can have multiple locations.
This is convenient for MI, though the problems here are fixable. I
think this does also give a somewhat nice story for users when the
inferior changes; often (but not always) locations can be preserved, and
`file:line', especially once canonicalized, is reasonably unambiguous,
even across objfiles. Tracking locations like this is desirable because
it means particular instances can be enabled or disabled and the user
can have some reasonable expectation that gdb will do the right thing
across re-runs, etc. Note that the existing code here can be confounded
in some situations: macrology for sure, maybe different template
instantiations (but I didn't try this one particularly).

Breakpoint conditions interact with multi-location breakpoints. A
condition needs a scope in which to parse. A breakpoint that can truly
be multi-location could acquire a new location that invalidates previous
parses.

In the particular case of SystemTap probe points, I think it would be ok
to require multi-location breakpoint conditions to just use the global
scope plus any arguments passed to the probe.

Commands also interact with multi-location breakpoints, but less
significantly than conditions. With a 3-tiered approach I wonder
whether it makes sense to attach commands at both outer tiers? Or just
the outermost?

Canonicalization is an important problem to solve. It matters at least
for the menu-choosing case, should we keep that. I think Matt Rice hit
on the right idea here: instead of always canonicalizing to a linespec,
have some internal object that holds more state. We probably also need
some new kind of linespec in order to let the user more precisely filter
locations.

It is worth thinking about what "the same" means when it comes to two
linespecs (or canonicalized objects). E.g., consider "break function".
Is "function" the same across objfiles? If so or not so, what is the
rationale? For example, "function" might be an inline function defined
in a header, and so really should be treated the same across objfiles;
or maybe this case requires further filtering based on file:line. Maybe
different sorts of linespecs require different comparators.

One consideration is what "the same" means when one location has
debuginfo and another does not. Per an earlier email, I think this
negatively affects the 3-tier approach.

It is worth thinking about "time invariance". E.g., suppose we adopt
Jerome's "menu" plan. In this case, an ambiguous linespec can present
the user with a menu (depending on a setting). But what happens if a
linespec is not ambiguous, but then becomes ambiguous due to changes in
the inferior?

Time invariance and canonicalization also affects the multi-inferior
case. The current plan is to handle multi-inferior breakpoints using
I/T sets; but it seems to me that these may match names in different
ways across inferiors. A simple example is just `break [*] main' --
this either makes a single breakpoint (with all the attendant true
multi-location problems), or binds eagerly (contra the `[*]' spec), or
introduces a tiered breakpoint (but with a more complex example perhaps
one requires 4 tiers? It is unclear to me).

FWIW, on `archer-tromey-multi-breakpoint-2' I implemented a simple form
of multi-tiered breakpoints for the multi-inferior case. On this branch
there is a new "multi break" command that makes a new kind of
breakpoint; this breakpoint is re-evalled for each matching inferior as
it is created, and may then create a new real breakpoint. You can try
it out if you are curious; I think it worked ok, but not truly great
(better would have been making it a real kind of breakpoint so it could
have commands and whatnot).

Many commands, not just "break", use linespecs. What I found was: list,
edit, func, tfind, and clear. Also linespec is called by
select_source_symtab, but I think only for "main" (so could be done
differently). Any solution has to deal with these commands in some way.

Linespecs are exposed to Python, so some updates are required there. I
don't think this is too big a problem. It is probably worth writing a
Python API to whatever canonicalized form exists.

Tom