public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v7 0/2] gdb: setting BP with multiple locations only displays one location
@ 2024-10-29 11:33 Klaus Gerlicher
  2024-10-29 11:33 ` [PATCH v7 1/2] gdb: extend gdb_breakpoint for multiple locations Klaus Gerlicher
  2024-10-29 11:33 ` [PATCH v7 2/2] gdb, breakpoint: output multiple bp locations Klaus Gerlicher
  0 siblings, 2 replies; 8+ messages in thread
From: Klaus Gerlicher @ 2024-10-29 11:33 UTC (permalink / raw)
  To: gdb-patches, aburgess, blarsen, eliz

From: "Gerlicher, Klaus" <klaus.gerlicher@intel.com>

Hi Andrew, Guinevere, all,

Thanks for all of your feedback on V6.

V6 of this series is here:

https://inbox.sourceware.org/gdb-patches/20240930060102.752079-1-klaus.gerlicher@intel.com/

V7 addresses the following suggestions from Andrew:

For the first patch (20240930060102.752079-2-klaus.gerlicher@intel.com):

- harden tests: matching linespec now when possible. This adds a locspec option
  where required.
- explain gdb_breakpoint option a bit more (regex).
- remove a stale comment
- use -wrap and some fill pattern and correct some wrong regex in
  gdb_test_multiple regexes
- replace [string compare ] with eq/ne comparisons.

For the 2nd patch (20240930060102.752079-3-klaus.gerlicher@intel.com):

- fix NEWS
- move the new setting under breakpoint commands.
- fix some printf format identifiers (%u -> %d)
- fix GNU style issues, I found some more not so obvious ones. Using
  clang-format is sometimes not very helpful.
- fix one explicit nullptr comparison
- fix styled_line oversights.
- add some internationalisation
- add wraps where Andrew suggested. I have no idea how to test these...
- output "in inferior" instead of "on inferior"

Thanks
Klaus

Gerlicher, Klaus (2):
  gdb: extend gdb_breakpoint for multiple locations
  gdb, breakpoint: output multiple bp locations

 gdb/NEWS                                      |   4 +
 gdb/breakpoint.c                              | 135 +++++++++++++----
 gdb/doc/gdb.texinfo                           |  45 +++++-
 gdb/testsuite/gdb.ada/bp_inlined_func.exp     |   4 +-
 gdb/testsuite/gdb.ada/homonym.exp             |   8 +-
 gdb/testsuite/gdb.ada/operator_bp.exp         |  18 +--
 .../gdb.base/condbreak-multi-context.exp      |  22 ++-
 gdb/testsuite/gdb.base/ctxobj.exp             |   4 +-
 gdb/testsuite/gdb.base/dtrace-probe.exp       |   4 +-
 gdb/testsuite/gdb.base/foll-fork.exp          |   7 +-
 gdb/testsuite/gdb.base/msym-bp-shl.exp        |   4 +-
 gdb/testsuite/gdb.base/msym-bp.exp            |   2 +-
 .../run-control-while-bg-execution.exp        |   2 +-
 gdb/testsuite/gdb.base/solib-symbol.exp       |   4 +-
 gdb/testsuite/gdb.base/stap-probe.exp         |   8 +-
 gdb/testsuite/gdb.base/step-over-exit.exp     |   2 +-
 gdb/testsuite/gdb.cp/breakpoint-locs.exp      |   2 +-
 gdb/testsuite/gdb.cp/ena-dis-br-range.exp     |   4 +-
 gdb/testsuite/gdb.cp/mb-ctor.exp              |   8 +-
 gdb/testsuite/gdb.cp/mb-inline.exp            |   8 +-
 gdb/testsuite/gdb.cp/mb-templates.exp         |  13 +-
 gdb/testsuite/gdb.cp/meth-typedefs.exp        |   2 +-
 gdb/testsuite/gdb.cp/ovldbreak.exp            |  10 +-
 gdb/testsuite/gdb.cp/paramless.exp            |   4 +-
 gdb/testsuite/gdb.cp/templates.exp            |  22 +--
 gdb/testsuite/gdb.dwarf2/dw2-inline-break.exp |  20 +--
 .../gdb.dwarf2/dw2-skip-prologue.exp          |   2 +-
 gdb/testsuite/gdb.linespec/break-asm-file.exp |   4 +-
 gdb/testsuite/gdb.linespec/cpcompletion.exp   |   2 +
 gdb/testsuite/gdb.linespec/linespec.exp       |  22 +--
 gdb/testsuite/gdb.linespec/multiple-locs.cc   |  41 +++++
 gdb/testsuite/gdb.linespec/multiple-locs.exp  |  57 +++++++
 .../mi-breakpoint-multiple-locations.exp      |   4 +-
 .../gdb.mi/user-selected-context-sync.exp     |  16 +-
 .../gdb.multi/bp-thread-specific.exp          |   6 +-
 .../gdb.multi/inferior-specific-bp.exp        |   3 +-
 .../gdb.multi/multi-target-continue.exp       |   3 +-
 .../gdb.multi/multi-target-ping-pong-next.exp |   6 +-
 gdb/testsuite/gdb.opt/inline-break.exp        |  23 ++-
 gdb/testsuite/gdb.python/py-bp-locations.exp  |   2 +-
 gdb/testsuite/gdb.python/py-breakpoint.exp    |   3 +-
 gdb/testsuite/lib/completion-support.exp      |   3 +
 gdb/testsuite/lib/gdb.exp                     | 143 +++++++++++++++---
 43 files changed, 480 insertions(+), 226 deletions(-)
 create mode 100644 gdb/testsuite/gdb.linespec/multiple-locs.cc
 create mode 100644 gdb/testsuite/gdb.linespec/multiple-locs.exp

-- 
2.34.1

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de
Managing Directors: Sean Fennelly, Jeffrey Schneiderman, Tiffany Doon Silva
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v7 1/2] gdb: extend gdb_breakpoint for multiple locations
  2024-10-29 11:33 [PATCH v7 0/2] gdb: setting BP with multiple locations only displays one location Klaus Gerlicher
@ 2024-10-29 11:33 ` Klaus Gerlicher
  2024-10-29 11:33 ` [PATCH v7 2/2] gdb, breakpoint: output multiple bp locations Klaus Gerlicher
  1 sibling, 0 replies; 8+ messages in thread
From: Klaus Gerlicher @ 2024-10-29 11:33 UTC (permalink / raw)
  To: gdb-patches, aburgess, blarsen, eliz

From: "Gerlicher, Klaus" <klaus.gerlicher@intel.com>

Many tests have gdb_test "break..." style testing which
could be more generically handled by gdb_breakpoint.

This, for example

gdb_test "break func2" \
    "Breakpoint.*at.*func2.*\\(2 locations\\)"

becomes

gdb_breakpoint "func2" -locs 2

where -locs specifies that gdb_breakpoint should try to match
to 2 locations in the "break" output.

Extend gdb_breakpoint with options for matching multiple
breakpoint locations.

Also remove one historical stale comment and trailing space
and indent issues.
---
 gdb/testsuite/gdb.ada/bp_inlined_func.exp     |   4 +-
 gdb/testsuite/gdb.ada/homonym.exp             |   8 +-
 gdb/testsuite/gdb.ada/operator_bp.exp         |  18 +--
 .../gdb.base/condbreak-multi-context.exp      |  22 ++--
 gdb/testsuite/gdb.base/dtrace-probe.exp       |   4 +-
 gdb/testsuite/gdb.base/foll-fork.exp          |   7 +-
 gdb/testsuite/gdb.base/msym-bp-shl.exp        |   4 +-
 gdb/testsuite/gdb.base/msym-bp.exp            |   2 +-
 gdb/testsuite/gdb.base/solib-symbol.exp       |   4 +-
 gdb/testsuite/gdb.base/stap-probe.exp         |   8 +-
 gdb/testsuite/gdb.base/step-over-exit.exp     |   2 +-
 gdb/testsuite/gdb.cp/breakpoint-locs.exp      |   2 +-
 gdb/testsuite/gdb.cp/ena-dis-br-range.exp     |   4 +-
 gdb/testsuite/gdb.cp/mb-ctor.exp              |   8 +-
 gdb/testsuite/gdb.cp/mb-inline.exp            |   8 +-
 gdb/testsuite/gdb.cp/mb-templates.exp         |  13 +-
 gdb/testsuite/gdb.cp/meth-typedefs.exp        |   2 +-
 gdb/testsuite/gdb.cp/ovldbreak.exp            |   4 +-
 gdb/testsuite/gdb.cp/paramless.exp            |   4 +-
 gdb/testsuite/gdb.cp/templates.exp            |  22 ++--
 gdb/testsuite/gdb.dwarf2/dw2-inline-break.exp |  20 ++--
 .../gdb.dwarf2/dw2-skip-prologue.exp          |   2 +-
 gdb/testsuite/gdb.linespec/break-asm-file.exp |   4 +-
 gdb/testsuite/gdb.linespec/linespec.exp       |  20 +---
 .../gdb.multi/bp-thread-specific.exp          |   6 +-
 .../gdb.multi/inferior-specific-bp.exp        |   3 +-
 gdb/testsuite/gdb.opt/inline-break.exp        |  23 ++--
 gdb/testsuite/gdb.python/py-bp-locations.exp  |   2 +-
 gdb/testsuite/lib/gdb.exp                     | 113 +++++++++++++++---
 29 files changed, 175 insertions(+), 168 deletions(-)

