From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr1-f54.google.com (mail-wr1-f54.google.com [209.85.221.54]) by sourceware.org (Postfix) with ESMTPS id 6AEE73839C5F for ; Thu, 19 May 2022 21:55:59 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 6AEE73839C5F Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=palves.net Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-wr1-f54.google.com with SMTP id j25so8988908wrc.9 for ; Thu, 19 May 2022 14:55:59 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=5hBIhtPLZE4osd5J7Xo7S3TECFvH5/FEzNy5LkL+2xs=; b=xmvbAUuwNiy0Ixuith6KjHIEdBipBACjG9iMr2eTS2sZvoyGogar3Zccyf8KNJMQDN MZyU+K9jrDTRaPrX1olVlKvKu3avGpyyQeg+3hWlocAvhz8lZkPz3cu/D0DRA6MjKPeQ dqfeIZmDprK7Lf/fIJzgE3fW1K/aHwkqljO+hCTbADRIxVYqjq+CbOvlwvpeYUt3oUKU vw2hTy3AScNChD0/jiFTwItW24y5Zm5l9z4FvigdBvyO+qGvZDEwiUXR7aDJARPUpkJj 93Smew6py7lpBYyFPdHYa0xF37F70SAq85bsYQCGh6OEbu91RKEERhTeF9HHnE7BbZts by6Q== X-Gm-Message-State: AOAM532SyhOGKwCY/npAxuMmE7mQnRLeDO3mS/9ExJADE7qh8fKPBzWD paYiquUBHXRJvmP4gYnT4ICU6a0/p/U= X-Google-Smtp-Source: ABdhPJzSAqFKomWnWh7NLxUh512IKOGrgYF7DrgZuMcsAkd0Na83AIX+kzJzyj9N7RAjHPhAznKY5w== X-Received: by 2002:a5d:5041:0:b0:20e:74e3:1d3b with SMTP id h1-20020a5d5041000000b0020e74e31d3bmr1710826wrt.323.1652997357199; Thu, 19 May 2022 14:55:57 -0700 (PDT) Received: from localhost ([2001:8a0:f924:2600:209d:85e2:409e:8726]) by smtp.gmail.com with ESMTPSA id s8-20020a7bc0c8000000b003942a244f42sm630386wmh.27.2022.05.19.14.55.55 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 19 May 2022 14:55:56 -0700 (PDT) From: Pedro Alves To: gdb-patches@sourceware.org Subject: [PATCH 1/2] Always show locations for breakpoints & show canonical location spec Date: Thu, 19 May 2022 22:55:51 +0100 Message-Id: <20220519215552.3254012-2-pedro@palves.net> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220519215552.3254012-1-pedro@palves.net> References: <20220519215552.3254012-1-pedro@palves.net> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-9.7 required=5.0 tests=BAYES_00, FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, KAM_DMARC_STATUS, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE, WEIRD_PORT autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 19 May 2022 21:56:03 -0000 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 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 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 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 1.1 n 0x0000000000a2d874 in func(int) at func.c:51 (the last example shows 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) at func.cc:28 4.2 y 0x000000000047abb8 in func(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 "" 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 | 183 +++++++++++++++++++++++++------------------- gdb/breakpoint.c | 95 +++++++++++------------ 2 files changed, 148 insertions(+), 130 deletions(-) diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 90c307a7dd2..7bd791afa06 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -4343,17 +4343,24 @@ Vars,, Convenience Variables}, for a discussion of what you can do with 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}. - -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. +@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. It is also possible to insert a breakpoint that will stop the program only if a specific thread (@pxref{Thread-Specific Breakpoints}) @@ -4407,11 +4414,11 @@ command: @smallexample (@value{GDBP}) info breakpoints Num Type Disp Enb Address What -1 breakpoint keep y +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 +4552,45 @@ 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. Optional argument @var{n} means +print information only about the specified breakpoint(s) (or +watchpoint(s) or tracepoint(s) or catchpoint(s)). + +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. 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. More on +this further below. + +For each breakpoint and breakpoint location, the following columns are +printed: @table @emph @item Breakpoint Numbers @item Type -Breakpoint, watchpoint, or catchpoint. +Breakpoint, watchpoint, tracepoint, or catchpoint. @item Disposition Whether the breakpoint is marked to be disabled or deleted when hit. @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. @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{}. 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{} in this field---see below for details. +Where the breakpoint location is in your program, as a memory address. +For a breakpoint whose location specification hasn't been resolved to +any location yet, this field will contain @samp{}. 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 +line that matches the location specification is loaded. See below for +details. @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, 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. @end table @noindent @@ -4583,8 +4603,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 @@ -4637,23 +4656,31 @@ several places where that function is inlined. In all those cases, @value{GDBN} will insert a breakpoint at all the relevant 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 @samp{} 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 +@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. + +Regulars 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 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}. For example: @smallexample Num Type Disp Enb Address What -1 breakpoint keep y +1 breakpoint keep y foo stop only if i==1 breakpoint already hit 1 time -1.1 y 0x080486a2 in void foo() at t.cc:8 -1.2 y 0x080486ca in void foo() at t.cc:8 + 1.1 y 0x080486a2 in void foo() at t.cc:8 + 1.2 y 0x080486ca in void foo() at t.cc:8 @end smallexample You cannot delete the individual locations from a breakpoint. However, @@ -4677,53 +4704,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{} 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, @value{GDBN} throws 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 @@ -30544,11 +30572,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{}, for a pending -breakpoint; or the string @samp{}, 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 +30656,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 +30685,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 diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 9abc1443d96..724bc778a9b 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", "", - metadata_style.style ()); + if (loc == nullptr) + uiout->field_skip ("addr"); else if (b->loc == NULL || loc->shlib_disabled) uiout->field_string ("addr", "", 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 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)) { @@ -6508,30 +6508,23 @@ print_one_breakpoint (struct breakpoint *b, if (!use_fixed_output) bkpt_tuple_emitter.reset (); - /* If this breakpoint has custom print function, - it's already printed. Otherwise, print individual - locations, if any. */ + /* If this breakpoint has custom print function, it's already + printed. Otherwise, print individual locations, if any, and if + not explicitly disabled by the user. */ 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 locations_list; -- 2.36.0