public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Pedro Alves <pedro@palves.net>
To: Eli Zaretskii <eliz@gnu.org>
Cc: gdb-patches@sourceware.org
Subject: [PATCH v2 1/2] Always show locations for breakpoints & show canonical location spec
Date: Mon, 23 May 2022 18:04:18 +0100	[thread overview]
Message-ID: <625057b2-1691-a472-fa93-0dabacbddd39@palves.net> (raw)
In-Reply-To: <834k1kd7ne.fsf@gnu.org>

Hi Eli,

On 2022-05-20 07:45, Eli Zaretskii wrote:

> 
>> +@item break @var{location_spec}
>> +Set a breakpoint at all the locations the given @var{location_spec}
>> +resolves to.  @var{location_spec} can specify a function name, a line
>> +number, an address of an instruction, and more.  @xref{Specify
>> +Location}, for a list of all the possible ways to specify a
>> +@var{location}.  The breakpoint will stop your program just before it
>> +executes any of the instructions at the resolved locations' addresses.
>> +
>> +When using source languages that permit overloading of symbols, such
>> +as C@t{++}, a function name may refer to more than one symbol, and
>> +thus more than one place to break.  @xref{Ambiguous
>> +Expressions,,Ambiguous Expressions}, for a discussion of that
>> +situation.
>> +
>> +It is possible that a given function is instantiated more than once in
>> +the program, resulting in a breakpoint with multiple resolved
>> +locations.  This can happen e.g., with inlined functions, or template
>> +functions.
> 
> This text was written when we showed N.x locations only when needed,
> so the text means to explain when a breakpoint will have several
> locations instead of just one.  But with this changeset, we will be
> displaying multiple locations _always_, so this text is no longer
> enough.  We should augment it with the background for multiple shown
> locations even in the cases where the underlying breakpoint is
> inserted only at a single address, such as your example of setting a
> breakpoint at a location that doesn't have any corresponding code
> address.

I don't understand what you're actually suggesting.  This is the
documentation of the "break" command, not "info breakpoints".

But read on, maybe I clarified it already.

> 
>> +A breakpoint location specification (@pxref{Specify Location}) may be
>> +resolved to several locations in your program.  E.g., @code{break
>> +func} will find a location for each function named @code{func} in the
>> +program.
> 
> Again, this "e.g." is incomplete and misses the frequent case, where
> there will be always 2 "locations", possibly identical, shown in the
> table.

I am making a distinction between a "location specification", and
a "resolved location".  So here:

 (top-gdb) info breakpoints 
 Num     Type           Disp Enb Address            What
 1       breakpoint     keep y                      internal_error
  1.1                        y   0x0000555555f813be in internal_error(char const*, int, char const*, ...) at /home/pedro/gdb/binutils-gdb/src/gdbsupport/errors.cc:51
 (top-gdb)

The "What" column of the breakpoint row, which just says "internal_error"
is the location specification, the string the user had input (or rather, a
canonicalized form of it) and gdb uses to match actual locations.

The "What" column of the "1.1" line is the actual found location that matches
the input string.

The "will find a location for each function named func", is talking about more
than info breakpoints.  Since this is the part describing the "break" command,
you can already see it here:

 (top-gdb) b main
 Breakpoint 3 at 0xed06c: main. (24 locations)
                                 ^^^^^^^^^^^^

The user typed "main", and gdb found 24 locations.  I.e., the single
location specification "main" was resolved to 24 locations in your program.

> 
>>               For each code breakpoint and tracepoint (not for
>> +watchpoints, nor catchpoints), @value{GDBN} prints a header entry, and
>> +then one entry for each resolved location of the breakpoint.
> 
> Likewise: "one entry" will be misleading with the new display, because
> we will always show at least 2.

It says "prints a header entry", so that's 1 entry, "and then one entry FOR EACH
resolved location".  I'm not sure  what you find confusing here.  If the breakpoint
has no locations (a pending breakpoint), that results in one entry for the breakpoint,
and then 0 for its zero locations, so it's obviously incorrect that we will always show
at least 2.  If the breakpoint has 1 location, then it results in one entry for the breakpoint,
and 1 entry for its locations; If the breakpoint has 5 location, then it results in one entry
for the breakpoint, and 5 entry for its locations; etc.  I think the text covers all that.

This is based on existing text actually, from the text after the table describing the
columns, where we describe multiple locations currently:

 "A breakpoint with multiple locations is displayed in the breakpoint table using several
 rows—one header row, followed by one row for each breakpoint location. "

I just reused that text before the table so that I could talk about
breakpoint locations in the description of the columns.  I just didn't use the
word "row".  I've reworded the new text a bit now, using "row" too.  Hopefully it reads
clearer that way.

> 
>> +Enabled breakpoints and breakpoint locations are marked with @samp{y}.
> 
> What does "enabled breakpoint location" mean?  One cannot enable a
> location.  

Sure we can.

(top-gdb) info breakpoints 3
3       breakpoint     keep y                      main
 3.1                        y   0x00000000000ed06c in main(int, char**) at /home/pedro/gdb/binutils-gdb/src/gdb/gdb.c:25
 3.2                        y   0x0000000000866436 in selftests::string_view::capacity_1::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/capacity/1.cc:167
 3.3                        y   0x0000000000866855 in selftests::string_view::cons_1::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/cons/char/1.cc:62
 ...

(top-gdb) disable 3.1 3.2
(top-gdb) info breakpoints 3
Num     Type           Disp Enb Address            What
3       breakpoint     keep y                      main
 3.1                        n   0x00000000000ed06c in main(int, char**) at /home/pedro/gdb/binutils-gdb/src/gdb/gdb.c:25
 3.2                        n   0x0000000000866436 in selftests::string_view::capacity_1::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/capacity/1.cc:167
 3.3                        y   0x0000000000866855 in selftests::string_view::cons_1::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/cons/char/1.cc:62
 ...

(top-gdb) enable 3.2
(top-gdb) info breakpoints 3
Num     Type           Disp Enb Address            What
3       breakpoint     keep y                      main
 3.1                        n   0x00000000000ed06c in main(int, char**) at /home/pedro/gdb/binutils-gdb/src/gdb/gdb.c:25
 3.2                        y   0x0000000000866436 in selftests::string_view::capacity_1::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/capacity/1.cc:167
 3.3                        y   0x0000000000866855 in selftests::string_view::cons_1::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/cons/char/1.cc:62


This is documented in the "Set Breaks" node already, here:

  "You cannot delete the individual locations from a breakpoint. However, each location can be individually enabled or
   disabled by passing breakpoint-number.location-number as argument to the enable and disable commands."

Note that, as I explained in the commit log of the patch in question, with current master, if the
breakpoint's enabled state is different from the location's enabled state, then GDB is already
presenting a single-location breakpoint in "multi-location" mode.  E.g., with current master
as top gdb, debugging another gdb:

(top-gdb) info breakpoints 1
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x0000000000a2d362 in internal_error(char const*, int, char const*, ...) at /home/pedro/gdb/binutils-gdb/src/gdbsupport/errors.cc:51
(top-gdb) disable 1.1
(top-gdb) info breakpoints 1
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   <MULTIPLE>         
1.1                         n   0x0000000000a2d362 in internal_error(char const*, int, char const*, ...) at /home/pedro/gdb/binutils-gdb/src/gdbsupport/errors.cc:51
(top-gdb)

> We should find some different terminology here for the N.x
> breakpoints, maybe something like "breakpoint" for the N.x and
> "breakpoint group" for the "parent" breakpoint?  You seem to use
> "breakpoint header" below, but that term is not explained and not used
> consistently.  Nor is it a "header", strictly speaking: it's
> conceptually an item that represents a group of actual breakpoints.

We already have terms for this and we make use of them pervasively.  A breakpoint
can have 0 locations (we call this a pending breakpoint), one location, or more than one
locations.  IOW, a breakpoint has a list of locations, and that location list can
have 0, 1, N elements.  This is already explained in the manual, both for CLI users,
and for MI, and understood by users.  I see no point in coming up with new terminology.

This is the current text, you can see it pre-rendered here:

 https://sourceware.org/gdb/onlinedocs/gdb/Set-Breaks.html#index-breakpoints_002c-multiple-locations

 "A breakpoint with multiple locations is displayed in the breakpoint table using several rows—one header row, followed
 by one row for each breakpoint location. The header row has ‘<MULTIPLE>’ in the address column. The rows for
 individual locations contain the actual addresses for locations, and show the functions to which those
 locations belong. The number column for a location is of the form breakpoint-number.location-number."

> 
>> +For a breakpoint whose location specification hasn't been resolved to
>> +any location yet, this field will contain @samp{<PENDING>}.  Such
>> +breakpoint won't fire until its location spec is resolved to an actual
>> +location, such as e.g., when a shared library that has the symbol or
>    ^^^^^^^^
> This should be "address", to avoid even more confusion wrt "location".
> (After reading more of your text, I realize that this is the tip of a
> very large iceberg, see below.)
> 
>> +For a breakpoint header row, the original location specification
>> +passed to the breakpoint command.  For a breakpoint location row,
>> +where the breakpoint location is in the source for your program, as a
>> +file and line number.
> 
> This should explain the crucial difference between "the original
> location specification" and "breakpoint location" used elsewhere in
> the text.  It is entirely not trivial to grasp the importance of that
> distinction.  (Another tip of the iceberg.)

