This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [RFC] canonical linespec and multiple breakpoints ...
- From: Tom Tromey <tromey at redhat dot com>
- To: gdb-patches at sourceware dot org
- Date: Fri, 01 Jul 2011 10:39:00 -0600
- Subject: Re: [RFC] canonical linespec and multiple breakpoints ...
- References: <20110505162855.GA2546@adacore.com> <m3oc3gx48l.fsf@fleche.redhat.com> <83bozgmhil.fsf@gnu.org> <m3oc2pxjds.fsf@fleche.redhat.com> <83k4dcd1bh.fsf@gnu.org> <m3r56bdoh9.fsf@fleche.redhat.com>
Here is my proposal for how to handle ambiguous linespecs. First I'll
describe it in general terms, with a few specifics about the
implementation. Then I'll describe how it handles each scenario I
posted yesterday.
I would appreciate comments on this. This is what I intend to work on
starting next Monday, and I would not like to be in the position where I
put in a lot of work and then have to redo it all.
I welcome contrasting proposals, but particularly if they address all
the scenarios identified thus far. I think that partial solutions are
much less interesting -- it is easy to do well on any particular facet
of the problem, but it is much tougher, I think, to come up with a
complete solution.
I propose a simple rule for the handling of ambiguous linespecs: a
breakpoint whose argument is ambiguous will fire at all matching
locations. This rule has several properties that I consider desirable:
* It is simple to explain to users
* It is predictable
* It is time-invariant
* It is implementable ;-)
In addition to this rule I think we should introduce some new linespec
syntax, to let users more precisely narrow down breakpoints. In
particular I would like to add objfile names as a prefix, like:
(gdb) break libc.so:malloc
I think I/T sets are also a good idea here, for the multi-inferior case.
These have been discussed several times and I think don't need much more
discussion.
In order to properly re-set breakpoints, we need a canonical form of the
linespec. Currently this is done by constructing a new canonicalized
linespec. In my proposal we will replace this with a structure, the
better to add more precise behavior without needing to construct
linespec syntax for every possible case. E.g., we can have a bit
indicating whether this canonical linespec matches symbols without
debuginfo.
I am not sure how the breakpoint location information should be arranged
internally. Perhaps each bp_location will need a canonical linespec
struct.
We'll continue to respect 'set multiple-symbols ask' -- in fact, we will
effectively expand it use by noticing more ambiguity in the first place.
This setting will provide users a way to easily create multiple
breakpoints from a single linespec (the "all" choice).
Linespecs are used in places other than "break", like "advance". My
full list plus how to handle ambiguity:
* list, edit: give a menu.
* func: rewrite; I'm not sure why this even uses linespec
* until, advance: use the current context to filter the results; error
if it is still ambiguous
* clear: work like breakpoints
* select_source_symtab: rewrite
One might note that this approach has a built-in inefficiency: nearly
every inferior change will require reading (this at a time when we are
trying to move more toward lazy reading) and scanning of debuginfo. I
think this is ok provided that we provide users with better ways to
precisely specify linespecs; and also perhaps by modifying the internal
code to be smarter about computing re-sets depending on different kinds
of events -- like just dropping some locations rather than fully
re-evaluating a breakpoint when an objfile goes away.
The last part of the proposal is providing a way to modify a
breakpoint's linespec after the breakpoint has been made. The rationale
for this is that it gives users a way to recover from ambiguity when a
condition is attached. See below.
Now on to the scenarios:
Tom> 1. Break on an ambiguously-named function.
Tom> $ gdb gdb
Tom> (gdb) break parse_number
Make a single breakpoint with 7 locations -- one for each function in
gdb with this name.
Tom> 2. The same, but with a file:line.
Make a single breakpoint with multiple locations, just as today.
Tom> 3. Set a breakpoint at a SystemTap probe, the thing that started all this:
Tom> (gdb) break probe:longjmp
Tom> This one (in Fedora 15 glibc) happens to have 2 locations.
Likewise.
Tom> 4. Set a pending breakpoint.
Tom> (gdb) break lib_function
Tom> 5. The same, but the pending name is ambiguous.
These both make a pending breakpoint; inferior changes may cause
locations to be added or removed.
If the name has no matches when 'break' is invoked, then we would
continue to respect 'set breakpoint pending'.
Tom> 6. Set a breakpoint that has a match in the inferior. Then the inferior
Tom> loads a .so to make the linespec ambiguous.
Add new locations to the breakpoint.
Tom> 7. 'break main', then start multiple inferiors
Each new inferior causes new locations to be added; gdb stops at the
'main' of each one.
Tom> 8. Any of the above, but with a breakpoint condition.
Tom> Of particular importance is the case where the condition cannot be
Tom> parsed in one location.
This, I think, is the one bad part of this proposal. When a location is
added to a breakpoint, it may cause the condition to no longer be
parseable.
In this situation I think we should change gdb in 2 ways, to give the
user more control:
1. When a condition is no longer parseable, provide the option to stop
the inferior so the user can correct it.
2. Also provide a way for the user to respecify the breakpoint location.
For the latter I think something like:
modify breakpoint N location LINESPEC
Tom> 9. An ambiguous linespec where one match has debuginfo and another does
Tom> not.
Handled by the canonical linespec struct.
Tom