Re: [PATCH 2/6] Introduce `pre_expanded sals'

Joel Brobecker
2011-05-03T18:17:50Z

I also wanted to say that, as it turns out, Jerome is here in Vancouver
for the week with the goal of adding handling for homonyms in GDB.
So the timing for this discussion could hardly be any better. The
downside, if we want to be able to take better advantage of his trip
is that a quick decision would be helpful so we can get started on
sending out implementation proposals.

I also wanted to give a summary of our discussions on this topic
that occured yesterday, after we read all the threads. We went
back and forth between Pedro's proposal and Tom's. We were trying
to think from the user's perspective, and with a focus on C++ and
Ada (we don't understand stap all that well, but hopefully it will
also apply there).

Right now, there are several situations that can lead to multiple
breakpoint addresses: Generics/templates, homonyms (functions with
the same name), and inlining. In Ada, we've traditionally treated
generics & homonyms differently (multiple breakpoints created) from
inlining (single breakpoint, multiple locations). But does it have
to be that way?

For homonyms, we feel that the typical case is that the user is
usually interested in debugging on specific function. If there
is a bunch of functions called "increment" but only one shows
symptoms of a bug, that's the one that he really wants to break
in.

On the other hand, are generics and templates all that different
from inlining? Thinking about typical debugging scenarios, though,
we think it's common for someone to debug a specific instantiation of
a generic, because it knows that this instantiation shows a bug, while
the others are not. So it's important to be able to specify that
a breakpoint applies to one specific instance, which means that
we're leaning towards handling generics/templates the same as
we'd handle homonyms.

Pedro's idea of federating these SLOC-based breakpoints inside
a 3rd-tier linespec-based breakpoint would probably work. But,
as Jerome and I kept discussing, we felt that maybe it wasn't
necessary. In terms of Ada itself, we've been able to work without
them. Perhaps C++ usage is sufficiently different that the concept
would be more interesting there?

But do we need the 3rd-tier consolidator that Pedro suggests?
We felt that the federation might come from the fact that we wanted GDB
to be smart enough to create new breakpoint locations when re-evaluating
breakpoints, for instance if a shared library got mapped and caused new
locations to match. That's where Jerome's suggestion of treating "all"
breakpoints as dynamic (vs treating specific-instance breakpoints as
static) comes into play. If the user uses an umbiguous linespec, and
then selects "all" (either automatically via multiple-symbol, or
manually via the multiple-choice menu), then create a dynamic version of
the breakpoint, which will constantly re-evaluate its locations.
Otherwise, create a series of static breakpoints, whose source location
are well enough defined to be unique.

There is a form of canonical linespec that we have been using at
AdaCore, which we think could be used universally:

FILE:FUNCTION:LINE

The FUNCTION name is the fully qualified name. For Ada, it means
for instance:

foo.adb:pck.gen.func:8

In C++ (bare in mind that we don't know much about C++ debugging),
it could be something like this:

foo.cc:GetMax<int>(int):8

But now, Jerome just whispered in my ears that using a multiple-location
breakpoint for homonyms would not work well in the following case:
Imagine ther user is trying to put a condition on a breakpoint
that has locations in units of different languages. What language
would we use? Right now, he says that, for lang auto, we do the nice
thing of using the unit's language to evaluate the condition.

So, in the end, it seems difficult to imagine that one single
breakpoint could have multiple slocs. And it also seems that
the suggestion of treating "all" breakpoints as multiple-location
breakpoints would suffer from the same problem.

So, perhaps the 3rd-tier linespec-based breakpoint might make sense,
after all... If we were to go that route, I'm just worried about
the potential for confusing the user, with 3 levels of breakpoints,
and I'm wondering if this could be helped... Perhaps we could hide
the intermediate level, and just show the top and bottom levels to
the user (I'm thinking of breakpoint notifications as well as the
output of "info break").

In terms of implementation, if we were to decide on a 3rd-tier
linespec-based breakpoint, I'd rather have it all the time, even
for non-ambiguous breakpoints (which might become ambiguous later,
as Tom points out). Even if a bit wasteful, I think it's easier to
deal with, rather than having a polymorphic list of breakpoints...

I still maintain, however, that it's important to be able to break
on a selected subset of locations via the multiple-choice menu. We've
had some users who immediately asked about this as soon as we switched
the default to breaking on all matching locations.

--
Joel