OK, I can agree with that.  Do note the current manual is already
ambiguous here, for it calls both things "location", and that's it.

So I'm actually proposing to improve things by calling the user-input
text as "location specification", distinct from the actual locations
the specification matches or resolves to.

Even GDB's source code uses "location" for both -- struct bp_location
for the breakpoint locations, the "1.1", "1.2" things, stored in each
struct breakpoint in the breakpoint::loc field, as a linked list:

  /* Location(s) associated with this high-level breakpoint.  */
  bp_location *loc = NULL;

We then have breakpoint::insert_location to physically insert a
location, etc.

And then, we have a different field called "breakpoint::location" for the
breakpoint's location specification:

  /* Location we used to set the breakpoint.  */
  event_location_up location;

This is where the linespec, is stored.

If this patch goes through, I'd like to rename this event_location_up
field to location_spec accordingly.


So here's what I changed in the manual compared to the previous version
of the patch:

- renamed the "Specify Location" node to "Location Specifications".

- In the (now named) "Location Specifications" node, explained
  what a location specification is, describing it as like a blueprint,
  and how it can match more than one actual location.   I moved the pre-existing 
  examples that were in the "Set Breaks" chapter there.  We have a ton
  of cross references to this chapter throughout, so having them here centralized
  should help.

- added more "info breakpoints" examples, better explaining the
  difference between what the "What" column shows for the breakpoint's
  row vs the breakpoint's locations rows.

- added an example about "b -qualified", and another "b file.c:line".  I think
  these will help a lot.

- adjusted a few other "info breakpoints" examples in the manual that I had
  missed before.

- several misc minor edits here and there inspired by your comments.

> 
>> +@value{GDBN} may add new locations to existing breakpoints when new
>> +symbols are loaded.  For example, if you have a breakpoint in a
>> +C@t{++} template function, and a newly loaded shared library has an
>> +instantiation of that template, a new location is added to the list of
>> +locations for the breakpoint.  More on this further below.
> 
> I fail to see why this paragraph is important to have.  What it says
> is trivial, and having it here makes a complex description harder to
> understand, because it interrupts the description with unimportant
> details.

Note this is a rewording of preexisting text.  Currently we say:

 "This logic works for breakpoints with multiple locations, too. For example, if you have
  a breakpoint in a C++ template function, and a newly loaded shared library has an
  instantiation of that template, a new location is added to the list of locations
  for the breakpoint."

... in the part explaining pending breakpoints.  But the fact that we add breakpoint
locations when shared libs are loaded is not specific to pending breakpoints, so
I moved it up right after we say that breakpoints can have multiple locations.  If 
we don't explain this about new symbols resulting in more locations, then users may
assume that breakpoints only end up with locations that exist at the time the breakpoint
was first set.  So I think it's an important thing to say explicitly.

> 
>> +Regulars code breakpoints and tracepoints are displayed in the
>    ^^^^^^^^
> Typo.

Fixed.

> 
>> +breakpoint table using several rows---one header row per breakpoint,
>> +followed by one row for each of the breakpoint's locations.  The
>> +header row has an empty address column, and the original location
>> +specification in the what column.  The rows for individual locations
>> +contain the addresses for the locations, and show the functions to
>> +which those addresses belong.  The number column for a location is
>> +indented by one space to the right for grouping, and is of the form
>>  @var{breakpoint-number}.@var{location-number}.
> 
> IMO, something like this text should precede the description of the
> table contents, because it both provides a high-level overview of how
> each breakpoint is displayed, and defines terminology like "header
> row", "breakpoint location row", etc.  Having it here is "too late".

I actually already did that, that's why I added the paragraph saying:

 "For each code breakpoint and tracepoint (not for watchpoints, nor catchpoints),
 @value{GDBN} prints a header entry, and then one entry for each resolved
 location of the breakpoint.", and finished it with "More on this further below.".

I don't think we should move this text (not the one I added, the one you're
pointing at), because it is talking about the "info breakpoint" columns, after they
are introduced.  It's a cyclical dependency, which I had broken with that
short paragraph I just mentioned.

> 
>>  set a breakpoint in a shared library at the beginning of your
>>  debugging session, when the library is not loaded, and when the
>>  symbols from the library are not available.  When you try to set
>> -breakpoint, @value{GDBN} will ask you if you want to set
>> -a so called @dfn{pending breakpoint}---breakpoint whose address
>> -is not yet resolved.
>> +a breakpoint, @value{GDBN} will ask you for confirmation of whether
>> +you want to set a so called @dfn{pending breakpoint}---a breakpoint with
>> +no resolved locations yet.
> 
> I'm not sure it is a good idea to talk about "resolved locations",
> here and elsewhere.  Why not "resolved addresses", as the original
> text did?  Using "location" here introduces a conceptual ambiguity,
> whereby a "location" could be in the source code and also in the
> executable code, and that overloading of concepts makes this complex
> issue even harder to understand.  My suggestion is to use "location"
> for source-level location specs, and for nothing else.

I disagree with that, because that's not how GDB behaves.  GDB's user interface
uses "location" for the resolved locations.  We call something like "1.3" the
location number.  We have that whole section talking about breakpoints with
multiple locations, and it's very clearly talking about those.  We have error
messages like:

 (gdb) disable 2.200
 Bad breakpoint location number '200'

etc. etc. etc.

It's the string that we pass as WHERE, as in "break WHERE" that should get a
different name, IMO, and I propose calling that a "location spec" / " location
specification", just like we already have the term "linespec" too, originally 
meaning "line specification" obviously, which then GDB resolves to an actual
line.  IOW, I see a location spec as a superset of a linespec (as linespec
is one of the 3 ways you can specify a location).

> 
> It sounds like you want to use the term "breakpoint location" to refer
> to those N.x "instances" of the breakpoints, and that is the root
> cause of the above terminology overloading.  

That's exactly what the term means, and I'm not inventing that now!
It has always been like that ever since multi-locations support was added
to GDB, at least, and the manual describes exactly that.  E.g., from
the current master's manual:

  "You cannot delete the individual locations from a breakpoint. However, each location can be individually
   enabled or disabled by passing breakpoint-number.location-number as argument to the
   enable and disable commands."

  "A breakpoint with multiple locations is displayed in the breakpoint table using several rows—one header row,
   followed by one row for each breakpoint location. The header row has ‘<MULTIPLE>’ in the address column.
   The rows for individual locations contain the actual addresses for locations, and show the functions to which
   those locations belong. The number column for a location is of the form breakpoint-number.location-number."

> If that is the case,
> let's find a better term for "breakpoint location" (which in itself is
> a vague and problematic term, since there are actually 2 locations
> involved: the source-level location and the address in the code).
> 
>>  After the program is run, whenever a new shared library is loaded,
>> -@value{GDBN} reevaluates all the breakpoints.  When a newly loaded
>> -shared library contains the symbol or line referred to by some
>> -pending breakpoint, that breakpoint is resolved and becomes an
>> -ordinary breakpoint.  When a library is unloaded, all breakpoints
>> -that refer to its symbols or source lines become pending again.
>> -
>> -This logic works for breakpoints with multiple locations, too.  For
>> -example, if you have a breakpoint in a C@t{++} template function, and
>> -a newly loaded shared library has an instantiation of that template,
>> -a new location is added to the list of locations for the breakpoint.
>> -
>> -Except for having unresolved address, pending breakpoints do not
>> +@value{GDBN} reevaluates all the breakpoints' location specs.  When a
>> +newly loaded shared library contains the symbol or line referred to by
>> +some pending breakpoint, a location for the breakpoint is found and
>> +the breakpoint becomes an ordinary breakpoint.  When a library is
>> +unloaded, breakpoint locations that refer to its symbols or source
>> +lines are not deleted -- they are instead displayed with a
>> +@code{<PENDING>} address.  This is so that if the shared library is
>> +loaded again, the location's enabled/disabled state is preserved.
> 
> This text has the same terminology difficulties I mentioned above.
> 
>>  @value{GDBN} provides some additional commands for controlling what
>> -happens when the @samp{break} command cannot resolve breakpoint
>> -address specification to an address:
>> +happens when the @samp{break} command cannot resolve its breakpoint
>> +location specification to any location:
> 
> The "resolve breakpoint location specification to any location" part
> uses "location" in two very different senses in the same sentence --
> do you see how confusing and hard to understand this is?

I honestly don't...  One says "specification", the other one doesn't.

This to me is like saying "resolve an airplane blueprint to an actual airplane."

I used "airplane" twice, but it is not ambiguous.

I clarified this in the now-renamed "Location Specifications" section, please
take a look at the new version.