diff --git a/gdb/testsuite/gdb.ada/bp_inlined_func.exp b/gdb/testsuite/gdb.ada/bp_inlined_func.exp
index db56a11d12a..028863af3fc 100644
--- a/gdb/testsuite/gdb.ada/bp_inlined_func.exp
+++ b/gdb/testsuite/gdb.ada/bp_inlined_func.exp
@@ -32,9 +32,7 @@ if {![runto_main]} {
 # Check that inserting breakpoint on read_small inlined function inserts
 # 4 breakpoints (or possibly 5, including the read_small function itself).
 
-gdb_test "break read_small" \
-         "Breakpoint $decimal at $hex: read_small\\. \\(\[45\] locations\\)" \
-         "set breakpoint at read_small"
+gdb_breakpoint "read_small" -locs "\[45\]"
 
 # We do not verify each breakpoint info, but use continue commands instead
 # to verify that we properly stop on each expected breakpoint.
diff --git a/gdb/testsuite/gdb.ada/homonym.exp b/gdb/testsuite/gdb.ada/homonym.exp
index 91a4e62e61f..dac20ad1cc4 100644
--- a/gdb/testsuite/gdb.ada/homonym.exp
+++ b/gdb/testsuite/gdb.ada/homonym.exp
@@ -29,13 +29,9 @@ clean_restart ${testfile}
 # Do these tests before running, so we are operating in a known
 # environment.
 
-gdb_test "break Get_Value" \
-    "Breakpoint \[0-9\]+ at $hex: Get_Value. .2 locations." \
-    "set breakpoint at Get_Value"
+gdb_breakpoint "Get_Value" -locs 2
 
-gdb_test "break homonym.adb:Get_Value" \
-    "Breakpoint \[0-9\]+ at $hex: homonym.adb:Get_Value. .2 locations." \
-    "set breakpoint at homonym.adb:Get_Value"
+gdb_breakpoint "homonym.adb:Get_Value" -locs 2
 
 gdb_test "break <homonym__get_value>" \
     "Breakpoint \[0-9\]+ at $hex: file .*homonym\\.adb, line $decimal\\." \
diff --git a/gdb/testsuite/gdb.ada/operator_bp.exp b/gdb/testsuite/gdb.ada/operator_bp.exp
index 2335d492798..d3f78ee6fe6 100644
--- a/gdb/testsuite/gdb.ada/operator_bp.exp
+++ b/gdb/testsuite/gdb.ada/operator_bp.exp
@@ -33,22 +33,12 @@ runto "ops_test.adb:$bp_location"
 
 # Set breakpoints for all operators, using just the operator name in quotes.
 
-set bp_re "Breakpoint $decimal at $hex"
 foreach op { "+" "-" } {
-    set op_re [string_to_regexp $op]
-    gdb_test "break \"$op\"" "$bp_re: \"$op_re\"\\. \\($decimal locations\\).*"
+    gdb_breakpoint "\"$op\"" -locs $::decimal
 }
 
 foreach op { "*" "/" "mod" "rem" "**" "<" "<=" ">" ">=" "=" "and" "or" "xor" "&" "abs" "not"} {
-    set op_re [string_to_regexp $op]
-    gdb_test_multiple "break \"$op\"" "" {
-	-re -wrap "$bp_re: file .*ops.adb, line $decimal." {
-	    pass $gdb_test_name
-	}
-	-re -wrap "$bp_re: \"$op_re\"\\. \\($decimal locations\\).*" {
-	    pass $gdb_test_name
-	}
-    }
+    gdb_breakpoint "\"$op\""
 }
 
 # Make sure we stop correctly in each operator function.
@@ -70,9 +60,7 @@ runto "ops_test.adb:$bp_location"
 # Set breakpoints for all operators, using just the operator name in quotes.
 
 foreach op { "+" "-" } {
-    set op_re [string_to_regexp $op]
-    gdb_test "break ops.\"$op\"" \
-             "Breakpoint $decimal at $hex: ops\\.\"$op_re\"\\. \\(2 locations\\)"
+    gdb_breakpoint "ops.\"$op\"" -locs 2
 }
 
 foreach op { "*" "/" "mod" "rem" "**" "<" "<=" ">" ">=" "=" "and" "or" "xor" "&" "abs" "not"} {
diff --git a/gdb/testsuite/gdb.base/condbreak-multi-context.exp b/gdb/testsuite/gdb.base/condbreak-multi-context.exp
index 3af37081e44..16a05cce0a6 100644
--- a/gdb/testsuite/gdb.base/condbreak-multi-context.exp
+++ b/gdb/testsuite/gdb.base/condbreak-multi-context.exp
@@ -109,24 +109,22 @@ with_test_prefix "scenario 1" {
     # and C::func) should be disabled.  We do not test location
     # indices strictly at this moment, because we don't know them,
     # yet.  We have strict location index tests below.
-    gdb_test "break func if a == 10" \
-	[multi_line \
+    set extra [multi_line \
 	     "${warning} at location $decimal, disabling:" \
 	     "  No symbol \"a\" in current context." \
 	     "${warning} at location $decimal, disabling:" \
-	     "  No symbol \"a\" in current context." \
-	     "Breakpoint $decimal at $fill .3 locations."] \
-	"define bp with condition a == 10"
+	     "  No symbol \"a\" in current context."]
+    gdb_breakpoint "func if a == 10" -locs 3 -extra $extra -locspec "func"
+
     set bpnum1 [get_integer_valueof "\$bpnum" 0 "get bpnum1"]
 
-    gdb_test "break func if c == 30" \
-	[multi_line \
-	     ".*${warning} at location $decimal, disabling:" \
-	     "  No symbol \"c\" in current context." \
-	     ".*${warning} at location $decimal, disabling:" \
+    set extra [multi_line \
+	     "${warning} at location $decimal, disabling:" \
 	     "  No symbol \"c\" in current context." \
-	     ".*Breakpoint $decimal at $fill .3 locations."] \
-	"define bp with condition c == 30"
+	     "${warning} at location $decimal, disabling:" \
+	     "  No symbol \"c\" in current context."]
+    gdb_breakpoint "func if c == 30" -locs 3 -extra $extra -locspec "func"
+
     set bpnum2 [get_integer_valueof "\$bpnum" 0 "get bpnum2"]
 
     find_location_contexts
diff --git a/gdb/testsuite/gdb.base/dtrace-probe.exp b/gdb/testsuite/gdb.base/dtrace-probe.exp
index a8c38f91fb6..2824b6ad27c 100644
--- a/gdb/testsuite/gdb.base/dtrace-probe.exp
+++ b/gdb/testsuite/gdb.base/dtrace-probe.exp
@@ -92,9 +92,7 @@ proc dtrace_test {} {
         "print \$_probe_arg1 for probe progress-counter"
 
     # Set a breakpoint with multiple probe locations.
-    gdb_test "break -pdtrace test:two-locations" \
-        "Breakpoint \[0-9\]+ at $hex.*2 locations.*" \
-        "set multi-location probe breakpoint (probe two-locations)"
+    gdb_breakpoint "-pdtrace test:two-locations" -locs 2
 
     return 0
 }
diff --git a/gdb/testsuite/gdb.base/foll-fork.exp b/gdb/testsuite/gdb.base/foll-fork.exp
index 0d801f004e4..177bc71f9bc 100644
--- a/gdb/testsuite/gdb.base/foll-fork.exp
+++ b/gdb/testsuite/gdb.base/foll-fork.exp
@@ -183,11 +183,8 @@ proc_with_prefix test_follow_fork { follow-fork-mode detach-on-fork cmd } {
     # locations it means there are two program spaces.
     if {${detach-on-fork} == "off" || ${follow-fork-mode} == "child"} {
 	set bpnum "<unset>"
-	gdb_test_multiple "break callee" "break callee" {
-	    -re -wrap "Breakpoint ($::decimal) at $::hex: callee\\. \\(2 locations\\)" {
-		set bpnum $expect_out(1,string)
-		pass $gdb_test_name
-	    }
+	if { [gdb_breakpoint "callee" -locs 2] } {
+	    set bpnum [get_integer_valueof "\$bpnum" 0 "get bpnum"]
 	}
 
 	set any {[^\r\n]+}
diff --git a/gdb/testsuite/gdb.base/msym-bp-shl.exp b/gdb/testsuite/gdb.base/msym-bp-shl.exp
index 31af1f90f31..ab178a18f9e 100644
--- a/gdb/testsuite/gdb.base/msym-bp-shl.exp
+++ b/gdb/testsuite/gdb.base/msym-bp-shl.exp
@@ -61,7 +61,7 @@ proc test {debug} {
     # Should find two locations: the static foo in the
     # msym-bp-shl-main-2 file, and <foo@plt>, both in the main binary.
     with_test_prefix "before run" {
-	gdb_test "break foo" "\\(2 locations\\)"
+	gdb_breakpoint "foo" -locs 2 -locspec ""
 
 	if {$debug} {
 	    test_info_break_2 \
@@ -85,7 +85,7 @@ proc test {debug} {
     # foo in the msym-bp-shl-main-2 file, and the extern foo in the
     # shared library.
     with_test_prefix "at main" {
-	gdb_test "break foo" "\\(2 locations\\)"
+	gdb_breakpoint "foo" -locs 2 -locspec ""
 
 	if {$debug} {
 	    test_info_break_2 \
diff --git a/gdb/testsuite/gdb.base/msym-bp.exp b/gdb/testsuite/gdb.base/msym-bp.exp
index 84d29020900..e154ea6da16 100644
--- a/gdb/testsuite/gdb.base/msym-bp.exp
+++ b/gdb/testsuite/gdb.base/msym-bp.exp
@@ -52,7 +52,7 @@ proc test {debug} {
 	upvar debug debug
 
 	with_test_prefix $prefix {
-	    gdb_test "break foo" "\\(2 locations\\)"
+	    gdb_breakpoint "foo" -locs 2 -locspec ""
 
 	    if {$debug} {
 		test_info_break_2 \
diff --git a/gdb/testsuite/gdb.base/solib-symbol.exp b/gdb/testsuite/gdb.base/solib-symbol.exp
index 1ec386703cf..6759156ef83 100644
--- a/gdb/testsuite/gdb.base/solib-symbol.exp
+++ b/gdb/testsuite/gdb.base/solib-symbol.exp
@@ -57,8 +57,6 @@ gdb_test "continue" \
 	 "Continuing.*"
 
 # This symbol is now looked up in the ELF library and the binary.
-gdb_test "br foo2" \
-	 "Breakpoint.*: foo2. .2 locations..*" \
-	 "foo2 in mdlib"
+gdb_breakpoint "foo2" -locs 2
 
 gdb_exit
diff --git a/gdb/testsuite/gdb.base/stap-probe.exp b/gdb/testsuite/gdb.base/stap-probe.exp
index 40e8c5e06f3..6bbbe837f84 100644
--- a/gdb/testsuite/gdb.base/stap-probe.exp
+++ b/gdb/testsuite/gdb.base/stap-probe.exp
@@ -181,9 +181,7 @@ proc stap_test {exec_name {args ""}} {
     	"check \$_probe_arg1 for probe user"
 
     # Set a breakpoint with multiple probe locations.
-    gdb_test "break -pstap test:two" \
-	"Breakpoint \[0-9\]+ at $hex.*2 locations.*" \
-	"set multi-location probe breakpoint (probe two)"
+    gdb_breakpoint "-pstap test:two" -locs 2 -locspec ""
 
     # Reinit GDB, set a breakpoint on probe m4.
     delete_breakpoints
@@ -273,9 +271,7 @@ proc stap_test_no_debuginfo {exec_name {args ""}} {
     # Set a breakpoint with multiple probe locations.
     # In this scenario, we may expect more than 2 locations because of
     # the optimizations (inlining, loop unrolling, etc).
-    gdb_test "break -pstap test:two" \
-	"Breakpoint .* at $hex.*\[0-9\]+ locations.*" \
-	"set multi-location probe breakpoint (probe two)"
+    gdb_breakpoint "-pstap test:two"  -locs "\[0-9\]+"
 
     # Reinit GDB, set a breakpoint on probe m4.
     delete_breakpoints
diff --git a/gdb/testsuite/gdb.base/step-over-exit.exp b/gdb/testsuite/gdb.base/step-over-exit.exp
index d373b1a28ad..7c657c7f0f8 100644
--- a/gdb/testsuite/gdb.base/step-over-exit.exp
+++ b/gdb/testsuite/gdb.base/step-over-exit.exp
@@ -44,7 +44,7 @@ gdb_test "set detach-on-fork off"
 
 # Step 1, find the syscall instruction address.
 
-gdb_test "break _exit" "Breakpoint $decimal at .*"
+gdb_breakpoint "_exit"
 
 # Hit the breakpoint on _exit.  The address of syscall insn is recorded.
 
diff --git a/gdb/testsuite/gdb.cp/breakpoint-locs.exp b/gdb/testsuite/gdb.cp/breakpoint-locs.exp
index 088a7660276..e873a97356e 100644
--- a/gdb/testsuite/gdb.cp/breakpoint-locs.exp
+++ b/gdb/testsuite/gdb.cp/breakpoint-locs.exp
@@ -26,4 +26,4 @@ if { [prepare_for_testing "failed to prepare" $testfile "$srcfile $srcfile2"\
     return -1
 }
 
-gdb_test "break N1::C1::baz" "\\(2 locations\\)"
+gdb_breakpoint "N1::C1::baz" -locs 2
diff --git a/gdb/testsuite/gdb.cp/ena-dis-br-range.exp b/gdb/testsuite/gdb.cp/ena-dis-br-range.exp
index 103d38baa2f..0bd1d2e1c0d 100644
--- a/gdb/testsuite/gdb.cp/ena-dis-br-range.exp
+++ b/gdb/testsuite/gdb.cp/ena-dis-br-range.exp
@@ -51,9 +51,7 @@ proc make_info_breakpoint_reply_re {b1 b2 b21 b22 b23 b24} {
 	       ]
 }
 
-gdb_test "break foo::overload" \
-    "Breakpoint \[0-9\]+ at $hex: foo::overload. .4 locations." \
-    "set breakpoint at overload"
+gdb_breakpoint "foo::overload" -locs 4
 
 gdb_test "info break" [make_info_breakpoint_reply_re y y y y y y] \
     "breakpoint info"
diff --git a/gdb/testsuite/gdb.cp/mb-ctor.exp b/gdb/testsuite/gdb.cp/mb-ctor.exp
index 1a84b7990f4..f628ea5e997 100644
--- a/gdb/testsuite/gdb.cp/mb-ctor.exp
+++ b/gdb/testsuite/gdb.cp/mb-ctor.exp
@@ -38,15 +38,11 @@ if {![runto_main]} {
 # Set a breakpoint with multiple locations
 # and a condition.
 
-gdb_test "break 'Derived::Derived(int)'" \
-    "Breakpoint.*at.*: Derived::Derived.int.. \\(2 locations\\).*" \
-    "set-breakpoint at ctor"
+gdb_breakpoint "Derived::Derived(int)" -locs 2
 
 gdb_breakpoint [gdb_get_line_number "set breakpoint here"]
 
-gdb_test "break 'Derived::~Derived()'" \
-    "Breakpoint.*at.*: Derived::~Derived... \\(2 locations\\).*" \
-    "set-breakpoint at dtor"
+gdb_breakpoint "Derived::~Derived()" -locs 2
 
 gdb_test "continue" \
     ".*Breakpoint.*Derived.*i=7.*" \
diff --git a/gdb/testsuite/gdb.cp/mb-inline.exp b/gdb/testsuite/gdb.cp/mb-inline.exp
index db80bb48e40..f34a12e4953 100644
--- a/gdb/testsuite/gdb.cp/mb-inline.exp
+++ b/gdb/testsuite/gdb.cp/mb-inline.exp
@@ -33,9 +33,7 @@ set bp_location [gdb_get_line_number "set breakpoint here" $hdrfile]
 
 # Set a breakpoint with multiple locations.
 
-gdb_test "break $hdrfile:$bp_location" \
-    "Breakpoint.*at.*: $hdrfile:$bp_location. \\(2 locations\\).*" \
-    "set breakpoint"
+gdb_breakpoint "$hdrfile:$bp_location" -locs 2
 
 # Do "info break" now so we can easily compare it with the later "info break"
 # if problems arise.
@@ -83,9 +81,7 @@ if { ![runto_main] } {
     return 0
 }
 
-gdb_test "break $hdrfile:$bp_location" \
-    "Breakpoint.*at.*: $hdrfile:$bp_location. \\(2 locations\\).*" \
-    "set multi_line_foo breakpoint"
+gdb_breakpoint "$hdrfile:$bp_location" -locs 2
 gdb_test "continue" \
     ".*Breakpoint.*multi_line_foo \\(i=0\\).*" \
     "run to multi_line_foo breakpoint 4 afn"
diff --git a/gdb/testsuite/gdb.cp/mb-templates.exp b/gdb/testsuite/gdb.cp/mb-templates.exp
index 2df88a322bb..3044223c4f4 100644
--- a/gdb/testsuite/gdb.cp/mb-templates.exp
+++ b/gdb/testsuite/gdb.cp/mb-templates.exp
@@ -30,9 +30,8 @@ set bp_location [gdb_get_line_number "set breakpoint here"]
 # Set a breakpoint with multiple locations
 # and a condition.
 
-gdb_test "break $srcfile:$bp_location if i==1" \
-    "Breakpoint.*at.*: $srcfile:$bp_location. \\(2 locations\\).*" \
-    "initial condition: set breakpoint"
+gdb_breakpoint "$srcfile:$bp_location if i==1" -locs 2 \
+    -locspec "$srcfile:$bp_location"
 
 gdb_run_cmd
 
@@ -55,9 +54,7 @@ delete_breakpoints
 gdb_test "kill" "" "kill" \
          {Kill the program being debugged\? \(y or n\) } "y"
 
-gdb_test "break $srcfile:$bp_location" \
-    "Breakpoint.*at.*: $srcfile:$bp_location. \\(2 locations\\).*" \
-    "separate condition: set breakpoint"
+gdb_breakpoint "$srcfile:$bp_location" -locs 2
 
 gdb_test_no_output {condition $bpnum i==1} \
     "separate condition: set condition"
@@ -111,9 +108,7 @@ if { ![runto_main] } {
     return 0
 }
 
-gdb_test "break $srcfile:$bp_location" \
-    "Breakpoint.*at.*: $srcfile:$bp_location. \\(2 locations\\).*" \
-    "set multi_line_foo breakpoint"
+gdb_breakpoint "break $srcfile:$bp_location" -locs 2
 gdb_test "continue" \
     ".*Breakpoint.*multi_line_foo<int> \\(i=0\\).*" \
     "run to multi_line_foo breakpoint 2 <int>"
diff --git a/gdb/testsuite/gdb.cp/meth-typedefs.exp b/gdb/testsuite/gdb.cp/meth-typedefs.exp
index 149f44c6c17..03163121df2 100644
--- a/gdb/testsuite/gdb.cp/meth-typedefs.exp
+++ b/gdb/testsuite/gdb.cp/meth-typedefs.exp
@@ -181,7 +181,7 @@ foreach f [list "$func" "'$func'"] {
 	     "$line3${any}// test${any}"]
 
     delete_breakpoints
-    gdb_test "break $f" "\\(3 locations\\)"
+    gdb_breakpoint "$f" -locs 3 -locspec ""
 }
 
 gdb_exit
diff --git a/gdb/testsuite/gdb.cp/ovldbreak.exp b/gdb/testsuite/gdb.cp/ovldbreak.exp
index 99d0a388adb..84efb37b8db 100644
--- a/gdb/testsuite/gdb.cp/ovldbreak.exp
+++ b/gdb/testsuite/gdb.cp/ovldbreak.exp
@@ -443,9 +443,7 @@ gdb_test "break foo::foofunc" \
 # Test breaking on an overloaded function when multiple-symbols
 # is set to "all"
 gdb_test_no_output "set multiple-symbols all"
-gdb_test "break foo::foofunc" \
-    "Breakpoint \[0-9\]+ at ${hex}: foo::foofunc. .2 locations..*" \
-    "break on ambiguous symbol when multiple-symbols is set to all"
+gdb_breakpoint "foo::foofunc" -locs 2
 
 # That's all, folks.
 
diff --git a/gdb/testsuite/gdb.cp/paramless.exp b/gdb/testsuite/gdb.cp/paramless.exp
index fe7c0b38748..d44c4f13073 100644
--- a/gdb/testsuite/gdb.cp/paramless.exp
+++ b/gdb/testsuite/gdb.cp/paramless.exp
@@ -36,10 +36,10 @@ delete_breakpoints
 gdb_breakpoint "outer<char>::fn<short>" message
 delete_breakpoints
 
-gdb_test "break outer::fn" "Breakpoint $decimal at .*2 locations."
+gdb_breakpoint "outer::fn" -locs 2
 delete_breakpoints
 
-gdb_test "break toplev" "Breakpoint $decimal at .*2 locations."
+gdb_breakpoint "toplev" -locs 2
 delete_breakpoints
 
 gdb_breakpoint "toplev<char>" message
diff --git a/gdb/testsuite/gdb.cp/templates.exp b/gdb/testsuite/gdb.cp/templates.exp
index 8dd0cdc70ef..3ca8b20d844 100644
--- a/gdb/testsuite/gdb.cp/templates.exp
+++ b/gdb/testsuite/gdb.cp/templates.exp
@@ -620,25 +620,25 @@ gdb_test_no_output "set multiple-symbols all"
 
 # Test setting breakpoints in a method of all class template instantiations,
 # including overloads.
-gdb_test "break Foo::foo"  "Breakpoint.*at.* \\(3 locations\\)"
+gdb_breakpoint "Foo::foo" -locs 3
 foreach t [list "int" "char" "volatile char *"] {
     gdb_breakpoint "Foo<$t>::foo (int, $t)"
     gdb_breakpoint "Foo::foo (int, $t)"
 }
 
-gdb_test "break Bar::bar" "Breakpoint.*at.* \\(2 locations\\)"
-gdb_test "break Bar::bar (int, int)" "Breakpoint.*at.* \\(2 locations\\)"
+gdb_breakpoint "Bar::bar" -locs 2
+gdb_breakpoint "Bar::bar (int, int)" -locs 2
 foreach val [list 1 33] {
     gdb_breakpoint "Bar<int, $val>::bar (int, int)"
 }
 
 # Test setting breakpoints in a member function template of a class template,
 # including overloads.
-gdb_test "break Foozle::fogey" "Breakpoint.*at.* \\(9 locations\\)" \
-    "break at template method fogey"
+gdb_breakpoint "Foozle::fogey" -locs 9
+
 foreach t [list "int" "char" "Empty<int>"] {
-    gdb_test "break Foozle::fogey ($t)" "Breakpoint.*at.* \\(3 locations\\)"
-    gdb_test "break Foozle::fogey<$t>" "Breakpoint.*at.* \\(3 locations\\)"
+    gdb_breakpoint "Foozle::fogey ($t)" -locs 3
+    gdb_breakpoint "Foozle::fogey<$t>" -locs 3
     foreach u [list "int" "char" "Empty<int>"] {
 	gdb_breakpoint "Foozle<$t>::fogey<$u>" message
 	gdb_assert { [gdb_breakpoint "Foozle<$t>::fogey<$u> ($u)" no-message] } \
@@ -657,10 +657,10 @@ foreach t [list "int" "char" "Empty<int>"] {
 # operator<<:
 #   1. operator<< <Empty<int>>
 #   2. operator<< <Foozle<int>>
-gdb_test "break -source $srcfile -func operator<" \
-    "Breakpoint.*at.* \\(4 locations\\)"
-gdb_test "break -source $srcfile -func operator<<" \
-    "Breakpoint.*at.* \\(2 locations\\)"
+gdb_breakpoint "-source $srcfile -func operator<" -locs 4 -locspec \
+    "-source $srcfile -function operator<"
+gdb_breakpoint "-source $srcfile -func operator<<" -locs 2 -locspec \
+   "-source $srcfile -function operator<<"
 foreach t [list "Empty" "Foozle"] {
     set tt "$t<int>"
     gdb_breakpoint "operator< <$tt>" message
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-inline-break.exp b/gdb/testsuite/gdb.dwarf2/dw2-inline-break.exp
index 2e6f7114c33..6371b629d9b 100644
--- a/gdb/testsuite/gdb.dwarf2/dw2-inline-break.exp
+++ b/gdb/testsuite/gdb.dwarf2/dw2-inline-break.exp
@@ -44,8 +44,8 @@ gdb_test "break func1" \
 # The result should be a breakpoint with two locations: the
 # out-of-line function and the single inlined instance.
 #
-gdb_test "break func2" \
-    "Breakpoint.*at.*func2.*\\(2 locations\\)"
+gdb_breakpoint "func2" -locs 2
+
 
 #
 # func3b is a static inlined function that is called once from
@@ -62,8 +62,7 @@ gdb_test "break func3b" \
 # the inlined call to func4a in main, and the inlined instance
 # within the out-of-line func4a.
 #
-gdb_test "break func4b" \
-    "Breakpoint.*at.*func4b.*\\(2 locations\\)"
+gdb_breakpoint "func4b" -locs 2
 
 #
 # func5b is a non-static inlined function that is called once
@@ -71,8 +70,8 @@ gdb_test "break func4b" \
 # breakpoint with two locations: the out-of-line function and the
 # inlined instance within the inlined call to func5a in main.
 #
-gdb_test "break func5b" \
-    "Breakpoint.*at.*func5b.*\\(2 locations\\)"
+gdb_breakpoint "func5b" -locs 2
+
 #
 # func6b is a non-static inlined function that is called once from
 # within another non-static inlined function.  The result should be
@@ -80,8 +79,7 @@ gdb_test "break func5b" \
 # inlined instance within the out-of-line func6a, and the inlined
 # instance within the inlined call to func6a in main,
 #
-gdb_test "break func6b" \
-    "Breakpoint.*at.*func6b.*\\(3 locations\\)"
+gdb_breakpoint "func6b" -locs 3
 
 #
 # func7b is a static inlined function that is called twice: once from
@@ -89,8 +87,7 @@ gdb_test "break func6b" \
 # two locations: the inlined instance within the inlined instance of
 # func7a, and the inlined instance within main.
 #
-gdb_test "break func7b" \
-    "Breakpoint.*at.*func7b.*\\(2 locations\\)"
+gdb_breakpoint "func7b" -locs 2
 
 #
 # func8b is a non-static inlined function that is called twice: once
@@ -99,8 +96,7 @@ gdb_test "break func7b" \
 # within the inlined instance of func7a, and the inlined instance
 # within main.
 #
-gdb_test "break func8b" \
-    "Breakpoint.*at.*func8b.*\\(3 locations\\)"
+gdb_breakpoint "func8b" -locs 3
 
 #
 # func1 is a static inlined function.  The result should be that no
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-skip-prologue.exp b/gdb/testsuite/gdb.dwarf2/dw2-skip-prologue.exp
index 78ac57439f3..49fc2293dc4 100644
--- a/gdb/testsuite/gdb.dwarf2/dw2-skip-prologue.exp
+++ b/gdb/testsuite/gdb.dwarf2/dw2-skip-prologue.exp
@@ -71,7 +71,7 @@ if ![runto_main] {
     return -1
 }
 
-gdb_breakpoint "func"
+gdb_breakpoint "func" -locs 2 -locspec ""
 gdb_continue_to_breakpoint "func"
 
 # Sanity check GDB has really found 2 locations
diff --git a/gdb/testsuite/gdb.linespec/break-asm-file.exp b/gdb/testsuite/gdb.linespec/break-asm-file.exp
index 1044fc79a26..3977e6aac85 100644
--- a/gdb/testsuite/gdb.linespec/break-asm-file.exp
+++ b/gdb/testsuite/gdb.linespec/break-asm-file.exp
@@ -60,7 +60,5 @@ gdb_test "break b/$asm_file0:func" \
 
 gdb_test "delete 2"
 
-gdb_test "break $asm_file0:func" \
-    "Breakpoint 3 at 0x\[0-9a-fA-F\]+: .*$asm_file0.*(2 locations).*" \
-    "set a break-point at function in all instances for a selected ASM file."
+gdb_breakpoint "$asm_file0:func" -locs 2
 
diff --git a/gdb/testsuite/gdb.linespec/linespec.exp b/gdb/testsuite/gdb.linespec/linespec.exp
index 576d788cae0..6398309f7e4 100644
--- a/gdb/testsuite/gdb.linespec/linespec.exp
+++ b/gdb/testsuite/gdb.linespec/linespec.exp
@@ -144,17 +144,11 @@ if { [is_remote host] } {
     }
 }
 
-gdb_test "break thefile.cc:$l1" \
-    "Breakpoint $decimal at $hex: thefile.cc:$l1. \[(\]2 locations\[)\]" \
-    "multi-location break using file:line"
+gdb_breakpoint "thefile.cc:$l1" -locs 2
 
-gdb_test "break dupname" \
-    "Breakpoint $decimal at $hex: dupname. \[(\]2 locations\[)\]" \
-    "multi-location break using duplicate function name"
+gdb_breakpoint "dupname" -locs 2
 
-gdb_test "break dupname:label" \
-    "Breakpoint $decimal at $hex: dupname:label. \[(\]2 locations\[)\]" \
-    "multi-location break using duplicate function name and label"
+gdb_breakpoint "dupname:label" -locs 2
 
 # Testing if the "condition" command completes only the breakpoints,
 # not the locations.
@@ -165,9 +159,7 @@ gdb_test "break lspec.cc:nosuchfunction" \
     "Function \"nosuchfunction\" not defined in \"lspec.cc\"." \
     "set breakpoint on non-existent function"
 
-gdb_test "break NameSpace::overload" \
-    "Breakpoint \[0-9\]+ at $hex: NameSpace::overload. \[(\]3 locations\[)\]" \
-    "set breakpoint at all instances of NameSpace::overload"
+gdb_breakpoint "NameSpace::overload" -locs 3
 
 gdb_test "break lspec.cc:NameSpace::overload" \
     "Breakpoint \[0-9\]+ at $hex: file .*lspec.cc, line 7." \
@@ -210,6 +202,4 @@ gdb_test "file $binfile" \
     "Reading symbols from .*" \
     "set the new inferior file for linespec tests"
 
-gdb_test "break -q main" \
-    "Breakpoint \[0-9\]+ at $hex: -qualified main. .2 locations." \
-    "set breakpoint at main in both inferiors"
+gdb_breakpoint "-qualified main" -locs 2
diff --git a/gdb/testsuite/gdb.multi/bp-thread-specific.exp b/gdb/testsuite/gdb.multi/bp-thread-specific.exp
index 11dc2483624..0e289790d7d 100644
--- a/gdb/testsuite/gdb.multi/bp-thread-specific.exp
+++ b/gdb/testsuite/gdb.multi/bp-thread-specific.exp
@@ -73,16 +73,14 @@ gdb_test "info threads" \
 # Set the first breakpoint.  Currently this is going to insert at two
 # locations ('foo' in both inferiors) even though only one of those
 # locations will ever trigger ('foo' in inferior 2).
-gdb_test "break foo thread 2.1" \
-    "Breakpoint $decimal at $hex: file \[^\r\n\]+$srcfile, line $decimal\\."
+gdb_breakpoint "foo thread 2.1"
 
 set bpnum [get_integer_valueof "\$bpnum" "INVALID"]
 
 # Now set another breakpoint that will be at the same location as the
 # earlier breakpoint.  Check that the thread-id used when describing
 # the earlier breakpoints is correct.
-gdb_test "break foo thread 1.1" \
-    "Breakpoint $decimal at $hex: file \[^\r\n\]+$srcfile, line $decimal\\."
+gdb_breakpoint "foo thread 1.1"
 
 # Save the breakpoints into a file.
 if {[is_remote host]} {
diff --git a/gdb/testsuite/gdb.multi/inferior-specific-bp.exp b/gdb/testsuite/gdb.multi/inferior-specific-bp.exp
index 82cc9240e50..67069e1da4d 100644
--- a/gdb/testsuite/gdb.multi/inferior-specific-bp.exp
+++ b/gdb/testsuite/gdb.multi/inferior-specific-bp.exp
@@ -172,8 +172,7 @@ proc check_info_breakpoints { testname bp_number expected_loc_count } {
 # Create an inferior-specific breakpoint.  Use gdb_test instead of
 # gdb_breakpoint here as we want to check the breakpoint was placed in
 # multiple locations.
-gdb_test "break foo inferior 1" \
-    "Breakpoint $decimal at $hex: foo\\. \\(2 locations\\)"
+gdb_breakpoint "foo inferior 1" -locs 2 -locspec "foo"
 set bp_number [get_integer_valueof "\$bpnum" "INVALID" \
 		  "get b/p number for inferior specific breakpoint"]
 
diff --git a/gdb/testsuite/gdb.opt/inline-break.exp b/gdb/testsuite/gdb.opt/inline-break.exp
index 9c57d22404b..70549301964 100644
--- a/gdb/testsuite/gdb.opt/inline-break.exp
+++ b/gdb/testsuite/gdb.opt/inline-break.exp
@@ -96,8 +96,7 @@ gdb_test "break func1" \
 # The result should be a breakpoint with two locations: the
 # out-of-line function and the single inlined instance.
 #
-gdb_test "break func2" \
-    "Breakpoint.*at.*func2.*\\(2 locations\\)"
+gdb_breakpoint "func2" -locs 2
 
 #
 # func3b is a static inlined function that is called once from
@@ -114,8 +113,8 @@ gdb_test "break func3b" \
 # the inlined call to func4a in main, and the inlined instance
 # within the out-of-line func4a.
 #
-gdb_test "break func4b" \
-    "Breakpoint.*at.*func4b.*\\(2 locations\\)"
+gdb_breakpoint "func4b" -locs 2
+
 
 #
 # func5b is a non-static inlined function that is called once
@@ -123,8 +122,8 @@ gdb_test "break func4b" \
 # breakpoint with two locations: the out-of-line function and the
 # inlined instance within the inlined call to func5a in main.
 #
-gdb_test "break func5b" \
-    "Breakpoint.*at.*func5b.*\\(2 locations\\)"
+gdb_breakpoint "func5b" -locs 2
+
 #
 # func6b is a non-static inlined function that is called once from
 # within another non-static inlined function.  The result should be
@@ -132,8 +131,7 @@ gdb_test "break func5b" \
 # inlined instance within the out-of-line func6a, and the inlined
 # instance within the inlined call to func6a in main,
 #
-gdb_test "break func6b" \
-    "Breakpoint.*at.*func6b.*\\(3 locations\\)"
+gdb_breakpoint "func6b" -locs 3
 
 #
 # func7b is a static inlined function that is called twice: once from
@@ -141,8 +139,7 @@ gdb_test "break func6b" \
 # two locations: the inlined instance within the inlined instance of
 # func7a, and the inlined instance within main.
 #
-gdb_test "break func7b" \
-    "Breakpoint.*at.*func7b.*\\(2 locations\\)"
+gdb_breakpoint "func7b" -locs 2
 
 #
 # func8b is a non-static inlined function that is called twice: once
@@ -151,8 +148,7 @@ gdb_test "break func7b" \
 # within the inlined instance of func7a, and the inlined instance
 # within main.
 #
-gdb_test "break func8b" \
-    "Breakpoint.*at.*func8b.*\\(3 locations\\)"
+gdb_breakpoint "func8b" -locs 3
 
 #
 # func1 is a static inlined function.  The result should be that no
@@ -314,8 +310,7 @@ with_test_prefix "check alignment" {
 	continue
     }
 
-    gdb_test "break func4b" \
-	"Breakpoint.*at.*func4b.*\\(2 locations\\)"
+    gdb_breakpoint "func4b" -locs 2
 
     set expected_line_length -1
     gdb_test_multiple "info break \$bpnum" "xxxx" {
diff --git a/gdb/testsuite/gdb.python/py-bp-locations.exp b/gdb/testsuite/gdb.python/py-bp-locations.exp
index 4892947ca55..a2bff8a655e 100644
--- a/gdb/testsuite/gdb.python/py-bp-locations.exp
+++ b/gdb/testsuite/gdb.python/py-bp-locations.exp
@@ -56,7 +56,7 @@ proc build_bpl_regexp { args } {
 }
 
 # Set breakpoint with 2 locations.
-gdb_breakpoint "add"
+gdb_breakpoint "add" -locs 2
 
 set expected_line_a [gdb_get_line_number "a + b"]
 set expected_line_b [gdb_get_line_number "c + d"]
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index a438a101fc9..bcaf061a8ce 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -672,6 +672,19 @@ proc gdb_starti_cmd { {inferior_args {}} } {
 #
 # If there is an additional argument it is a list of options; the supported
 # options are allow-pending, temporary, message, no-message and qualified.
+# For multiple breakpoint locations additional options are used. These
+# are -locspec, -locs and -extra:
+# -locspec specifies a regex for the location spec output of the break command.
+#          This is only used when multiple locations matching is enabled by
+#          the -locs option. It is useful when a very specific breakpoint
+#          output is expected. For example, "func if a == 0" and the caller
+#          wants to match "func" in the breakpoint command output. When
+#          not set the content of LINESPEC is matched, regardless of -locs.
+# -locs specifies a regex for the number of locations that are printed by the
+#	break command. This also enforces that a single location match is
+#       treated as an error.
+# -extra allows specifying a regex for extra matches that need to appear in
+#	 the output.
 #
 # The result is 1 for success, 0 for failure.
 #
@@ -685,16 +698,27 @@ proc gdb_breakpoint { linespec args } {
     global gdb_prompt
     global decimal
 
+    parse_some_args {
+	{locspec "\[^\r\n\]*"}
+	{locs "\[0-9\]+"}
+	{extra "<nomatch>"}
+	{inferior ""}
+    }
+
+    if { $locspec eq "\[^\r\n\]*" && $locs ne "\[0-9\]+"} {
+	set locspec [string_to_regexp $linespec]
+    }
+
     set pending_response n
     if {[lsearch -exact $args allow-pending] != -1} {
 	set pending_response y
     }
 
     set break_command "break"
-    set break_message "Breakpoint"
+    set break_message "Breakpoint $decimal"
     if {[lsearch -exact $args temporary] != -1} {
 	set break_command "tbreak"
-	set break_message "Temporary breakpoint"
+	set break_message "Temporary breakpoint $decimal"
     }
 
     if {[lsearch -exact $args qualified] != -1} {
@@ -712,36 +736,91 @@ proc gdb_breakpoint { linespec args } {
 	set print_pass 1
     }
 
+    # Counters for single and multiple locations
+    set multiple_locs 0
+    set single_loc 0
+    set extra_matches 0
+
     set test_name "gdb_breakpoint: set breakpoint at $linespec"
-    # The first two regexps are what we get with -g, the third is without -g.
+
+    # Commonly used pattern.
+    set fill "\[^\r\n]"
+
+    # The extra regex is setup to not match unless the caller specifies
+    # an extra match.
     gdb_test_multiple "$break_command $linespec" $test_name {
-	-re "$break_message \[0-9\]* at .*: file .*, line $decimal.\r\n$gdb_prompt $" {}
-	-re "$break_message \[0-9\]*: file .*, line $decimal.\r\n$gdb_prompt $" {}
-	-re "$break_message \[0-9\]* at .*$gdb_prompt $" {}
-	-re "$break_message \[0-9\]* \\(.*\\) pending.*$gdb_prompt $" {
-		if {$pending_response == "n"} {
-			if { $print_fail } {
-				fail $gdb_test_name
-			}
-			return 0
+	-re "$extra" {
+	    incr extra_matches
+	    exp_continue
+	}
+	-re "Note: breakpoint$fill+" {
+	    exp_continue
+	}
+	-re -wrap "$break_message at $fill+: file $fill+, line $decimal\\." {
+	    incr single_loc
+	}
+	-re -wrap "$break_message: file .*, line $decimal\\." {
+	    incr single_loc
+	}
+	-re -wrap "$break_message at $::hex$fill*$locspec$fill*\\($locs locations\\)$fill+" {
+	    incr multiple_locs
+	}
+	-re -wrap "$break_message at $fill+\." {
+	    incr single_loc
+	}
+	-re -wrap "$break_message \\(.*\\) pending$fill+" {
+	    if {$pending_response == "n"} {
+		if { $print_fail } {
+		    fail $gdb_test_name
 		}
+		return 0
+	    }
 	}
-	-re "Make breakpoint pending.*y or \\\[n\\\]. $" { 
-		send_gdb "$pending_response\n"
-		exp_continue
+	-re "Make breakpoint pending.*y or \\\[n\\\]. $" {
+	    send_gdb "$pending_response\n"
+	    exp_continue
 	}
-	-re "$gdb_prompt $" {
+	-re -wrap "" {
 	    if { $print_fail } {
 		fail $test_name
 	    }
 	    return 0
 	}
     }
+
+    # If multiple locations where requested, assert we didn't
+    # see a single location match.
+    if { $locs ne "\[0-9\]+"
+	 && $locs ne 1
+	 && $single_loc != 0 } {
+	if { $print_fail } {
+	    fail $test_name
+	}
+	return 0
+    }
+
+    # Special case to enforce single location matches only. If -LOCS is set to
+    # 1 fail if we get multi location matches.
+    if { $locs eq 1 && $multiple_locs != 0 } {
+	if { $print_fail } {
+	    fail $test_name
+	}
+	return 0
+    }
+
+    # If extra regex is specified, see that it was actually matched.
+    if { $extra ne "<nomatch>" && $extra_matches == 0 } {
+	if { $print_fail } {
+	    fail $test_name
+	}
+	return 0
+    }
+
     if { $print_pass } {
 	pass $test_name
     }
     return 1
-}    
+}
 
 # Set breakpoint at function and run gdb until it breaks there.
 # Since this is the only breakpoint that will be set, if it stops
-- 
2.34.1

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de
Managing Directors: Sean Fennelly, Jeffrey Schneiderman, Tiffany Doon Silva
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v7 2/2] gdb, breakpoint: output multiple bp locations
  2024-10-29 11:33 [PATCH v7 0/2] gdb: setting BP with multiple locations only displays one location Klaus Gerlicher
  2024-10-29 11:33 ` [PATCH v7 1/2] gdb: extend gdb_breakpoint for multiple locations Klaus Gerlicher
@ 2024-10-29 11:33 ` Klaus Gerlicher
  2024-10-29 13:10   ` Eli Zaretskii
  1 sibling, 1 reply; 8+ messages in thread
From: Klaus Gerlicher @ 2024-10-29 11:33 UTC (permalink / raw)
  To: gdb-patches, aburgess, blarsen, eliz

From: "Gerlicher, Klaus" <klaus.gerlicher@intel.com>

When setting a breakpoint that resolves to multiple locations
only the address of the first location is printed but multiple
locations are indicated.

See this example:

01 template <typename T>
02 T
03 f (T t)
04 {
05   return t;
06 }
07
08 int
09 main (void)
10 {
11   return f<int> (1) + f<float> (1.0f) + f<char> (1)
12	    + f<short> (1) + f<bool> (1);
13 }

Setting a breakpoint on line 5 will yield 5 locations:

(gdb) b 5
Breakpoint 1 at 0x11cf: main.cpp:5. (5 locations)

Even though this indicates multiple locations, it only shows
the first one. A better way would be:

Set how many locations to be printed, then...
(gdb) set breakpoint max-breakpoint-locations-printed 4

... set breakpoint.

(gdb) b 5
Breakpoint 1 for main.cpp:5 at 5 locations:
    Location 1 at 0x11cf in function f<int>(int) in file main.cpp, line 5.
    Location 2 at 0x11e1 in function f<float>(float) in file main.cpp, line 5.
    Location 3 at 0x11f5 in function f<char>(char) in file main.cpp, line 5.
    Location 4 at 0x1209 in function f<short>(short) in file main.cpp, line 5.
1 additional location not printed.

Make the number of breakpoint locations printed configurable. Introduce
the "set breakpoint max-breakpoint-locations-printed" command.

Convert tests that use gdb_test "break" to using gdb_breakpoint because
previously the "break" output was parseable with a single regex. Now that
it has become multi-line, tests that were previously creating multiple
locations unknowingly need to be fixed to use the right regex which is
simpler (and more properly) done by using the gdb_breakpoint. gdb_breakpoint
knows which regex to use for any case.

This also adds two more options to gdb_breakpoint, -add_locs and -inferior:

  -add_locs is used for testing the additional print when there are more
            locations then allowed to be printed with the "set
            max-breakpoint-locations-printed" command.
  -inferior is used to match "on inferior X" output when multiple locations
            are on different inferiors.
---
 gdb/NEWS                                      |   4 +
 gdb/breakpoint.c                              | 135 ++++++++++++++----
 gdb/doc/gdb.texinfo                           |  45 +++++-
 gdb/testsuite/gdb.base/ctxobj.exp             |   4 +-
 .../run-control-while-bg-execution.exp        |   2 +-
 gdb/testsuite/gdb.cp/ovldbreak.exp            |   6 +-
 gdb/testsuite/gdb.linespec/cpcompletion.exp   |   2 +
 gdb/testsuite/gdb.linespec/linespec.exp       |   2 +-
 gdb/testsuite/gdb.linespec/multiple-locs.cc   |  41 ++++++
 gdb/testsuite/gdb.linespec/multiple-locs.exp  |  57 ++++++++
 .../mi-breakpoint-multiple-locations.exp      |   4 +-
 .../gdb.mi/user-selected-context-sync.exp     |  16 +--
 .../gdb.multi/inferior-specific-bp.exp        |   2 +-
 .../gdb.multi/multi-target-continue.exp       |   3 +-
 .../gdb.multi/multi-target-ping-pong-next.exp |   6 +-
 gdb/testsuite/gdb.python/py-breakpoint.exp    |   3 +-
 gdb/testsuite/lib/completion-support.exp      |   3 +
 gdb/testsuite/lib/gdb.exp                     |  34 ++++-
 18 files changed, 308 insertions(+), 61 deletions(-)
 create mode 100644 gdb/testsuite/gdb.linespec/multiple-locs.cc
 create mode 100644 gdb/testsuite/gdb.linespec/multiple-locs.exp

diff --git a/gdb/NEWS b/gdb/NEWS
index 42b8a88fd8a..bae2fa9b93f 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -3,6 +3,10 @@
 
 *** Changes since GDB 15
 
+* Printing multiple breakpoint locations when setting a breakpoint that is
+  instantiated for multiple locations now prints all locations limited by
+  "set breakpoint max-breakpoint-location-printed <count>".
+
 * Debugging support for Intel MPX has been removed.  This includes the
   removal of
   ** MPX register support
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index b7e4f5d0a45..7845d696de9 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -170,6 +170,19 @@ static bool bl_address_is_meaningful (bp_location *loc);
 
 static int find_loc_num_by_location (const bp_location *loc);
 
+/* Maximum number of locations printed when setting a breakpoint.  Controlled
+   by "set breakpoint max-breakpoint-locations-printed <number>".  */
+
+static unsigned int breakpoint_show_max_locations = 10;
+static void
+show_max_breakpoint_location_printed (struct ui_file *file, int from_tty,
+		    struct cmd_list_element *c, const char *value)
+{
+  gdb_printf (file,
+	      _("Number of breakpoint location printed is %s.\n"),
+	      value);
+}
+
 /* update_global_location_list's modes of operation wrt to whether to
    insert locations now.  */
 enum ugll_insert_mode
@@ -11813,39 +11826,93 @@ code_breakpoint::say_where () const
     }
   else
     {
-      const bp_location &bl = this->first_loc ();
-      if (opts.addressprint || bl.symtab == nullptr)
-	gdb_printf (" at %ps",
-		    styled_string (address_style.style (),
-				   paddress (bl.gdbarch,
-					     bl.address)));
-      if (bl.symtab != NULL)
-	{
-	  /* If there is a single location, we can print the location
-	     more nicely.  */
-	  if (!this->has_multiple_locations ())
+      if (this->has_multiple_locations ())
+	{
+	  int n = std::distance (m_locations.begin (), m_locations.end ());
+
+	  gdb_printf (" for %s at %d locations:\n", locspec->to_string (), n);
+	  int loc_idx = 0;
+	  for (const bp_location &bl : m_locations)
+	    {
+	      gdb_printf ("    Location %d", loc_idx + 1);
+	      if (opts.addressprint || bl.symtab == nullptr)
+		gdb_printf (" at %ps", styled_string (address_style.style (),
+						      paddress (bl.gdbarch,
+								bl.address)));
+
+	      if (bl.symtab != nullptr)
+		{
+		  const struct symbol *sym = bl.symbol;
+		  if (sym != nullptr)
+		    {
+		      gdb_stdout->wrap_here (6);
+		      gdb_printf (" in function %ps",
+				  styled_string (function_name_style.style (),
+						 sym->print_name ()));
+		    }
+
+		  const char *filename
+		    = symtab_to_filename_for_display (bl.symtab);
+		  gdb_stdout->wrap_here (6);
+		  gdb_printf (": file %ps, line %ps",
+			      styled_string (file_name_style.style (),
+					     filename),
+			      styled_string (line_number_style.style (),
+					     pulongest (bl.line_number)));
+		}
+
+	      if (all_inferiors ().size () > 1)
+		{
+		  for (const auto &inf : all_inferiors ())
+		    if (inf->pspace == bl.pspace)
+		      gdb_printf (" in inferior %d", inf->num);
+		}
+	      else if (bl.owner->inferior != -1)
+		gdb_printf (" in inferior %d", bl.owner->inferior);
+
+	      loc_idx++;
+
+	      gdb_printf (".");
+	      if (loc_idx < n)
+		gdb_printf ("\n");
+
+	      /* The user (or default) has selected a maximum number of
+		 locations to be printed.  */
+	      if (loc_idx >= breakpoint_show_max_locations)
+		break;
+	    }
+
+	  /* We printed less locations than there are present, let the user
+	     know how many more there are.  */
+	  if (loc_idx < n)
 	    {
-	      const char *filename
-		= symtab_to_filename_for_display (bl.symtab);
-	      gdb_printf (": file %ps, line %ps.",
-			  styled_string (file_name_style.style (),
-					 filename),
-			  styled_string (line_number_style.style (),
-					 pulongest (bl.line_number)));
+	      int omitted_locs = n - loc_idx;
+	      if (omitted_locs == 1)
+		gdb_printf (_("%u additional location not printed."),
+			    omitted_locs);
+	      else
+		gdb_printf (_("%u additional locations not printed."),
+			    omitted_locs);
 	    }
-	  else
-	    /* This is not ideal, but each location may have a
-	       different file name, and this at least reflects the
-	       real situation somewhat.  */
-	    gdb_printf (": %s.", locspec->to_string ());
 	}
-
-      if (this->has_multiple_locations ())
+      else
 	{
-	  int n = std::distance (m_locations.begin (), m_locations.end ());
-	  gdb_printf (" (%d locations)", n);
+	  const bp_location &bl = this->first_loc ();
+	  if (opts.addressprint || bl.symtab == nullptr)
+	    gdb_printf (" at %ps",
+			styled_string (address_style.style (),
+				       paddress (bl.gdbarch, bl.address)));
+	  if (bl.symtab != nullptr)
+	    {
+		const char *filename
+		  = symtab_to_filename_for_display (bl.symtab);
+		gdb_printf (": file %ps, line %ps.",
+			    styled_string (file_name_style.style (), filename),
+			    styled_string (line_number_style.style (),
+					   pulongest (bl.line_number)));
+	    }
 	}
-    }
+      }
 }
 
 /* See breakpoint.h.  */
@@ -15254,6 +15321,18 @@ Usage: agent-printf \"format string\", ARG1, ARG2, ARG3, ..., ARGN\n\
 This supports most C printf format specifications, like %s, %d, etc.\n\
 This is useful for formatted output in user-defined commands."));
 
+  add_setshow_uinteger_cmd ("max-breakpoint-locations-printed",
+			    class_breakpoint,
+			    &breakpoint_show_max_locations, _("\
+Set number of locations printed when setting a breakpoint."), _("\
+Show number of locations printed when setting a breakpoint."), _("\
+Use this to choose how many number of locations are printed\n\
+when setting a breakpoint.\n\
+A value of \"unlimited\", or zero, means there's no limit."),
+			    nullptr, /* set_cmd.  */
+			    show_max_breakpoint_location_printed,
+			    &breakpoint_set_cmdlist, &breakpoint_show_cmdlist);
+
   automatic_hardware_breakpoints = true;
 
   gdb::observers::about_to_proceed.attach (breakpoint_about_to_proceed,
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index eb2aff974bb..a03ceccd5fa 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -4518,16 +4518,47 @@ $1 = 1
 
 A breakpoint may be mapped to multiple code locations for example with
 inlined functions, Ada generics, C@t{++} templates or overloaded function names.
-@value{GDBN} then indicates the number of code locations in the breakpoint
+@value{GDBN} then lists the number of code locations in the breakpoint
 command output:
 @smallexample
 (gdb) b some_func
-Breakpoint 2 at 0x1179: some_func. (3 locations)
+Breakpoint 2 for some_func at 3 locations:
+    Location 1 at 0x118e in function some_func in file somefunc.cc, line 23.
+    Location 2 at 0x11ee in function some_func in file somefunc.cc, line 38.
+    Location 3 at 0x12fe in function some_func in file someother.cc, line 58.
 (gdb) p $bpnum
 $2 = 2
 (gdb)
 @end smallexample
 
+@cindex @code{break}, how many locations are displayed
+By default, @value{GDBN} prints up to ten breakpoint locations, you can change
+this using @code{set breakpoint max-breakpoint-locations-printed}:
+
+@smallexample
+(gdb) set breakpoint max-breakpoint-locations-printed 2
+(gdb) b some_func
+Breakpoint 2 for some_func at 3 locations:
+    Location 1 at 0x118e in function some_func in file somefunc.cc, line 23.
+    Location 2 at 0x11ee in function some_func in file somefunc.cc, line 38.
+1 additional location not printed.
+(gdb)
+@end smallexample
+
+@table @code
+@kindex set breakpoint max-breakpoint-locations-printed
+@item set breakpoint max-breakpoint-locations-printed @var{count}
+@itemx set breakpoint max-breakpoint-locations-printed unlimited
+Make the @code{break} command display up to @var{count} locations.
+Setting @var{count} to @code{unlimited} or 0 means there's no limit.
+
+@kindex show breakpoint max-breakpoint-locations-printed
+@item show breakpoint max-breakpoint-locations-printed
+Display the number of locations that @code{break} will print.  If the number
+of locations is greater than the limit, the additional number of locations
+will be listed.
+@end table
+
 @vindex $_hit_bpnum@r{, convenience variable}
 @vindex $_hit_locno@r{, convenience variable}
 When your program stops on a breakpoint, the convenience variables
@@ -4637,7 +4668,10 @@ warning: failed to validate condition at location 0x11ce, disabling:
   No symbol "a" in current context.
 warning: failed to validate condition at location 0x11b6, disabling:
   No symbol "a" in current context.
-Breakpoint 1 at 0x11b6: func. (3 locations)
+Breakpoint 1 for func at 3 locations:
+    Location 1 at 0x11ce in function func in file somefunc.cc, line 23.
+    Location 2 at 0x11b6 in function func in file somefunc.cc, line 38.
+    Location 3 at 0x12fe in function func in file someother.cc, line 58.
 @end smallexample
 
 Locations that are disabled because of the condition are denoted by an
@@ -4681,7 +4715,10 @@ warning: failed to validate condition at location 2, disabling:
   No symbol "foo" in current context.
 warning: failed to validate condition at location 3, disabling:
   No symbol "foo" in current context.
-Breakpoint 1 at 0x1158: test.c:18. (3 locations)
+Breakpoint 1 for func at 3 locations:
+    Location 1 at 0x1158 in function func in file test.c, line 18.
+    Location 2 at 0x11b6 in function func in file test.c, line 28.
+    Location 3 at 0x12fe in function func in file test.c, line 58.
 @end smallexample
 
 This causes all the present locations where the breakpoint would
diff --git a/gdb/testsuite/gdb.base/ctxobj.exp b/gdb/testsuite/gdb.base/ctxobj.exp
index d1137189108..e73b29fcf3a 100644
--- a/gdb/testsuite/gdb.base/ctxobj.exp
+++ b/gdb/testsuite/gdb.base/ctxobj.exp
@@ -61,9 +61,7 @@ if ![runto_main] {
 }
 
 set bp_location [gdb_get_line_number "STOP" "ctxobj-f.c"]
-gdb_test "break ctxobj-f.c:$bp_location" \
-         "Breakpoint \[0-9\]+ at 0x\[0-9a-fA-F\]+: .*" \
-         "break in get_version functions"
+gdb_breakpoint "ctxobj-f.c:$bp_location"
 
 global expect_out
 set test "continue to get_version_1"
diff --git a/gdb/testsuite/gdb.base/run-control-while-bg-execution.exp b/gdb/testsuite/gdb.base/run-control-while-bg-execution.exp
index 380047ae854..fd395f10387 100644
--- a/gdb/testsuite/gdb.base/run-control-while-bg-execution.exp
+++ b/gdb/testsuite/gdb.base/run-control-while-bg-execution.exp
@@ -90,7 +90,7 @@ proc do_test { action1 action2 } {
     if { $action2 == "start" } {
 	gdb_test "start" "Temporary breakpoint $::decimal\(?:\.$::decimal\)?, main .*"
     } elseif { $action2 == "run" } {
-	gdb_test "break main" "Breakpoint $::decimal at $::hex.*"
+	gdb_breakpoint "main"
 	gdb_test "run" "Breakpoint $::decimal\(?:\.$::decimal\)?, main .*"
     } elseif { $action2 == "attach" } {
 	set test_spawn_id [spawn_wait_for_attach $::binfile]
diff --git a/gdb/testsuite/gdb.cp/ovldbreak.exp b/gdb/testsuite/gdb.cp/ovldbreak.exp
index 84efb37b8db..1f5383e92e9 100644
--- a/gdb/testsuite/gdb.cp/ovldbreak.exp
+++ b/gdb/testsuite/gdb.cp/ovldbreak.exp
@@ -332,6 +332,10 @@ gdb_test "info breakpoints" "No breakpoints, watchpoints, tracepoints, or catchp
 # Test choice "all".
 # This is copy-and-paste from set_bp_overloaded.
 
+gdb_test_no_output "set breakpoint max-breakpoint-locations-printed 0"
+
+set breakmsg [gdb_multi_loc_regex "Breakpoint $decimal" 12]
+
 incr bpnum
 send_gdb "break foo::overload1arg\n" 
 gdb_expect {
@@ -340,7 +344,7 @@ gdb_expect {
         # Choose all.
         send_gdb "1\n"
         gdb_expect {
-	    -re "Breakpoint $bpnum at $hex: foo::overload1arg. .12 locations.\r\n.*$gdb_prompt $" {
+	    -re "$breakmsg$gdb_prompt $" {
                 pass "set bp on overload1arg all"
             }
             -re ".*$gdb_prompt $" {
diff --git a/gdb/testsuite/gdb.linespec/cpcompletion.exp b/gdb/testsuite/gdb.linespec/cpcompletion.exp
index 09bd9a25d77..49d59e79918 100644
--- a/gdb/testsuite/gdb.linespec/cpcompletion.exp
+++ b/gdb/testsuite/gdb.linespec/cpcompletion.exp
@@ -1397,4 +1397,6 @@ proc test_driver {} {
     if-expression
 }
 
+gdb_test_no_output "set breakpoint max-breakpoint-locations-printed 0"
+
 test_driver
diff --git a/gdb/testsuite/gdb.linespec/linespec.exp b/gdb/testsuite/gdb.linespec/linespec.exp
index 6398309f7e4..e5a0e205e9e 100644
--- a/gdb/testsuite/gdb.linespec/linespec.exp
+++ b/gdb/testsuite/gdb.linespec/linespec.exp
@@ -69,7 +69,7 @@ if { [is_remote host] } {
 
 		send_gdb "\n"
 		gdb_test "" \
-		    "Breakpoint $decimal at $hex: thefile.cc:twodup\\(\\). \[(\]2 locations\[)\]" \
+		    "[gdb_multi_loc_regex "Breakpoint $decimal" 2]\[^\r\n\]*" \
 		    "set break at unique function name in two source files"
 	    }
 	}
diff --git a/gdb/testsuite/gdb.linespec/multiple-locs.cc b/gdb/testsuite/gdb.linespec/multiple-locs.cc
new file mode 100644
index 00000000000..e7ca889e0fa
--- /dev/null
+++ b/gdb/testsuite/gdb.linespec/multiple-locs.cc
@@ -0,0 +1,41 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2024 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+template <typename T>
+int
+templ1 (T param)
+{
+  return (int) param; /* Break here.  */
+}
+
+template <>
+int
+templ1 (char* param)
+{
+  return  2;
+}
+
+int
+main ()
+{
+  templ1 (1L);
+  templ1 (1.0f);
+  templ1 (1U);
+  templ1 (1UL);
+  templ1 (1ULL);
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.linespec/multiple-locs.exp b/gdb/testsuite/gdb.linespec/multiple-locs.exp
new file mode 100644
index 00000000000..d829e93b1ed
--- /dev/null
+++ b/gdb/testsuite/gdb.linespec/multiple-locs.exp
@@ -0,0 +1,57 @@
+# Copyright 2024 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Tests of printing of multiple breakpoint locations when setting a breakpoint.
+
+standard_testfile .cc
+
+require allow_cplus_tests
+
+if {[prepare_for_testing "failed to prepare" $testfile $srcfile]} {
+    return -1
+}
+
+gdb_test_no_output "set confirm off"
+
+gdb_test_no_output "set multiple-symbols all"
+
+set bp_location [gdb_get_line_number "Break here." $srcfile]
+gdb_breakpoint "$bp_location" -locs 5
+
+delete_breakpoints
+
+gdb_test_no_output "set breakpoint max-breakpoint-locations-printed 2"
+
+set bp_location [gdb_get_line_number "Break here." $srcfile]
+
+gdb_breakpoint $bp_location -locs 5 -add_locs 3
+
+delete_breakpoints
+
+set bp_location [gdb_get_line_number "Break here." $srcfile]
+
+gdb_breakpoint "$bp_location inferior 1" -locs 5 -locspec "$bp_location" \
+    -add_locs 3 -inferior 1
+
+delete_breakpoints
+
+# Now add the 2nd inferior.
+gdb_test "add-inferior" "Added inferior 2.*" "add inferior 2"
+gdb_test "inferior 2" "Switching to inferior 2.*" "switch to inferior 2"
+gdb_file_cmd $binfile
+
+gdb_test_no_output "set breakpoint max-breakpoint-locations-printed 20"
+
+gdb_breakpoint "$bp_location" -locs 10 -inferior "\[12\]"
diff --git a/gdb/testsuite/gdb.mi/mi-breakpoint-multiple-locations.exp b/gdb/testsuite/gdb.mi/mi-breakpoint-multiple-locations.exp
index 93ddad84444..a02fe1f7cce 100644
--- a/gdb/testsuite/gdb.mi/mi-breakpoint-multiple-locations.exp
+++ b/gdb/testsuite/gdb.mi/mi-breakpoint-multiple-locations.exp
@@ -69,7 +69,9 @@ proc do_test { mi_version use_fix_flag expect_fixed_output } {
 	    set pattern [make_breakpoints_pattern $expect_fixed_output 2 y y]
 	    mi_gdb_test "break a_very_unique_name" \
 		[multi_line "&\"break a_very_unique_name\\\\n\"" \
-			    "~\"Breakpoint ${decimal} at.*\\(2 locations\\)\\\\n\"" \
+			    "~\"Breakpoint ${decimal} for.*at.*2 locations:\\\\n\"" \
+			    "~\"    Location ${decimal}.*\\\\n\"" \
+			    "~\"    Location ${decimal}.*\\\\n\"" \
 			    "=breakpoint-created,${pattern}" \
 			    "\\^done" ] \
 		"break a_very_unique_name"
diff --git a/gdb/testsuite/gdb.mi/user-selected-context-sync.exp b/gdb/testsuite/gdb.mi/user-selected-context-sync.exp
index e168a5eee45..b8d640d010a 100644
--- a/gdb/testsuite/gdb.mi/user-selected-context-sync.exp
+++ b/gdb/testsuite/gdb.mi/user-selected-context-sync.exp
@@ -293,9 +293,7 @@ proc test_continue_to_start { mode inf } {
 	with_spawn_id $gdb_main_spawn_id {
 	    # Continue to the point where we know for sure the threads are
 	    # started.
-	    gdb_test "tbreak $srcfile:$main_break_line" \
-		"Temporary breakpoint ${any}" \
-		"set breakpoint in main"
+	    gdb_breakpoint "$srcfile:$main_break_line" {temporary}
 
 	    gdb_continue_to_breakpoint "main breakpoint"
 
@@ -321,9 +319,7 @@ proc test_continue_to_start { mode inf } {
 		foreach thread { 2 3 } {
 		    gdb_test "thread $inf.$thread" ".*" "select child thread $inf.$thread"
 
-		    gdb_test "tbreak $srcfile:$thread_loop_line" \
-			"Temporary breakpoint ${any}" \
-			"set breakpoint for thread $inf.$thread"
+		    gdb_breakpoint "$srcfile:$thread_loop_line" {temporary}
 
 		    gdb_continue_to_breakpoint "continue thread $inf.$thread to infinite loop breakpoint"
 
@@ -347,12 +343,8 @@ proc test_continue_to_start { mode inf } {
 		# Put a thread-specific breakpoint for thread 2 of the current
 		# inferior.  We don't put a breakpoint for thread 3, since we
 		# want to let it run.
-		set test "set thread-specific breakpoint, thread $inf.2"
-		gdb_test_multiple "tbreak $srcfile:$thread_loop_line thread $inf.2" $test {
-		    -re "Temporary breakpoint ${any}\r\n$gdb_prompt " {
-			pass $test
-		    }
-		}
+		gdb_breakpoint "$srcfile:$thread_loop_line thread $inf.2" \
+		    {temporary}
 
 		# Confirm the stop of thread $inf.2.
 		set test "thread $inf.2 stops CLI"
diff --git a/gdb/testsuite/gdb.multi/inferior-specific-bp.exp b/gdb/testsuite/gdb.multi/inferior-specific-bp.exp
index 67069e1da4d..3c37c068b71 100644
--- a/gdb/testsuite/gdb.multi/inferior-specific-bp.exp
+++ b/gdb/testsuite/gdb.multi/inferior-specific-bp.exp
@@ -172,7 +172,7 @@ proc check_info_breakpoints { testname bp_number expected_loc_count } {
 # Create an inferior-specific breakpoint.  Use gdb_test instead of
 # gdb_breakpoint here as we want to check the breakpoint was placed in
 # multiple locations.
-gdb_breakpoint "foo inferior 1" -locs 2 -locspec "foo"
+gdb_breakpoint "foo inferior 1" -locs 2 -locspec "foo" -inferior 1
 set bp_number [get_integer_valueof "\$bpnum" "INVALID" \
 		  "get b/p number for inferior specific breakpoint"]
 
diff --git a/gdb/testsuite/gdb.multi/multi-target-continue.exp b/gdb/testsuite/gdb.multi/multi-target-continue.exp
index d4b2fc28133..2e8dcae13bf 100644
--- a/gdb/testsuite/gdb.multi/multi-target-continue.exp
+++ b/gdb/testsuite/gdb.multi/multi-target-continue.exp
@@ -29,8 +29,7 @@ proc test_continue {non-stop} {
     }
 
     proc set_break {inf} {
-	gdb_test "break function${inf} thread ${inf}.1" \
-	    "Breakpoint ${::decimal} at ${::hex}: file .*, line ${::decimal}\\."
+	gdb_breakpoint "function${inf} thread ${inf}.1"
     }
 
     # Select inferior INF, and then run to a breakpoint on inferior
diff --git a/gdb/testsuite/gdb.multi/multi-target-ping-pong-next.exp b/gdb/testsuite/gdb.multi/multi-target-ping-pong-next.exp
index 36f9d24a917..fe2683e9edb 100644
--- a/gdb/testsuite/gdb.multi/multi-target-ping-pong-next.exp
+++ b/gdb/testsuite/gdb.multi/multi-target-ping-pong-next.exp
@@ -51,13 +51,11 @@ proc test_ping_pong_next {} {
 
     gdb_test "thread 1.1" "Switching to thread 1.1 .*"
 
-    gdb_test "break $srcfile:$line1 thread 1.1" \
-	"Breakpoint .*$srcfile, line $line1\\."
+    gdb_breakpoint "$srcfile:$line1 thread 1.1"
 
     gdb_test "continue" "hit Breakpoint .*"
 
-    gdb_test "break $srcfile:$line2 thread 2.1" \
-	"Breakpoint .*$srcfile, line $line2\\."
+    gdb_breakpoint "$srcfile:$line2 thread 2.1"
 
     # Now block inferior 1 and issue "next".  We should stop at the
     # breakpoint for inferior 2, given schedlock off.
diff --git a/gdb/testsuite/gdb.python/py-breakpoint.exp b/gdb/testsuite/gdb.python/py-breakpoint.exp
index 934690db2a1..e2f55f4e98e 100644
--- a/gdb/testsuite/gdb.python/py-breakpoint.exp
+++ b/gdb/testsuite/gdb.python/py-breakpoint.exp
@@ -765,7 +765,8 @@ proc_with_prefix test_bkpt_qualified {} {
     clean_restart ${testfile}
 
     set one_location_re "Breakpoint $decimal at $hex:.*line $decimal."
-    set two_location_re "Breakpoint $decimal at $hex:.*2 locations."
+    set two_location_re \
+	"[gdb_multi_loc_regex "Breakpoint $decimal" 2]\[^\r\n\]*"
 
     if {![runto_main]} {
 	return 0
diff --git a/gdb/testsuite/lib/completion-support.exp b/gdb/testsuite/lib/completion-support.exp
index 5f0f6199894..e6f1c7b1f9f 100644
--- a/gdb/testsuite/lib/completion-support.exp
+++ b/gdb/testsuite/lib/completion-support.exp
@@ -417,6 +417,9 @@ proc completion::_create_bp {break_command} {
 	-re "\\\(\($decimal\) locations\\\)\r\n$gdb_prompt $" {
 	    set found_locations "$expect_out(1,string)"
 	}
+	-re "[gdb_multi_loc_regex "Breakpoint $decimal" $decimal]$gdb_prompt $" {
+	    set found_locations 1
+	}
 	-re "Breakpoint $decimal at $hex: file .*, line .*$gdb_prompt $" {
 	    set found_locations 1
 	}
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index bcaf061a8ce..f72b42beeb8 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -668,12 +668,25 @@ proc gdb_starti_cmd { {inferior_args {}} } {
     return -1
 }
 
+# Construct a breakpoint regex for multiple bp locations given a breakpoint
+# command BREAK_MESSAGE and a regex of expected locations LOCS.
+# This is useful for constructing multiple location regex where the
+# gdb_breakpoint proc cannot be used (for instance in completion tests).
+# It is also used in proc gdb_breakpoint.
+
+proc gdb_multi_loc_regex { break_message locs {locspec ""} { inferior ""}} {
+    set fill "\[^\r\n]"
+    return [multi_line \
+	"$break_message for $fill*$locspec at $locs locations:" \
+	"(?:    Location $::decimal at $::hex\[^\r\n\]*$inferior\.\\r\n)+" ]
+}
+
 # Set a breakpoint using LINESPEC.
 #
 # If there is an additional argument it is a list of options; the supported
 # options are allow-pending, temporary, message, no-message and qualified.
 # For multiple breakpoint locations additional options are used. These
-# are -locspec, -locs and -extra:
+# are -locspec, -locs, -extra, -add_locs and -inferior:
 # -locspec specifies a regex for the location spec output of the break command.
 #          This is only used when multiple locations matching is enabled by
 #          the -locs option. It is useful when a very specific breakpoint
@@ -685,6 +698,8 @@ proc gdb_starti_cmd { {inferior_args {}} } {
 #       treated as an error.
 # -extra allows specifying a regex for extra matches that need to appear in
 #	 the output.
+# -add_locs specifies a regex for additional locations printed.
+# -inferior specifies a regex for "in inferior" in the break command output.
 #
 # The result is 1 for success, 0 for failure.
 #
@@ -701,6 +716,7 @@ proc gdb_breakpoint { linespec args } {
     parse_some_args {
 	{locspec "\[^\r\n\]*"}
 	{locs "\[0-9\]+"}
+	{add_locs ""}
 	{extra "<nomatch>"}
 	{inferior ""}
     }
@@ -746,6 +762,20 @@ proc gdb_breakpoint { linespec args } {
     # Commonly used pattern.
     set fill "\[^\r\n]"
 
+    # If requested, expect "in inferior" in the locations output.
+    if { $inferior != ""} {
+	set inferior "in inferior $inferior"
+    }
+
+    set multiloc_msg \
+	[gdb_multi_loc_regex $break_message $locs $locspec $inferior]
+
+    set additional_locs ""
+    if { $add_locs != "" } {
+	set additional_locs \
+	    "$add_locs additional location\[s\]* not printed\.\r\n"
+    }
+
     # The extra regex is setup to not match unless the caller specifies
     # an extra match.
     gdb_test_multiple "$break_command $linespec" $test_name {
@@ -762,7 +792,7 @@ proc gdb_breakpoint { linespec args } {
 	-re -wrap "$break_message: file .*, line $decimal\\." {
 	    incr single_loc
 	}
-	-re -wrap "$break_message at $::hex$fill*$locspec$fill*\\($locs locations\\)$fill+" {
+	-re "$multiloc_msg$additional_locs$gdb_prompt $" {
 	    incr multiple_locs
 	}
 	-re -wrap "$break_message at $fill+\." {
-- 
2.34.1

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de
Managing Directors: Sean Fennelly, Jeffrey Schneiderman, Tiffany Doon Silva
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v7 2/2] gdb, breakpoint: output multiple bp locations
  2024-10-29 11:33 ` [PATCH v7 2/2] gdb, breakpoint: output multiple bp locations Klaus Gerlicher
@ 2024-10-29 13:10   ` Eli Zaretskii
  2024-10-29 15:57     ` Gerlicher, Klaus
  0 siblings, 1 reply; 8+ messages in thread
From: Eli Zaretskii @ 2024-10-29 13:10 UTC (permalink / raw)
  To: Klaus Gerlicher; +Cc: gdb-patches, aburgess, blarsen

> From: Klaus Gerlicher <klaus.gerlicher@intel.com>
> Date: Tue, 29 Oct 2024 11:33:43 +0000
> 
>  gdb/NEWS                                      |   4 +
>  gdb/breakpoint.c                              | 135 ++++++++++++++----
>  gdb/doc/gdb.texinfo                           |  45 +++++-
>  gdb/testsuite/gdb.base/ctxobj.exp             |   4 +-
>  .../run-control-while-bg-execution.exp        |   2 +-
>  gdb/testsuite/gdb.cp/ovldbreak.exp            |   6 +-
>  gdb/testsuite/gdb.linespec/cpcompletion.exp   |   2 +
>  gdb/testsuite/gdb.linespec/linespec.exp       |   2 +-
>  gdb/testsuite/gdb.linespec/multiple-locs.cc   |  41 ++++++
>  gdb/testsuite/gdb.linespec/multiple-locs.exp  |  57 ++++++++
>  .../mi-breakpoint-multiple-locations.exp      |   4 +-
>  .../gdb.mi/user-selected-context-sync.exp     |  16 +--
>  .../gdb.multi/inferior-specific-bp.exp        |   2 +-
>  .../gdb.multi/multi-target-continue.exp       |   3 +-
>  .../gdb.multi/multi-target-ping-pong-next.exp |   6 +-
>  gdb/testsuite/gdb.python/py-breakpoint.exp    |   3 +-
>  gdb/testsuite/lib/completion-support.exp      |   3 +
>  gdb/testsuite/lib/gdb.exp                     |  34 ++++-
>  18 files changed, 308 insertions(+), 61 deletions(-)
>  create mode 100644 gdb/testsuite/gdb.linespec/multiple-locs.cc
>  create mode 100644 gdb/testsuite/gdb.linespec/multiple-locs.exp

Thanks.

> --- a/gdb/NEWS
> +++ b/gdb/NEWS
> @@ -3,6 +3,10 @@
>  
>  *** Changes since GDB 15
>  
> +* Printing multiple breakpoint locations when setting a breakpoint that is
> +  instantiated for multiple locations now prints all locations limited by
> +  "set breakpoint max-breakpoint-location-printed <count>".
> +
>  * Debugging support for Intel MPX has been removed.  This includes the
>    removal of
>    ** MPX register support

This part is OK.

> +  add_setshow_uinteger_cmd ("max-breakpoint-locations-printed",
> +			    class_breakpoint,
> +			    &breakpoint_show_max_locations, _("\
> +Set number of locations printed when setting a breakpoint."), _("\
> +Show number of locations printed when setting a breakpoint."), _("\
> +Use this to choose how many number of locations are printed\n\
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Either "how many locations" or "the number of locations".

> +@kindex show breakpoint max-breakpoint-locations-printed
> +@item show breakpoint max-breakpoint-locations-printed
> +Display the number of locations that @code{break} will print.  If the number
> +of locations is greater than the limit, the additional number of locations
> +will be listed.
   ^^^^^^^^^^^^^^
I guess "will not be listed"?

The documentation is OK with those nits fixed.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* RE: [PATCH v7 2/2] gdb, breakpoint: output multiple bp locations
  2024-10-29 13:10   ` Eli Zaretskii
@ 2024-10-29 15:57     ` Gerlicher, Klaus
  2024-10-29 16:53       ` Eli Zaretskii
  0 siblings, 1 reply; 8+ messages in thread
From: Gerlicher, Klaus @ 2024-10-29 15:57 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb-patches, aburgess, blarsen

Thanks Eli. Replies inline. I'll wait until I get some feedback from others and will roll fixes into a V8.

Klaus

> -----Original Message-----
> From: Eli Zaretskii <eliz@gnu.org>
> Sent: Tuesday, October 29, 2024 2:10 PM
> To: Gerlicher, Klaus <klaus.gerlicher@intel.com>
> Cc: gdb-patches@sourceware.org; aburgess@redhat.com;
> blarsen@redhat.com
> Subject: Re: [PATCH v7 2/2] gdb, breakpoint: output multiple bp locations
> 
> > From: Klaus Gerlicher <klaus.gerlicher@intel.com>
> > Date: Tue, 29 Oct 2024 11:33:43 +0000
> >
> >  gdb/NEWS                                      |   4 +
> >  gdb/breakpoint.c                              | 135 ++++++++++++++----
> >  gdb/doc/gdb.texinfo                           |  45 +++++-
> >  gdb/testsuite/gdb.base/ctxobj.exp             |   4 +-
> >  .../run-control-while-bg-execution.exp        |   2 +-
> >  gdb/testsuite/gdb.cp/ovldbreak.exp            |   6 +-
> >  gdb/testsuite/gdb.linespec/cpcompletion.exp   |   2 +
> >  gdb/testsuite/gdb.linespec/linespec.exp       |   2 +-
> >  gdb/testsuite/gdb.linespec/multiple-locs.cc   |  41 ++++++
> >  gdb/testsuite/gdb.linespec/multiple-locs.exp  |  57 ++++++++
> >  .../mi-breakpoint-multiple-locations.exp      |   4 +-
> >  .../gdb.mi/user-selected-context-sync.exp     |  16 +--
> >  .../gdb.multi/inferior-specific-bp.exp        |   2 +-
> >  .../gdb.multi/multi-target-continue.exp       |   3 +-
> >  .../gdb.multi/multi-target-ping-pong-next.exp |   6 +-
> >  gdb/testsuite/gdb.python/py-breakpoint.exp    |   3 +-
> >  gdb/testsuite/lib/completion-support.exp      |   3 +
> >  gdb/testsuite/lib/gdb.exp                     |  34 ++++-
> >  18 files changed, 308 insertions(+), 61 deletions(-)
> >  create mode 100644 gdb/testsuite/gdb.linespec/multiple-locs.cc
> >  create mode 100644 gdb/testsuite/gdb.linespec/multiple-locs.exp
> 
> Thanks.
> 
> > --- a/gdb/NEWS
> > +++ b/gdb/NEWS
> > @@ -3,6 +3,10 @@
> >
> >  *** Changes since GDB 15
> >
> > +* Printing multiple breakpoint locations when setting a breakpoint that is
> > +  instantiated for multiple locations now prints all locations limited by
> > +  "set breakpoint max-breakpoint-location-printed <count>".
> > +
> >  * Debugging support for Intel MPX has been removed.  This includes the
> >    removal of
> >    ** MPX register support
> 
> This part is OK.
> 


Thank you.

> > +  add_setshow_uinteger_cmd ("max-breakpoint-locations-printed",
> > +			    class_breakpoint,
> > +			    &breakpoint_show_max_locations, _("\
> > +Set number of locations printed when setting a breakpoint."), _("\
> > +Show number of locations printed when setting a breakpoint."), _("\
> > +Use this to choose how many number of locations are printed\n\
>                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> Either "how many locations" or "the number of locations".
> 

I think I had looked at similar commands and tried to copy something verbatim 
and I failed miserably. Thanks for catching this.

> > +@kindex show breakpoint max-breakpoint-locations-printed
> > +@item show breakpoint max-breakpoint-locations-printed
> > +Display the number of locations that @code{break} will print.  If the
> number
> > +of locations is greater than the limit, the additional number of locations
> > +will be listed.
>    ^^^^^^^^^^^^^^
> I guess "will not be listed"?
> 

What I meant to say is that there will be a line of output that tells the user
how many more locations apart from the listed one there are.

So maybe:

"If the number of locations is greater than the limit, the breakpoint command will 
add a line reporting the number of locations that were not listed due to the limit.

Or maybe you have a better way of phrasing this?

> The documentation is OK with those nits fixed.
> 
> Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de
Managing Directors: Sean Fennelly, Jeffrey Schneiderman, Tiffany Doon Silva
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v7 2/2] gdb, breakpoint: output multiple bp locations
  2024-10-29 15:57     ` Gerlicher, Klaus
@ 2024-10-29 16:53       ` Eli Zaretskii
  2024-11-04 10:03         ` Gerlicher, Klaus
  0 siblings, 1 reply; 8+ messages in thread
From: Eli Zaretskii @ 2024-10-29 16:53 UTC (permalink / raw)
  To: Gerlicher, Klaus; +Cc: gdb-patches, aburgess, blarsen

> From: "Gerlicher, Klaus" <klaus.gerlicher@intel.com>
> CC: "gdb-patches@sourceware.org" <gdb-patches@sourceware.org>,
> 	"aburgess@redhat.com" <aburgess@redhat.com>, "blarsen@redhat.com"
> 	<blarsen@redhat.com>
> Date: Tue, 29 Oct 2024 15:57:47 +0000
> 
> > > +@kindex show breakpoint max-breakpoint-locations-printed
> > > +@item show breakpoint max-breakpoint-locations-printed
> > > +Display the number of locations that @code{break} will print.  If the
> > number
> > > +of locations is greater than the limit, the additional number of locations
> > > +will be listed.
> >    ^^^^^^^^^^^^^^
> > I guess "will not be listed"?
> > 
> 
> What I meant to say is that there will be a line of output that tells the user
> how many more locations apart from the listed one there are.
> 
> So maybe:
> 
> "If the number of locations is greater than the limit, the breakpoint command will 
> add a line reporting the number of locations that were not listed due to the limit.

Yes, that's much better.  Bonus points for showing an example of such
output.

Thanks.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* RE: [PATCH v7 2/2] gdb, breakpoint: output multiple bp locations
  2024-10-29 16:53       ` Eli Zaretskii
@ 2024-11-04 10:03         ` Gerlicher, Klaus
  2024-11-04 13:22           ` Eli Zaretskii
  0 siblings, 1 reply; 8+ messages in thread
From: Gerlicher, Klaus @ 2024-11-04 10:03 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb-patches, aburgess, blarsen

> -----Original Message-----
> From: Eli Zaretskii <eliz@gnu.org>
> Sent: Tuesday, October 29, 2024 5:54 PM
> To: Gerlicher, Klaus <klaus.gerlicher@intel.com>
> Cc: gdb-patches@sourceware.org; aburgess@redhat.com;
> blarsen@redhat.com
> Subject: Re: [PATCH v7 2/2] gdb, breakpoint: output multiple bp locations
> 
> > From: "Gerlicher, Klaus" <klaus.gerlicher@intel.com>
> > CC: "gdb-patches@sourceware.org" <gdb-patches@sourceware.org>,
> > 	"aburgess@redhat.com" <aburgess@redhat.com>,
> "blarsen@redhat.com"
> > 	<blarsen@redhat.com>
> > Date: Tue, 29 Oct 2024 15:57:47 +0000
> >
> > > > +@kindex show breakpoint max-breakpoint-locations-printed
> > > > +@item show breakpoint max-breakpoint-locations-printed
> > > > +Display the number of locations that @code{break} will print.  If the
> > > number
> > > > +of locations is greater than the limit, the additional number of locations
> > > > +will be listed.
> > >    ^^^^^^^^^^^^^^
> > > I guess "will not be listed"?
> > >
> >
> > What I meant to say is that there will be a line of output that tells the user
> > how many more locations apart from the listed one there are.
> >
> > So maybe:
> >
> > "If the number of locations is greater than the limit, the breakpoint
> command will
> > add a line reporting the number of locations that were not listed due to the
> limit.
> 
> Yes, that's much better.  Bonus points for showing an example of such
> output.

The GDB doc has an example right above this text. Is there a way to easily point to this example? 
Should I maybe add a line that says, "see last line of the small example above"?

Thanks
Klaus
> 
> Thanks.

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de
Managing Directors: Sean Fennelly, Jeffrey Schneiderman, Tiffany Doon Silva
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v7 2/2] gdb, breakpoint: output multiple bp locations
  2024-11-04 10:03         ` Gerlicher, Klaus
@ 2024-11-04 13:22           ` Eli Zaretskii
  0 siblings, 0 replies; 8+ messages in thread
From: Eli Zaretskii @ 2024-11-04 13:22 UTC (permalink / raw)
  To: Gerlicher, Klaus; +Cc: gdb-patches, aburgess, blarsen

> From: "Gerlicher, Klaus" <klaus.gerlicher@intel.com>
> CC: "gdb-patches@sourceware.org" <gdb-patches@sourceware.org>,
> 	"aburgess@redhat.com" <aburgess@redhat.com>, "blarsen@redhat.com"
> 	<blarsen@redhat.com>
> Date: Mon, 4 Nov 2024 10:03:15 +0000
> 
> > > So maybe:
> > >
> > > "If the number of locations is greater than the limit, the breakpoint
> > command will
> > > add a line reporting the number of locations that were not listed due to the
> > limit.
> > 
> > Yes, that's much better.  Bonus points for showing an example of such
> > output.
> 
> The GDB doc has an example right above this text. Is there a way to easily point to this example? 
> Should I maybe add a line that says, "see last line of the small example above"?

Yes, thanks.

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2024-11-04 13:22 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-10-29 11:33 [PATCH v7 0/2] gdb: setting BP with multiple locations only displays one location Klaus Gerlicher
2024-10-29 11:33 ` [PATCH v7 1/2] gdb: extend gdb_breakpoint for multiple locations Klaus Gerlicher
2024-10-29 11:33 ` [PATCH v7 2/2] gdb, breakpoint: output multiple bp locations Klaus Gerlicher
2024-10-29 13:10   ` Eli Zaretskii
2024-10-29 15:57     ` Gerlicher, Klaus
2024-10-29 16:53       ` Eli Zaretskii
2024-11-04 10:03         ` Gerlicher, Klaus
2024-11-04 13:22           ` Eli Zaretskii

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).