* [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