> 
>> +                               When @value{GDBN} cannot find any
>> +location for the location specification, it queries you whether a
> 
> Likewise here.
> 
>> +This indicates that when @value{GDBN} cannot resolve any location for
>> +the location specification, it should create a pending breakpoint
> 
> And here.  And elsewhere -- if we don't find a good solution for this
> problematic terminology, we will bump into such problems and confuse
> the heck out of our users from here to eternity.
> 
>> +This indicates that pending breakpoints are not to be created.  If
>> +@value{GDBN} cannot resolve any location for the location
>> +specification, @value{GDBN} throws an error.
> 
> I wouldn't use "throws an error" in describing user-facing features.
> "Displays an error message", perhaps?

OK.  I actually had looked to see if "throw an error" is used in the manual,
as I also wasn't sure whether it would be good, but found it one other
spot, so assumed yes.  Saying "throws an error" is more accurate in the
sense that an error also stops command processing.  Just prints an error
or displays an error as we typically say throughout doesn't convey that.
Maybe "aborts the command with an error" would be a better way to convey this?
I notice now -- some spots say also "error raised".  But I think the
command abortion is more informative here, like so:

 @item set breakpoint pending off
 This indicates that pending breakpoints are not to be created.  If
 @value{GDBN} cannot resolve any location for the location
 specification, it aborts the breakpoint creation with an error.  This
 setting does not affect any pending breakpoints previously created.

> 
>> +breakpoint; This field will not be present if no address can be
>              ^^^
> Typo(s).
> 
>> +This field is present for ordinary breakpoints and tracepoints.
> 
> What is an "ordinary" breakpoint, and how is it different from the
> other kinds?  (There are other places in the new text that use this
> unexplained terminology.)

I've just using the terminology already used in this table.  See:

 type
 The type of the breakpoint. For ordinary breakpoints this will be ‘breakpoint’, but many values are possible.

 catch-type
 If the type of the breakpoint is ‘catchpoint’, then this indicates the exact type of catchpoint.

Since "info breakpoints" lists all of breakpoints, watchpoints, catchpoint,
tracepoints, "delete" deletes all of these, etc., you can think of all of these
being different types of breakpoints, and indeed that's how things are implemented,
and what the "type" column above suggests, as well as the catch-type's column's description,
seen above.

Thus "ordinary" here refers to actual code breakpoints, as opposed to the generic "breakpoint"
term meaning all of code breakpoints, watchpoints, tracepoints, catchpoints.

Below is the updated patch.  Only the documentation changed.



From 49e1502a9c6c1344f6cc449e87ac39d4cef77caf Mon Sep 17 00:00:00 2001
From: Pedro Alves <pedro@palves.net>
Date: Tue, 17 May 2022 13:12:04 +0100
Subject: [PATCH] Always show locations for breakpoints & show canonical
 location spec

I've thought for a few years that "info breakpoints" should show BOTH
the canonical location spec behind each breakpoint, and the actual
resolved location(s) where the breakpoint is inserted.  It currently
only shows the latter.

Here are for example 3 breakpoints that I set while debugging gdb:

 (top-gdb) info breakpoints
 Num     Type           Disp Enb Address            What
 1       breakpoint     keep y   0x0000000000575127 in internal_error(char const*, int, char const*, ...) at src/gdb/common/errors.c:54
 2       breakpoint     keep y   0x0000000000575127 in internal_error(char const*, int, char const*, ...) at src/gdb/common/errors.c:54
 3       breakpoint     keep y   <MULTIPLE>
 3.1                         y   0x0000000000575127 in internal_error(char const*, int, char const*, ...) at src/gdb/common/errors.c:54
 3.2                         y   0x00007ffff6d50410 in PyErr_SetObject at /usr/src/debug/python2-2.7.15-4.fc27.x86_64/Python/errors.c:54
 (top-gdb)

From looking at those, you have no idea how I created the breakpoints
in the first place, which specs I used.  Breakpoints 1 and 2 look like
the same from that output, but really aren't.  I'll have forgotten
after a while which was which though.  And what's with the third
breakpoint, showing seemingly unrelated functions in its locations?

GDB of course knows all those breakpoints were set differently.  It
needs to remember the location specs in order to re_set the locations
properly.  And it needs to remember the spec in order to save the
breakpoints, like:

 (top-gdb) save breakpoints bpts.cmd
 Saved to file 'bpts.cmd'.

Let's look at the file, see how the breakpoints had been created:

 (top-gdb) shell cat bpts.cmd
 break internal_error
 break -qualified internal_error
 break errors.c:54
 (top-gdb)

Ah, the "-qualified" information for breakpoint 2 was lost from "info
breakpoints" output.  And now it's obvious why we have two locations
for breakpoint 3 -- that breakpoint was set by FILE:LINE, and GDB
resolved that to two locations in unrelated functions that happen to
be implemented in files with the same name.

I propose that we show this info in "info breakpoints" too, with a
conceptualy simple change that just removes special cases.  To get
there, let's observe a fact -- there are a couple cases where "info
breakpoints" prints the breakpoint's locations in their own rows:

#1 - when the breakpoint has multiple locations:

 (gdb) info breakpoints
 Num     Type           Disp Enb Address            What
 1       breakpoint     keep y   <MULTIPLE>
 1.1                         y   0x0000000000a2d874 in func(int) at func.c:51
 1.2                         y   0x0000000000b2d640 in func(int) at func2.c:51

#2 - when the breakpoint only has one location, but it is disabled,
     while the breakpoint itself is enabled.  E.g.:

 (gdb) info breakpoints
 Num     Type           Disp Enb Address            What
 1       breakpoint     keep y   0x0000000000a2d874 in func(int) at func.c:51
 (gdb) disable 1.1
 (gdb) info breakpoints
 Num     Type           Disp Enb Address            What
 1       breakpoint     keep y   <MULTIPLE>
 1.1                         n   0x0000000000a2d874 in func(int) at func.c:51

(the last example shows <MULTIPLE> when there's only one location, but
let's ignore that...)

Note that when we print the locations in a separate row, the "What"
column for the breakpoint header row is empty.  That seems to me to be
the perfect spot to put the breakpoint's location spec.

Then, if we make it such that breakpoints always print their locations
in separate rows, even if they only have one location, that space is
always there to use.  The result for the confusing example at the top
would be this:

 (top-gdb) info breakpoints
 Num     Type           Disp Enb Address            What
 1       breakpoint     keep y                      internal_error
 1.1                         y   0x00000000005755a5 in internal_error(char const*, int, char const*, ...) at src/gdb/common/errors.c:54
 2       breakpoint     keep y                      -qualified internal_error
 2.1                         y   0x00000000005755a5 in internal_error(char const*, int, char const*, ...) at src/gdb/common/errors.c:54
 3       breakpoint     keep y                      errors.c:54
 3.1                         y   0x00000000005755a5 in internal_error(char const*, int, char const*, ...) at src/gdb/common/errors.c:54
 3.2                         y   0x00007ffff6d50410 in PyErr_SetObject at /usr/src/debug/python2-2.7.15-4.fc27.x86_64/Python/errors.c:54

(Note: this looks better on a terminal with color.)

Breakpoints would no longer move from single-location to
multiple-location "display modes" as locations were added/removed
(e.g., when a shared library is loaded), they'd always be in
multi-location display mode.  And we'd get rid of the "breakpoint has
a single location that is disabled" special case.

Now, after using this for a while, I came to wish that the output
would give a better visual clue on each group of "breakpoint + its
locations".  This commit implements that by simply indenting the
location number by one space, like so:

 (top-gdb) info breakpoints
 Num     Type           Disp Enb Address            What
 1       breakpoint     keep y                      internal_error
  1.1                        y   0x00000000005755a5 in internal_error(char const*, int, char const*, ...) at src/gdb/common/errors.c:54
 2       breakpoint     keep y                      -qualified internal_error
  2.1                        y   0x00000000005755a5 in internal_error(char const*, int, char const*, ...) at src/gdb/common/errors.c:54
 3       breakpoint     keep y                      errors.c:54
  3.1                        y   0x00000000005755a5 in internal_error(char const*, int, char const*, ...) at src/gdb/common/errors.c:54
  3.2                        y   0x00007ffff6d50410 in PyErr_SetObject at /usr/src/debug/python2-2.7.15-4.fc27.x86_64/Python/errors.c:54

The need for grouping is clearer if you have breakpoints with dozens
of locations, such as when you do "b main" when debugging GDB.

Another interesting case where this commit helps is when the user sets
a breakpoint by line number, and the line corresponds to a comment or
empty line, or to code that was optimized away.  E.g., again when
debugging GDB:

 (top-gdb) b 27
 Breakpoint 4 at 0x469aa6: file src/gdb/gdb.c, line 28.

Note I asked for line 27 but got line 28.

"info breakpoints" currently says:

 (top-gdb) info breakpoints 4
 Num     Type           Disp Enb Address            What
 4       breakpoint     keep y   0x0000000000469aa6 in main(int, char**) at src/gdb/gdb.c:28

Again here we lost the info about the original location spec, line 27.
While after this commit, we get:

 (top-gdb) info breakpoints 4
 Num     Type           Disp Enb Address            What
 4       breakpoint     keep y                      src/gdb/gdb.c:27
  4.1                        y   0x0000000000469aa6 in main(int, char**) at src/gdb/gdb.c:28

Lancelot is working on a GDB change that will make GDB slide each
breakpoint location's line independently, so we could end up with
something like this, even:

 (top-gdb) info breakpoints 4
 Num     Type           Disp Enb Address            What
 4       breakpoint     keep y                      func.cc:27
  4.1                        y   0x0000000000469aa6 in func<float>(float) at func.cc:28
  4.2                        y   0x000000000047abb8 in func<int>(int) at func.cc:30

The output for watchpoints and catchpoints is unmodified, they will
continue being printed like before, as we never print locations for
those:

 Num     Type           Disp Enb Address            What
 2       catchpoint     keep y                      syscall "<any syscall>"
 3       hw watchpoint  keep y                      *main

Before this commit can go in, I'll need to address testsuite fallout,
of course.  I expect this will be a significant effort, so I'm hoping
we can come to agreement on whether the GDB change is OK before
wasting time adjusting the testsuite.

Documentation adjustments included.  They also clean up a few tangent
things in the area of the docs I was adjusting to better match
reality.

Change-Id: Ic42ad8565e79ca67bfebb22cbb4794ea816fd08b
---
 gdb/doc/gdb.texinfo | 384 +++++++++++++++++++++++++++-----------------
 gdb/doc/guile.texi  |   2 +-
 gdb/doc/python.texi |   5 +-
 gdb/breakpoint.c    |  89 +++++-----
 4 files changed, 278 insertions(+), 202 deletions(-)

diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 90c307a7dd2..f988d9d6bd1 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -2024,7 +2024,7 @@ func<int>()    func<float>()
 (@value{GDBP}) p 'func<
 @end smallexample
 
-When setting breakpoints however (@pxref{Specify Location}), you don't
+When setting breakpoints however (@pxref{Location Specifications}), you don't
 usually need to type a quote before the function name, because
 @value{GDBN} understands that you want to set a breakpoint on a
 function:
@@ -4344,16 +4344,24 @@ convenience variables.
 
 @table @code
 @item break @var{location}
-Set a breakpoint at the given @var{location}, which can specify a
-function name, a line number, or an address of an instruction.
-(@xref{Specify Location}, for a list of all the possible ways to
-specify a @var{location}.)  The breakpoint will stop your program just
-before it executes any of the code in the specified @var{location}.
+Set a breakpoint at all the locations the given location specification
+matches.  @var{location} can specify a function name, a line number,
+an address of an instruction, and more.  @xref{Location
+Specifications}, for the various forms of @var{location}.
 
-When using source languages that permit overloading of symbols, such as
-C@t{++}, a function name may refer to more than one possible place to break.
-@xref{Ambiguous Expressions,,Ambiguous Expressions}, for a discussion of
-that situation.
+When using source languages that permit overloading of symbols, such
+as C@t{++}, a function name may refer to more than one symbol, and
+thus more than one place to break.  @xref{Ambiguous
+Expressions,,Ambiguous Expressions}, for a discussion of that
+situation.
+
+It is possible that a given function is instantiated more than once in
+the program, resulting in a breakpoint with multiple addresses, and
+thus multiple locations.  This can happen e.g., with inlined
+functions, or template functions.
+
+The breakpoint will stop your program just before it executes any of
+the instructions at its locations' addresses.
 
 It is also possible to insert a breakpoint that will stop the program
 only if a specific thread (@pxref{Thread-Specific Breakpoints})
@@ -4407,11 +4415,11 @@ command:
 @smallexample
 (@value{GDBP}) info breakpoints
 Num     Type           Disp Enb Address            What
-1       breakpoint     keep y   <MULTIPLE>
+1       breakpoint     keep y                      func
         stop only if a == 10
-1.1                         N*  0x00000000000011b6 in ...
-1.2                         y   0x00000000000011c2 in ...
-1.3                         N*  0x00000000000011ce in ...
+ 1.1                        N*  0x00000000000011b6 in ...
+ 1.2                        y   0x00000000000011c2 in ...
+ 1.3                        N*  0x00000000000011ce in ...
 (*): Breakpoint condition is invalid at this location.
 @end smallexample
 
@@ -4545,32 +4553,42 @@ optionally be surrounded by spaces.
 @cindex @code{$_} and @code{info breakpoints}
 @item info breakpoints @r{[}@var{list}@dots{}@r{]}
 @itemx info break @r{[}@var{list}@dots{}@r{]}
-Print a table of all breakpoints, watchpoints, and catchpoints set and
-not deleted.  Optional argument @var{n} means print information only
-about the specified breakpoint(s) (or watchpoint(s) or catchpoint(s)).
-For each breakpoint, following columns are printed:
+Print a table of all breakpoints, watchpoints, tracepoints, and
+catchpoints set and not deleted.  The optional argument @var{n} means
+print information only about the specified breakpoint(s) (or
+watchpoint(s) or tracepoint(s) or catchpoint(s)).
+
+For each code breakpoint and tracepoint (i.e., not for watchpoints,
+nor catchpoints), after printing a row for the breakpoint itself,
+@value{GDBN} prints one row for each of the breakpoint's locations.
+More on this further below.
+
+For each breakpoint (and watchpoint, tracepoint, catchpoint) and
+breakpoint location, the following columns are printed:
 
 @table @emph
 @item Breakpoint Numbers
 @item Type
-Breakpoint, watchpoint, or catchpoint.
+Breakpoint, watchpoint, tracepoint, or catchpoint.  This is empty for
+breakpoint location rows.
 @item Disposition
 Whether the breakpoint is marked to be disabled or deleted when hit.
+This is empty for breakpoint location rows.
 @item Enabled or Disabled
-Enabled breakpoints are marked with @samp{y}.  @samp{n} marks breakpoints
-that are not enabled.
+Enabled breakpoints and breakpoint locations are marked with @samp{y}.
+@samp{n} marks breakpoints and breakpoint locations that are not
+enabled.  Note individual locations can be enabled/disabled
+independently of their parent breakpoint.
 @item Address
-Where the breakpoint is in your program, as a memory address.  For a
-pending breakpoint whose address is not yet known, this field will
-contain @samp{<PENDING>}.  Such breakpoint won't fire until a shared
-library that has the symbol or line referred by breakpoint is loaded.
-See below for details.  A breakpoint with several locations will
-have @samp{<MULTIPLE>} in this field---see below for details.
+Where the breakpoint location is in your program, as a memory address.
+For a breakpoint with no locations, this field will contain
+@samp{<PENDING>}.
 @item What
-Where the breakpoint is in the source for your program, as a file and
-line number.  For a pending breakpoint, the original string passed to
-the breakpoint command will be listed as it cannot be resolved until
-the appropriate shared library is loaded in the future.
+For a breakpoint header row, this shows the breakpoint's location
+specification, derived from the string passed to the breakpoint
+command.  For a breakpoint location row, this shows where the
+breakpoint location is in the source for your program, as a file and
+line number.
 @end table
 
 @noindent
@@ -4583,8 +4601,7 @@ its condition evaluation mode in between parentheses.
 
 Breakpoint commands, if any, are listed after that.  A pending breakpoint is
 allowed to have a condition specified for it.  The condition is not parsed for
-validity until a shared library is loaded that allows the pending
-breakpoint to resolve to a valid location.
+validity until the pending breakpoint is resolved to a valid location.
 
 @noindent
 @code{info break} with a breakpoint
@@ -4614,46 +4631,85 @@ the breakpoints are conditional, this is even useful
 
 @cindex multiple locations, breakpoints
 @cindex breakpoints, multiple locations
-It is possible that a breakpoint corresponds to several locations
-in your program.  Examples of this situation are:
+It is possible that a breakpoint corresponds to several locations in
+your program.  @value{GDBN} will insert a breakpoint at all the
+locations its location specification resolves to.
+@xref{Location Specifications}.
+
+@value{GDBN} may add new locations to existing breakpoints when new
+symbols are loaded.  For example, if you have a breakpoint in a
+C@t{++} template function, and a newly loaded shared library has an
+instantiation of that template, a new location is added to the list of
+locations for the breakpoint.  More on this further below.
+
+As mentioned above, regular code breakpoints and tracepoints are
+displayed in the breakpoint table using several rows---one header row
+per breakpoint, followed by one row for each of the breakpoint's
+locations.  The header row has an empty address column, and the
+breakpoint's location specification in the what column.  The rows for
+individual locations contain the addresses for the locations, and show
+the functions to which those addresses belong.  The number column for
+a location is indented by one space to the right for grouping, and is
+of the form @var{breakpoint-number}.@var{location-number}.
 
-@itemize @bullet
-@item
-Multiple functions in the program may have the same name.
+For example:
 
-@item
-For a C@t{++} constructor, the @value{NGCC} compiler generates several
-instances of the function body, used in different cases.
+@smallexample
+Num     Type           Disp Enb  Address    What
+1       breakpoint     keep y               foo
+        stop only if i==1
+        breakpoint already hit 1 time
+ 1.1                        y    0x080486a2 in void foo<int>() at t.cc:8
+ 1.2                        y    0x080486ca in void foo<double>() at t.cc:8
+@end smallexample
 
-@item
-For a C@t{++} template function, a given line in the function can
-correspond to any number of instantiations.
+Above you can tell from the what column that the breakpoint had been
+created with @code{break foo}, and that @value{GDBN} found two actual
+locations that matched that location specification, each of them a
+different instanciation of the foo function template.
 
-@item
-For an inlined function, a given source line can correspond to
-several places where that function is inlined.
-@end itemize
+Breakpoints created with the @code{-qualified} option show that fact
+in the breakpoint row's what column, as part of the breakpoint's
+location specification.  For example:
+
+@smallexample
+Num     Type           Disp Enb  Address    What
+1       breakpoint     keep y               -qualified func
+ 1.1                        y    0x080486a2 in void func() at func.cc:30
+2       breakpoint     keep y               func
+ 2.1                        y    0x080486a2 in void func() at func.cc:30
+@end smallexample
 
-In all those cases, @value{GDBN} will insert a breakpoint at all
-the relevant locations.
+Note how above both breakpoints resolved to the same location, while
+they show different location specifications.  If the program
+subsequently loads a shared library that defines a C@t{++} method
+named @code{A::func()}, then breakpoint 2 will gain a new location,
+but not breakpoint 1, like so:
 
-A breakpoint with multiple locations is displayed in the breakpoint
-table using several rows---one header row, followed by one row for
-each breakpoint location.  The header row has @samp{<MULTIPLE>} in the
-address column.  The rows for individual locations contain the actual
-addresses for locations, and show the functions to which those
-locations belong.  The number column for a location is of the form
-@var{breakpoint-number}.@var{location-number}.
+@smallexample
+Num     Type           Disp Enb  Address        What
+1       breakpoint     keep y                   -qualified func
+ 1.1                        y    0x0000080486a2 in void func() at func.cc:30
+2       breakpoint     keep y                   func
+ 2.1                        y    0x0000080486a2 in void func() at func.cc:30
+ 2.2                        y    0x7ffff6caa000 in int A::func(int) at shlib.cc:102
+@end smallexample
 
-For example:
+If you set a breakpoint by line number, @value{GDBN} may determine
+that there is no actual code at the given line number, and arm the
+breakpoint at the next line number with code instead.  This can happen
+for example if the line number you specify corresponds to a source
+location that only contains comments, or contains source code that was
+completely optimized out.  You can identify such a situation happened
+in @code{info breakpoints} output, as the location specification for
+the breakpoint as shown in the what column gives you the line you
+requested, while the breakpoint's location row shows the line the
+breakpoint was actually planted at:
 
 @smallexample
 Num     Type           Disp Enb  Address    What
-1       breakpoint     keep y    <MULTIPLE>
-        stop only if i==1
-        breakpoint already hit 1 time
-1.1                         y    0x080486a2 in void foo<int>() at t.cc:8
-1.2                         y    0x080486ca in void foo<double>() at t.cc:8
+1       breakpoint     keep y               file.c:18
+ 1.1                        y    0x08028832 in void func() at path/to/file.c:20
 @end smallexample
 
 You cannot delete the individual locations from a breakpoint.  However,
@@ -4677,53 +4733,54 @@ any shared library is loaded or unloaded.  Typically, you would
 set a breakpoint in a shared library at the beginning of your
 debugging session, when the library is not loaded, and when the
 symbols from the library are not available.  When you try to set
-breakpoint, @value{GDBN} will ask you if you want to set
-a so called @dfn{pending breakpoint}---breakpoint whose address
-is not yet resolved.
+a breakpoint, @value{GDBN} will ask you for confirmation of whether
+you want to set a so called @dfn{pending breakpoint}---a breakpoint with
+no resolved locations yet.
 
 After the program is run, whenever a new shared library is loaded,
-@value{GDBN} reevaluates all the breakpoints.  When a newly loaded
-shared library contains the symbol or line referred to by some
-pending breakpoint, that breakpoint is resolved and becomes an
-ordinary breakpoint.  When a library is unloaded, all breakpoints
-that refer to its symbols or source lines become pending again.
-
-This logic works for breakpoints with multiple locations, too.  For
-example, if you have a breakpoint in a C@t{++} template function, and
-a newly loaded shared library has an instantiation of that template,
-a new location is added to the list of locations for the breakpoint.
-
-Except for having unresolved address, pending breakpoints do not
+@value{GDBN} reevaluates all the breakpoints' location specs.  When a
+newly loaded shared library contains the symbol or line referred to by
+some pending breakpoint, a location for the breakpoint is found and
+the breakpoint becomes an ordinary breakpoint.  When a library is
+unloaded, breakpoint locations that refer to its symbols or source
+lines are not deleted -- they are instead displayed with a
+@code{<PENDING>} address.  This is so that if the shared library is
+loaded again, the location's enabled/disabled state is preserved.
+
+Except for having no resolved locations, pending breakpoints do not
 differ from regular breakpoints.  You can set conditions or commands,
 enable and disable them and perform other breakpoint operations.
 
 @value{GDBN} provides some additional commands for controlling what
-happens when the @samp{break} command cannot resolve breakpoint
-address specification to an address:
+happens when the @samp{break} command cannot resolve its breakpoint
+location specification to any location:
 
 @kindex set breakpoint pending
 @kindex show breakpoint pending
 @table @code
 @item set breakpoint pending auto
-This is the default behavior.  When @value{GDBN} cannot find the breakpoint
-location, it queries you whether a pending breakpoint should be created.
+This is the default behavior.  When @value{GDBN} cannot find any
+location for the location specification, it queries you whether a
+pending breakpoint should be created.
 
 @item set breakpoint pending on
-This indicates that an unrecognized breakpoint location should automatically
-result in a pending breakpoint being created.
+This indicates that when @value{GDBN} cannot resolve any location for
+the location specification, it should create a pending breakpoint
+without asking for confirmation.
 
 @item set breakpoint pending off
-This indicates that pending breakpoints are not to be created.  Any
-unrecognized breakpoint location results in an error.  This setting does
-not affect any pending breakpoints previously created.
+This indicates that pending breakpoints are not to be created.  If
+@value{GDBN} cannot resolve any location for the location
+specification, it aborts the breakpoint creation with an error.  This
+setting does not affect any pending breakpoints previously created.
 
 @item show breakpoint pending
 Show the current behavior setting for creating pending breakpoints.
 @end table
 
 The settings above only affect the @code{break} command and its
-variants.  Once breakpoint is set, it will be automatically updated
-as shared libraries are loaded and unloaded.
+variants.  Once a breakpoint is created, it will be automatically
+updated as shared libraries are loaded and unloaded.
 
 @cindex automatic hardware breakpoints
 For some targets, @value{GDBN} can automatically decide if hardware or
@@ -5444,8 +5501,8 @@ breakpoint where your program just stopped.
 
 @item clear @var{location}
 Delete any breakpoints set at the specified @var{location}.
-@xref{Specify Location}, for the various forms of @var{location}; the
-most useful ones are listed below:
+@xref{Location Specifications}, for the various forms of
+@var{location}; the most useful ones are listed below:
 
 @table @code
 @item clear @var{function}
@@ -5852,12 +5909,14 @@ you could do the following:
 (gdb) set dprintf-style call
 (gdb) set dprintf-function fprintf
 (gdb) set dprintf-channel mylog
-(gdb) dprintf 25,"at line 25, glob=%d\n",glob
+(gdb) dprintf main.c:25,"at line 25, glob=%d\n",glob
 Dprintf 1 at 0x123456: file main.c, line 25.
 (gdb) info break
-1       dprintf        keep y   0x00123456 in main at main.c:25
+Num     Type           Disp Enb Address     What
+1       dprintf        keep y               main.c:25
         call (void) fprintf (mylog,"at line 25, glob=%d\n",glob)
         continue
+ 1.1                        y   0x00123456  in main at main.c:25
 (gdb)
 @end example
 
@@ -6304,7 +6363,7 @@ argument.
 @itemx u @var{location}
 Continue running your program until either the specified @var{location} is
 reached, or the current stack frame returns.  The location is any of
-the forms described in @ref{Specify Location}.
+the forms described in @ref{Location Specifications}.
 This form of the command uses temporary breakpoints, and
 hence is quicker than @code{until} without an argument.  The specified
 location is actually reached only if it is in the current frame.  This
@@ -6329,7 +6388,7 @@ invocations have returned.
 @item advance @var{location}
 Continue running the program up to the given @var{location}.  An argument is
 required, which should be of one of the forms described in
-@ref{Specify Location}.
+@ref{Location Specifications}.
 Execution will also stop upon exit from the current stack
 frame.  This command is similar to @code{until}, but @code{advance} will
 not skip over recursive function calls, and the target location doesn't
@@ -6429,7 +6488,7 @@ A more flexible solution is to execute @kbd{skip boring}.  This instructs
 @code{foo}.
 
 Functions may be skipped by providing either a function name, linespec
-(@pxref{Specify Location}), regular expression that matches the function's
+(@pxref{Location Specifications}), regular expression that matches the function's
 name, file name or a @code{glob}-style pattern that matches the file name.
 
 On Posix systems the form of the regular expression is
@@ -6466,7 +6525,7 @@ over when stepping.
 @itemx -fu @var{linespec}
 Functions named by @var{linespec} or the function containing the line
 named by @var{linespec} will be skipped over when stepping.
-@xref{Specify Location}.
+@xref{Location Specifications}.
 
 @item -rfunction @var{regexp}
 @itemx -rfu @var{regexp}
@@ -6499,7 +6558,7 @@ will be skipped.
 @item skip function @r{[}@var{linespec}@r{]}
 After running this command, the function named by @var{linespec} or the
 function containing the line named by @var{linespec} will be skipped over when
-stepping.  @xref{Specify Location}.
+stepping.  @xref{Location Specifications}.
 
 If you do not specify @var{linespec}, the function you're currently debugging
 will be skipped.
@@ -7130,9 +7189,8 @@ breakpoints on all threads, or on a particular thread.
 @kindex break @dots{} thread @var{thread-id}
 @item break @var{location} thread @var{thread-id}
 @itemx break @var{location} thread @var{thread-id} if @dots{}
-@var{location} specifies source lines; there are several ways of
-writing them (@pxref{Specify Location}), but the effect is always to
-specify some source line.
+@var{location} specifies a location or locations in your program's
+code.  @xref{Location Specifications}, for details.
 
 Use the qualifier @samp{thread @var{thread-id}} with a breakpoint command
 to specify that you only want @value{GDBN} to stop the program when a
@@ -8932,7 +8990,7 @@ prefer to use Emacs facilities to view source; see @ref{Emacs, ,Using
 
 @menu
 * List::                        Printing source lines
-* Specify Location::            How to specify code locations
+* Location Specifications::     How to specify code locations
 * Edit::                        Editing source files
 * Search::                      Searching source files
 * Source Path::                 Specifying source directories
@@ -8948,7 +9006,7 @@ prefer to use Emacs facilities to view source; see @ref{Emacs, ,Using
 To print lines from a source file, use the @code{list} command
 (abbreviated @code{l}).  By default, ten lines are printed.
 There are several ways to specify what part of the file you want to
-print; see @ref{Specify Location}, for the full list.
+print; see @ref{Location Specifications}, for the full list.
 
 Here are the forms of the @code{list} command most commonly used:
 
@@ -8997,7 +9055,7 @@ each repetition moves up in the source file.
 
 In general, the @code{list} command expects you to supply zero, one or two
 @dfn{locations}.  Locations specify source lines; there are several ways
-of writing them (@pxref{Specify Location}), but the effect is always
+of writing them (@pxref{Location Specifications}), but the effect is always
 to specify some source line.
 
 Here is a complete description of the possible arguments for @code{list}:
@@ -9028,17 +9086,41 @@ Print lines just before the lines last printed.
 As described in the preceding table.
 @end table
 
-@node Specify Location
-@section Specifying a Location
+@node Location Specifications
+@section Location Specifications
 @cindex specifying location
 @cindex location
 @cindex source location
 
 Several @value{GDBN} commands accept arguments that specify a location
 of your program's code.  Since @value{GDBN} is a source-level
-debugger, a location usually specifies some line in the source code.
-Locations may be specified using three different formats:
-linespec locations, explicit locations, or address locations.
+debugger, a location specification usually indicates some line in the
+source code, but it can also indicate a function name, an address, and
+more.
+
+A location specification serves as a blueprint, and it may match more
+than one actual location in your program.  Examples of this situation
+are:
+
+@itemize @bullet
+@item
+Multiple functions in the program may have the same name.
+
+@item
+For a C@t{++} constructor, the @value{NGCC} compiler generates several
+instances of the function body, used in different cases.
+
+@item
+For a C@t{++} template function, a given line in the function can
+correspond to any number of instantiations.
+
+@item
+For an inlined function, a given source line can correspond to several
+places where that function is inlined.
+@end itemize
+
+Locations may be specified using three different formats: linespec
+locations, explicit locations, or address locations.
 
 @menu
 * Linespec Locations::                Linespec locations
@@ -9260,9 +9342,9 @@ want to print if you want to see other parts of the program:
 @item edit @var{location}
 Edit the source file specified by @code{location}.  Editing starts at
 that @var{location}, e.g., at the specified source line of the
-specified file.  @xref{Specify Location}, for all the possible forms
-of the @var{location} argument; here are the forms of the @code{edit}
-command most commonly used:
+specified file.  @xref{Location Specifications}, for all the possible
+forms of the @var{location} argument; here are the forms of the
+@code{edit} command most commonly used:
 
 @table @code
 @item edit @var{number}
@@ -9645,8 +9727,8 @@ well as hex.
 @itemx info line @var{location}
 Print the starting and ending addresses of the compiled code for
 source line @var{location}.  You can specify source lines in any of
-the ways documented in @ref{Specify Location}.  With no @var{location}
-information about the current source line is printed.
+the ways documented in @ref{Location Specifications}.  With no
+@var{location} information about the current source line is printed.
 @end table
 
 For example, we can use @code{info line} to discover the location of
@@ -9870,10 +9952,10 @@ Dump of assembler code from 0x400281 to 0x40028b:
 End of assembler dump.
 @end smallexample
 
-Addresses cannot be specified as a location (@pxref{Specify Location}).
-So, for example, if you want to disassemble function @code{bar}
-in file @file{foo.c}, you must type @samp{disassemble 'foo.c'::bar}
-and not @samp{disassemble foo.c:bar}.
+Addresses cannot be specified as a location (@pxref{Location
+Specifications}).  So, for example, if you want to disassemble
+function @code{bar} in file @file{foo.c}, you must type
+@samp{disassemble 'foo.c'::bar} and not @samp{disassemble foo.c:bar}.
 
 Some architectures have more than one commonly-used set of instruction
 mnemonics or other syntax.
@@ -14466,8 +14548,8 @@ conditions and actions.
 @kindex trace
 @item trace @var{location}
 The @code{trace} command is very similar to the @code{break} command.
-Its argument @var{location} can be any valid location.
-@xref{Specify Location}.  The @code{trace} command defines a tracepoint,
+Its argument @var{location} can be any valid location specification.
+@xref{Location Specifications}.  The @code{trace} command defines a tracepoint,
 which is a point in the target program where the debugger will briefly stop,
 collect some data, and then allow the program to continue.  Setting a tracepoint
 or changing its actions takes effect immediately if the remote stub
@@ -14986,21 +15068,22 @@ the state about installed on target of each location
 @smallexample
 (@value{GDBP}) @b{info trace}
 Num     Type           Disp Enb Address    What
-1       tracepoint     keep y   0x0804ab57 in foo() at main.cxx:7
+1       tracepoint     keep y              foo1
         while-stepping 20
           collect globfoo, $regs
         end
         collect globfoo2
         end
         pass count 1200 
-2       tracepoint     keep y   <MULTIPLE>
+ 1.1                        y   0x0804ab57 in foo1() at main.cxx:7
+2       tracepoint     keep y              func4
         collect $eip
-2.1                         y     0x0804859c in func4 at change-loc.h:35
+ 2.1                        y   0x0804859c in func4 at change-loc.h:35
         installed on target
-2.2                         y     0xb7ffc480 in func4 at change-loc.h:35
+ 2.2                        y   0xb7ffc480 in func4 at change-loc.h:35
         installed on target
-2.3                         y     <PENDING>  set_tracepoint
-3       tracepoint     keep y   0x080485b1 in foo at change-loc.c:29
+3       tracepoint     keep y              foo2
+ 3.1                        y   0x080485b1 in foo2 at change-loc.c:29
         not installed on target
 (@value{GDBP})
 @end smallexample
@@ -16946,7 +17029,8 @@ tag.  For example:
 Breakpoint 2 at 0x40060d: file main.cc, line 10.
 (gdb) info breakpoints
 Num     Type           Disp Enb Address    What
-1       breakpoint     keep y   0x0040060d in function[abi:cxx11](int)
+1       breakpoint     keep y              function(int)
+ 1.1                        y   0x0040060d in function[abi:cxx11](int)
                                            at main.cc:10
 @end smallexample
 
@@ -17426,9 +17510,9 @@ peculiarities and holes to be aware of.
 
 @itemize @bullet
 @item
-Linespecs (@pxref{Specify Location}) are never relative to the current
-crate.  Instead, they act as if there were a global namespace of
-crates, somewhat similar to the way @code{extern crate} behaves.
+Linespecs (@pxref{Location Specifications}) are never relative to the
+current crate.  Instead, they act as if there were a global namespace
+of crates, somewhat similar to the way @code{extern crate} behaves.
 
 That is, if @value{GDBN} is stopped at a breakpoint in a function in
 crate @samp{A}, module @samp{B}, then @code{break B::f} will attempt
@@ -18757,7 +18841,7 @@ Flags @code{-c} and @code{-s} cannot be used together.
 These commands are like the @code{break @dots{} thread @dots{}}
 command (@pxref{Thread Stops}).  The
 @var{location} argument specifies source lines, as described
-in @ref{Specify Location}.
+in @ref{Location Specifications}.
 
 Use the qualifier @samp{task @var{taskno}} with a breakpoint command
 to specify that you only want @value{GDBN} to stop the program when a
@@ -19520,10 +19604,11 @@ These commands can be used to enable or disable type printers.
 @cindex local variables
 @item info scope @var{location}
 List all the variables local to a particular scope.  This command
-accepts a @var{location} argument---a function name, a source line, or
-an address preceded by a @samp{*}, and prints all the variables local
-to the scope defined by that location.  (@xref{Specify Location}, for
-details about supported forms of @var{location}.)  For example:
+accepts a location specification argument---a function name, a source
+line, or an address preceded by a @samp{*}, and prints all the
+variables local to the scope defined by that location specification.
+(@xref{Location Specifications}, for details about supported forms of
+@var{location}.)  For example:
 
 @smallexample
 (@value{GDBP}) @b{info scope command_line_handler}
@@ -20114,8 +20199,8 @@ an address of your own choosing, with the following commands:
 @item jump @var{location}
 @itemx j @var{location}
 Resume execution at @var{location}.  Execution stops again immediately
-if there is a breakpoint there.  @xref{Specify Location}, for a description
-of the different forms of @var{location}.  It is common
+if there is a breakpoint there.  @xref{Location Specifications}, for a
+description of the different forms of @var{location}.  It is common
 practice to use the @code{tbreak} command in conjunction with
 @code{jump}.  @xref{Set Breaks, ,Setting Breakpoints}.
 
@@ -25356,7 +25441,7 @@ use the @code{break-range} command.
 Set a breakpoint for an address range given by
 @var{start-location} and @var{end-location}, which can specify a function name,
 a line number, an offset of lines from the current line or from the start
-location, or an address of an instruction (see @ref{Specify Location},
+location, or an address of an instruction (see @ref{Location Specifications},
 for a list of all the possible ways to specify a @var{location}.)
 The breakpoint will stop execution of the inferior whenever it
 executes an instruction at any address within the specified range,
@@ -30544,11 +30629,10 @@ value is @samp{y}, or disabled, in which case the value is @samp{n}.
 Note that this is not the same as the field @code{enable}.
 
 @item addr
-The address of the breakpoint.  This may be a hexidecimal number,
+The address of the breakpoint.  This may be a hexadecimal number,
 giving the address; or the string @samp{<PENDING>}, for a pending
-breakpoint; or the string @samp{<MULTIPLE>}, for a breakpoint with
-multiple locations.  This field will not be present if no address can
-be determined.  For example, a watchpoint does not have an address.
+breakpoint; This field will not be present if no address can be
+determined.  For example, a watchpoint does not have an address.
 
 @item addr_flags
 Optional field containing any flags related to the address.  These flags are
@@ -30629,16 +30713,14 @@ is not.
 Some extra data, the exact contents of which are type-dependent.
 
 @item locations
-This field is present if the breakpoint has multiple locations.  It is also
-exceptionally present if the breakpoint is enabled and has a single, disabled
-location.
+This field is present for ordinary breakpoints and tracepoints.
 
 The value is a list of locations.  The format of a location is described below.
 
 @end table
 
-A location in a multi-location breakpoint is represented as a tuple with the
-following fields:
+Each location in an ordinary breakpoint or tracepoint is represented
+as a tuple with the following fields:
 
 @table @code
 
@@ -30660,7 +30742,7 @@ at this location.
 @end table
 
 @item addr
-The address of this location as an hexidecimal number.
+The address of this location as an hexadecimal number.
 
 @item addr_flags
 Optional field containing any flags related to the address.  These flags are
@@ -32542,8 +32624,8 @@ fullname="/home/foo/bar/try.c",line="13",arch="i386:x86_64"@}
 @end smallexample
 
 Resumes execution of the inferior program at the location specified by
-parameter.  @xref{Specify Location}, for a description of the
-different forms of @var{location}.
+the parameter.  @xref{Location Specifications}, for a description of
+the different forms of @var{location}.
 
 @subsubheading @value{GDBN} Command
 
@@ -34925,7 +35007,7 @@ next trace frame that corresponds to a tracepoint at an address outside
 the specified range.  Both bounds are considered to be inside the range.
 
 @item line
-Line specification is required as parameter.  @xref{Specify Location}.
+Line specification is required as parameter.  @xref{Location Specifications}.
 Finds next trace frame that corresponds to a tracepoint at
 the specified location.
 
diff --git a/gdb/doc/guile.texi b/gdb/doc/guile.texi
index 3c517230929..63916eed181 100644
--- a/gdb/doc/guile.texi
+++ b/gdb/doc/guile.texi
@@ -1965,7 +1965,7 @@ This constant means that filename completion should be performed.
 
 @item COMPLETE_LOCATION
 This constant means that location completion should be done.
-@xref{Specify Location}.
+@xref{Location Specifications}.
 
 @item COMPLETE_COMMAND
 This constant means that completion should examine @value{GDBN}
diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi
index cb5283e03c0..f933c7d30c9 100644
--- a/gdb/doc/python.texi
+++ b/gdb/doc/python.texi
@@ -577,7 +577,8 @@ either @code{None} or another tuple that contains all the locations
 that match the expression represented as @code{gdb.Symtab_and_line}
 objects (@pxref{Symbol Tables In Python}).  If @var{expression} is
 provided, it is decoded the way that @value{GDBN}'s inbuilt
-@code{break} or @code{edit} commands do (@pxref{Specify Location}).
+@code{break} or @code{edit} commands do (@pxref{Location
+Specifications}).
 @end defun
 
 @defun gdb.prompt_hook (current_prompt)
@@ -4186,7 +4187,7 @@ This constant means that filename completion should be performed.
 @vindex COMPLETE_LOCATION
 @item gdb.COMPLETE_LOCATION
 This constant means that location completion should be done.
-@xref{Specify Location}.
+@xref{Location Specifications}.
 
 @vindex COMPLETE_COMMAND
 @item gdb.COMPLETE_COMMAND
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 9abc1443d96..60c34c4d2f8 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -6179,42 +6179,36 @@ print_one_breakpoint_location (struct breakpoint *b,
   static char bpenables[] = "nynny";
 
   struct ui_out *uiout = current_uiout;
-  int header_of_multiple = 0;
-  int part_of_multiple = (loc != NULL);
   struct value_print_options opts;
 
   get_user_print_options (&opts);
 
   gdb_assert (!loc || loc_number != 0);
-  /* See comment in print_one_breakpoint concerning treatment of
-     breakpoints with single disabled location.  */
-  if (loc == NULL 
-      && (b->loc != NULL 
-	  && (b->loc->next != NULL
-	      || !b->loc->enabled || b->loc->disabled_by_cond)))
-    header_of_multiple = 1;
-  if (loc == NULL)
-    loc = b->loc;
 
   annotate_record ();
 
   /* 1 */
   annotate_field (0);
-  if (part_of_multiple)
-    uiout->field_fmt ("number", "%d.%d", b->number, loc_number);
+  if (loc != nullptr)
+    {
+      if (uiout->is_mi_like_p ())
+	uiout->field_fmt ("number", "%d.%d", b->number, loc_number);
+      else
+	uiout->field_fmt ("number", " %d.%d", b->number, loc_number);
+    }
   else
     uiout->field_signed ("number", b->number);
 
   /* 2 */
   annotate_field (1);
-  if (part_of_multiple)
+  if (loc != nullptr)
     uiout->field_skip ("type");
   else
     uiout->field_string ("type", bptype_string (b->type));
 
   /* 3 */
   annotate_field (2);
-  if (part_of_multiple)
+  if (loc != nullptr)
     uiout->field_skip ("disp");
   else
     uiout->field_string ("disp", bpdisp_text (b->disposition));
@@ -6225,7 +6219,7 @@ print_one_breakpoint_location (struct breakpoint *b,
      display "N*" on CLI, where "*" refers to a footnote below the
      table.  For MI, simply display a "N" without a footnote.  */
   const char *N = (uiout->is_mi_like_p ()) ? "N" : "N*";
-  if (part_of_multiple)
+  if (loc != nullptr)
     uiout->field_string ("enabled", (loc->disabled_by_cond ? N
 				     : (loc->enabled ? "y" : "n")));
   else
@@ -6255,9 +6249,8 @@ print_one_breakpoint_location (struct breakpoint *b,
 	  if (opts.addressprint)
 	    {
 	      annotate_field (4);
-	      if (header_of_multiple)
-		uiout->field_string ("addr", "<MULTIPLE>",
-				     metadata_style.style ());
+	      if (loc == nullptr)
+		uiout->field_skip ("addr");
 	      else if (b->loc == NULL || loc->shlib_disabled)
 		uiout->field_string ("addr", "<PENDING>",
 				     metadata_style.style ());
@@ -6266,14 +6259,22 @@ print_one_breakpoint_location (struct breakpoint *b,
 					loc->gdbarch, loc->address);
 	    }
 	  annotate_field (5);
-	  if (!header_of_multiple)
+	  if (loc == nullptr)
+	    {
+	      if (b->location != nullptr)
+		uiout->field_string
+		  ("what", event_location_to_string (b->location.get ()));
+	      else
+		uiout->field_skip ("what");
+	    }
+	  else
 	    print_breakpoint_location (b, loc);
 	  if (b->loc)
 	    *last_loc = b->loc;
 	}
     }
 
-  if (loc != NULL && !header_of_multiple)
+  if (loc != nullptr)
     {
       std::vector<int> inf_nums;
       int mi_only = 1;
@@ -6296,8 +6297,7 @@ print_one_breakpoint_location (struct breakpoint *b,
 	mi_only = 0;
       output_thread_groups (uiout, "thread-groups", inf_nums, mi_only);
     }
-
-  if (!part_of_multiple)
+  else
     {
       if (b->thread != -1)
 	{
@@ -6315,10 +6315,10 @@ print_one_breakpoint_location (struct breakpoint *b,
 
   uiout->text ("\n");
 
-  if (!part_of_multiple)
+  if (loc == nullptr)
     b->print_one_detail (uiout);
 
-  if (part_of_multiple && frame_id_p (b->frame_id))
+  if (loc != nullptr && frame_id_p (b->frame_id))
     {
       annotate_field (6);
       uiout->text ("\tstop only in stack frame at ");
@@ -6329,7 +6329,7 @@ print_one_breakpoint_location (struct breakpoint *b,
       uiout->text ("\n");
     }
   
-  if (!part_of_multiple && b->cond_string)
+  if (loc == nullptr && b->cond_string)
     {
       annotate_field (7);
       if (is_tracepoint (b))
@@ -6351,7 +6351,7 @@ print_one_breakpoint_location (struct breakpoint *b,
       uiout->text ("\n");
     }
 
-  if (!part_of_multiple && b->thread != -1)
+  if (loc == nullptr && b->thread != -1)
     {
       /* FIXME should make an annotation for this.  */
       uiout->text ("\tstop only in thread ");
@@ -6366,7 +6366,7 @@ print_one_breakpoint_location (struct breakpoint *b,
       uiout->text ("\n");
     }
   
-  if (!part_of_multiple)
+  if (loc == nullptr)
     {
       if (b->hit_count)
 	{
@@ -6392,7 +6392,7 @@ print_one_breakpoint_location (struct breakpoint *b,
 	}
     }
 
-  if (!part_of_multiple && b->ignore_count)
+  if (loc == nullptr && b->ignore_count)
     {
       annotate_field (8);
       uiout->message ("\tignore next %pF hits\n",
@@ -6402,7 +6402,7 @@ print_one_breakpoint_location (struct breakpoint *b,
   /* Note that an enable count of 1 corresponds to "enable once"
      behavior, which is reported by the combination of enablement and
      disposition, so we don't need to mention it here.  */
-  if (!part_of_multiple && b->enable_count > 1)
+  if (loc == nullptr && b->enable_count > 1)
     {
       annotate_field (8);
       uiout->text ("\tdisable after ");
@@ -6416,7 +6416,7 @@ print_one_breakpoint_location (struct breakpoint *b,
       uiout->text (" hits\n");
     }
 
-  if (!part_of_multiple && is_tracepoint (b))
+  if (loc == nullptr && is_tracepoint (b))
     {
       struct tracepoint *tp = (struct tracepoint *) b;
 
@@ -6429,7 +6429,7 @@ print_one_breakpoint_location (struct breakpoint *b,
     }
 
   l = b->commands ? b->commands.get () : NULL;
-  if (!part_of_multiple && l)
+  if (loc == nullptr && l)
     {
       annotate_field (9);
       ui_out_emit_tuple tuple_emitter (uiout, "script");
@@ -6440,7 +6440,7 @@ print_one_breakpoint_location (struct breakpoint *b,
     {
       struct tracepoint *t = (struct tracepoint *) b;
 
-      if (!part_of_multiple && t->pass_count)
+      if (loc == nullptr && t->pass_count)
 	{
 	  annotate_field (10);
 	  uiout->text ("\tpass count ");
@@ -6450,7 +6450,7 @@ print_one_breakpoint_location (struct breakpoint *b,
 
       /* Don't display it when tracepoint or tracepoint location is
 	 pending.   */
-      if (!header_of_multiple && loc != NULL && !loc->shlib_disabled)
+      if (loc != nullptr && !loc->shlib_disabled)
 	{
 	  annotate_field (11);
 
@@ -6468,7 +6468,7 @@ print_one_breakpoint_location (struct breakpoint *b,
 	}
     }
 
-  if (uiout->is_mi_like_p () && !part_of_multiple)
+  if (uiout->is_mi_like_p () && loc == nullptr)
     {
       if (is_watchpoint (b))
 	{
@@ -6513,25 +6513,18 @@ print_one_breakpoint (struct breakpoint *b,
      locations, if any.  */
   if (!printed || allflag)
     {
-      /* If breakpoint has a single location that is disabled, we
-	 print it as if it had several locations, since otherwise it's
-	 hard to represent "breakpoint enabled, location disabled"
-	 situation.
-
-	 Note that while hardware watchpoints have several locations
+      /* Note that while hardware watchpoints have several locations
 	 internally, that's not a property exposed to users.
 
 	 Likewise, while catchpoints may be implemented with
 	 breakpoints (e.g., catch throw), that's not a property
 	 exposed to users.  We do however display the internal
 	 breakpoint locations with "maint info breakpoints".  */
-      if (!is_hardware_watchpoint (b)
-	  && (!is_catchpoint (b) || is_exception_catchpoint (b)
-	      || is_ada_exception_catchpoint (b))
-	  && (allflag
-	      || (b->loc && (b->loc->next
-			     || !b->loc->enabled
-			     || b->loc->disabled_by_cond))))
+      if (!is_watchpoint (b)
+	  && (!is_catchpoint (b)
+	      || ((is_exception_catchpoint (b)
+		  || is_ada_exception_catchpoint (b))
+		  && allflag)))
 	{
 	  gdb::optional<ui_out_emit_list> locations_list;
 

base-commit: ee3272d472e864bcbe86d6c647d7b48df715c72b
-- 
2.36.0


  reply	other threads:[~2022-05-23 17:04 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-19 21:55 [PATCH 0/2] info breakpoints improvements Pedro Alves
2022-05-19 21:55 ` [PATCH 1/2] Always show locations for breakpoints & show canonical location spec Pedro Alves
2022-05-20  6:45   ` Eli Zaretskii
2022-05-23 17:04     ` Pedro Alves [this message]
2022-05-24 13:06       ` [PATCH v2 " Eli Zaretskii
2022-05-25 19:32         ` Pedro Alves
2022-05-26 12:48           ` Eli Zaretskii
2022-05-26 14:04             ` Pedro Alves
2022-05-26 15:03               ` Eli Zaretskii
2022-05-26 15:10                 ` Pedro Alves
2022-05-26 15:33                   ` Eli Zaretskii
2022-05-26 19:29                 ` Pedro Alves
2022-05-26 19:55                   ` Eli Zaretskii
2022-05-26 20:40                     ` Pedro Alves
2023-04-10 15:07                   ` Andrew Burgess
2022-05-20  7:45   ` [PATCH " Metzger, Markus T
2022-05-23 17:05     ` Lancelot SIX
2022-05-19 21:55 ` [PATCH 2/2] Introduce "info breakpoints -hide-locations" Pedro Alves
2022-05-20  6:48   ` Eli Zaretskii
2022-05-20  5:57 ` [PATCH 0/2] info breakpoints improvements Eli Zaretskii
2022-05-23 17:06   ` Pedro Alves
2022-05-24 13:14     ` Eli Zaretskii
2022-05-24 13:45       ` Pedro Alves
2022-05-24  8:38 ` Luis Machado
2022-05-24 10:02   ` Pedro Alves
2022-05-24 13:20     ` Eli Zaretskii
2022-05-24 13:29       ` Pedro Alves
2022-05-24 13:43         ` Eli Zaretskii
2022-05-24 13:50           ` Pedro Alves
2022-05-24 14:03             ` Eli Zaretskii
2022-05-24 14:09               ` Pedro Alves
2022-05-24 14:25                 ` Eli Zaretskii
2022-05-24 14:33                   ` Pedro Alves
2022-05-24 14:11               ` Andreas Schwab
2022-05-24 14:17                 ` Pedro Alves
2022-05-24 19:49                   ` [PATCH] Show enabled locations with disabled breakpoint parent as "y-" (Re: [PATCH 0/2] info breakpoints improvements) Pedro Alves
2022-05-25 13:57                     ` Eli Zaretskii
2022-05-25 19:19                       ` Pedro Alves
2022-05-24 14:26                 ` [PATCH 0/2] info breakpoints improvements Eli Zaretskii

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=625057b2-1691-a472-fa93-0dabacbddd39@palves.net \
    --to=pedro@palves.net \
    --cc=eliz@gnu.org \
    --cc=gdb-patches@sourceware.org \
    /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).