[PATCHv2,03/13] gdb: include breakpoint number in testing condition error message
Commit Message
When GDB fails to test the condition of a conditional breakpoint, for
whatever reason, the error message looks like this:
(gdb) break foo if (*(int *) 0) == 1
Breakpoint 1 at 0x40111e: file bpcond.c, line 11.
(gdb) r
Starting program: /tmp/bpcond
Error in testing breakpoint condition:
Cannot access memory at address 0x0
Breakpoint 1, foo () at bpcond.c:11
11 int a = 32;
(gdb)
The line I'm interested in for this commit is this one:
Error in testing breakpoint condition:
In the case above we can figure out that the problematic breakpoint
was #1 because in the final line of the message GDB reports the stop a
breakpoint #1.
However, in the next few patches I plan to change this. In some cases
I don't think it makes sense for GDB to report the stop as being at
breakpoint #1, consider this case:
(gdb) list some_func
1 int
2 some_func ()
3 {
4 int *p = 0;
5 return *p;
6 }
7
8 void
9 foo ()
10 {
(gdb) break foo if (some_func ())
Breakpoint 1 at 0x40111e: file bpcond.c, line 11.
(gdb) r
Starting program: /tmp/bpcond
Program received signal SIGSEGV, Segmentation fault.
0x0000000000401116 in some_func () at bpcond.c:5
5 return *p;
Error in testing breakpoint condition:
The program being debugged was signaled while in a function called from GDB.
GDB remains in the frame where the signal was received.
To change this behavior use "set unwindonsignal on".
Evaluation of the expression containing the function
(some_func) will be abandoned.
When the function is done executing, GDB will silently stop.
Program received signal SIGSEGV, Segmentation fault.
Breakpoint 1, 0x0000000000401116 in some_func () at bpcond.c:5
5 return *p;
(gdb)
Notice that, the final lines of output report the stop as being at
breakpoint #1, even though we are actually located within some_func.
I find this behaviour confusing, and propose that this should be
changed. However, if I make that change then every reference to
breakpoint #1 will be lost from the error message.
So, in this commit, in preparation for the later commits, I propose to
change the 'Error in testing breakpoint condition:' line to this:
Error in testing condition for breakpoint NUMBER:
where NUMBER will be filled in as appropriate. Here's the first
example with the updated error:
(gdb) break foo if (*(int *) 0) == 0
Breakpoint 1 at 0x40111e: file bpcond.c, line 11.
(gdb) r
Starting program: /tmp/bpcond
Error in testing condition for breakpoint 1:
Cannot access memory at address 0x0
Breakpoint 1, foo () at bpcond.c:11
11 int a = 32;
(gdb)
The breakpoint number does now appear twice in the output, but I don't
see that as a negative.
This commit just changes the one line of the error, and updates the
few tests that either included the old error in comments, or actually
checked for the error in the expected output.
As the only test that checked the line I modified is a Python test,
I've added a new test that doesn't rely on Python that checks the
error message in detail.
While working on the new test, I spotted that it would fail when run
with native-gdbserver and native-extended-gdbserver target boards.
This turns out to be due to a gdbserver bug. To avoid cluttering this
commit I've added a work around to the new test script so that the
test passes for the remote boards, in the next few commits I will fix
gdbserver, and update the test script to remove the work around.
---
gdb/breakpoint.c | 3 +-
gdb/testsuite/gdb.base/bp-cond-failure.c | 30 +++++++
gdb/testsuite/gdb.base/bp-cond-failure.exp | 83 +++++++++++++++++++
.../gdb.base/catch-signal-siginfo-cond.exp | 2 +-
gdb/testsuite/gdb.base/gnu-ifunc.exp | 2 +-
.../gdb.python/py-finish-breakpoint.exp | 2 +-
gdb/testsuite/lib/gdb.exp | 8 ++
7 files changed, 126 insertions(+), 4 deletions(-)
create mode 100644 gdb/testsuite/gdb.base/bp-cond-failure.c
create mode 100644 gdb/testsuite/gdb.base/bp-cond-failure.exp
Comments
On Wednesday, January 18, 2023 5:18 PM, Andrew Burgess wrote:
> When GDB fails to test the condition of a conditional breakpoint, for
> whatever reason, the error message looks like this:
>
> (gdb) break foo if (*(int *) 0) == 1
> Breakpoint 1 at 0x40111e: file bpcond.c, line 11.
> (gdb) r
> Starting program: /tmp/bpcond
> Error in testing breakpoint condition:
> Cannot access memory at address 0x0
>
> Breakpoint 1, foo () at bpcond.c:11
> 11 int a = 32;
> (gdb)
>
> The line I'm interested in for this commit is this one:
>
> Error in testing breakpoint condition:
>
> In the case above we can figure out that the problematic breakpoint
> was #1 because in the final line of the message GDB reports the stop a
> breakpoint #1.
...
> diff --git a/gdb/testsuite/gdb.base/bp-cond-failure.c b/gdb/testsuite/gdb.base/bp-cond-
> failure.c
> new file mode 100644
> index 00000000000..be9d1fdcf2d
> --- /dev/null
> +++ b/gdb/testsuite/gdb.base/bp-cond-failure.c
> @@ -0,0 +1,30 @@
> +/* Copyright 2022 Free Software Foundation, Inc.
The year now has to be 2022-2023, I believe. There is one more case
below.
...
> diff --git a/gdb/testsuite/gdb.base/bp-cond-failure.exp b/gdb/testsuite/gdb.base/bp-cond-
> failure.exp
> new file mode 100644
> index 00000000000..6f89771d187
> --- /dev/null
> +++ b/gdb/testsuite/gdb.base/bp-cond-failure.exp
> @@ -0,0 +1,83 @@
> +# Copyright 2022 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/>.
> +
> +# Check the format of the error message given when a breakpoint
> +# condition fails.
> +#
> +# In this case the breakpoint condition does not make use of inferior
> +# function calls, instead, the expression used for the breakpoint
> +# condition will throw an error when evaluated.
> +#
> +# We check that the correct breakpoint number appears in the error
> +# message, and that the error is reported at the correct source
> +# location.
> +
> +standard_testfile
> +
> +if { [prepare_for_testing "failed to prepare" ${binfile} "${srcfile}" \
> + {debug}] == -1 } {
> + return
> +}
> +
> +# This test relies on reading address zero triggering a SIGSEGV.
> +if { [is_address_zero_readable] } {
> + return
> +}
> +
> +# Where the breakpoint will be placed.
> +set bp_line [gdb_get_line_number "Breakpoint here"]
> +
> +proc run_test { cond_eval } {
> + clean_restart ${::binfile}
> +
> + if {![runto_main]} {
The other if-statements in this file put spaces around the condition.
> + fail "run to main"
> + return -1
> + }
> +
> + if { $cond_eval != "auto" } {
AFAIK, for string comparison, `eq` and `ne` are the recommended operators to use.
> + gdb_test_no_output "set breakpoint condition-evaluation ${cond_eval}"
> + }
> +
> + # Setup the conditional breakpoint and record its number.
> + gdb_breakpoint "${::srcfile}:${::bp_line} if (*(int *) 0) == 0"
> + set bp_num [get_integer_valueof "\$bpnum" "*UNKNOWN*"]
> +
> + gdb_test "continue" \
> + [multi_line \
> + "Continuing\\." \
> + "Error in testing condition for breakpoint ${bp_num}:" \
> + "Cannot access memory at address 0x0" \
> + "" \
> + "Breakpoint ${bp_num}, foo \\(\\) at \[^\r\n\]+:${::bp_line}" \
> + "${::decimal}\\s+\[^\r\n\]+Breakpoint here\[^\r\n\]+"]
> +}
> +
> +# If we're using a remote target then conditions could be evaulated
> +# locally on the host, or on the remote target. Otherwise, conditions
> +# are always evaluated locally (which is what auto will select).
> +#
> +# NOTE: 'target' is not included here for remote targets as a
> +# gdbserver bug prevents the test from passing. This will be fixed in
> +# the next commit, and this test updated.
> +if { [gdb_is_remote_or_extended_remote_target] } {
> + set cond_eval_modes { "host" }
> +} else {
> + set cond_eval_modes { "auto" }
> +}
> +
> +foreach_with_prefix cond_eval $cond_eval_modes {
> + run_test $cond_eval
> +}
> diff --git a/gdb/testsuite/gdb.base/catch-signal-siginfo-cond.exp
> b/gdb/testsuite/gdb.base/catch-signal-siginfo-cond.exp
> index 182b2f25faa..f400fc03b28 100644
> --- a/gdb/testsuite/gdb.base/catch-signal-siginfo-cond.exp
> +++ b/gdb/testsuite/gdb.base/catch-signal-siginfo-cond.exp
> @@ -18,7 +18,7 @@
> #
> # (gdb) continue
> # Continuing.
> -# Error in testing breakpoint condition:
> +# Error in testing condition for breakpoint NUM:
> # Selected thread is running.
> #
> # Catchpoint 3 (signal SIGUSR1), 0x0000003615e35877 in __GI_raise (sig=10) at raise.c:56
> diff --git a/gdb/testsuite/gdb.base/gnu-ifunc.exp b/gdb/testsuite/gdb.base/gnu-ifunc.exp
> index 0a435806409..22462bea233 100644
> --- a/gdb/testsuite/gdb.base/gnu-ifunc.exp
> +++ b/gdb/testsuite/gdb.base/gnu-ifunc.exp
> @@ -281,7 +281,7 @@ proc misc_tests {resolver_attr resolver_debug final_debug} {
>
> # Also test a former patch regression:
> # Continuing.
> - # Error in testing breakpoint condition:
> + # Error in testing condition for breakpoint NUM:
> # Attempt to take address of value not located in memory.
> #
> # Breakpoint 2, main () at ./gdb.base/gnu-ifunc.c:33
> diff --git a/gdb/testsuite/gdb.python/py-finish-breakpoint.exp
> b/gdb/testsuite/gdb.python/py-finish-breakpoint.exp
> index b6bd7a63c8f..e5a46874afd 100644
> --- a/gdb/testsuite/gdb.python/py-finish-breakpoint.exp
> +++ b/gdb/testsuite/gdb.python/py-finish-breakpoint.exp
> @@ -188,7 +188,7 @@ with_test_prefix "finish in normal frame" {
> gdb_test "python TestBreakpoint()" "TestBreakpoint init" "set BP in condition"
>
> gdb_test "continue" \
> - "test don't stop: 1.*test don't stop: 2.*test stop.*Error in testing breakpoint
> condition.*The program being debugged stopped while in a function called from GDB.*" \
> + "test don't stop: 1.*test don't stop: 2.*test stop.*Error in testing condition for
> breakpoint ${::decimal}.*The program being debugged stopped while in a function called from
> GDB.*" \
> "stop in condition function"
>
> gdb_test "continue" "Continuing.*" "finish condition evaluation"
> diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
> index 68337bd235c..f51332b0177 100644
> --- a/gdb/testsuite/lib/gdb.exp
> +++ b/gdb/testsuite/lib/gdb.exp
> @@ -9332,5 +9332,13 @@ proc has_dependency { file dep } {
> return [regexp $dep $output]
> }
>
> +# Return true if we are currently testing the 'remote' or
> +# 'extended-remote' targets.
> +proc gdb_is_remote_or_extended_remote_target {} {
> + return [target_info exists gdb_protocol]
> + && ([target_info gdb_protocol] == "remote"
> + || [target_info gdb_protocol] == "extended-remote")
Here, the same comment about `eq` and `ne` for string comparison.
> +}
> +
> # Always load compatibility stuff.
> load_lib future.exp
> --
> 2.25.4
Regards
-Baris
Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928
On Wednesday, January 18, 2023 5:18 PM, Andrew Burgess wrote:
...
> So, in this commit, in preparation for the later commits, I propose to
> change the 'Error in testing breakpoint condition:' line to this:
>
> Error in testing condition for breakpoint NUMBER:
Here, because we're now referring to a particular breakpoint,
I believe the spelling should be "condition for Breakpoint NUMBER:",
with uppercase 'B'. Maybe Eli can comment on this, too.
Regards
-Baris
Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928
> From: "Aktemur, Tankut Baris" <tankut.baris.aktemur@intel.com>
> Date: Thu, 19 Jan 2023 10:54:16 +0000
>
> On Wednesday, January 18, 2023 5:18 PM, Andrew Burgess wrote:
> ...
> > So, in this commit, in preparation for the later commits, I propose to
> > change the 'Error in testing breakpoint condition:' line to this:
> >
> > Error in testing condition for breakpoint NUMBER:
>
> Here, because we're now referring to a particular breakpoint,
> I believe the spelling should be "condition for Breakpoint NUMBER:",
> with uppercase 'B'. Maybe Eli can comment on this, too.
No, capitalized "Breakpoint" would read wrong English-wise in that
case.
On Thursday, January 19, 2023 12:34 PM, Eli Zaretskii wrote:
> > From: "Aktemur, Tankut Baris" <tankut.baris.aktemur@intel.com>
> > Date: Thu, 19 Jan 2023 10:54:16 +0000
> >
> > On Wednesday, January 18, 2023 5:18 PM, Andrew Burgess wrote:
> > ...
> > > So, in this commit, in preparation for the later commits, I propose to
> > > change the 'Error in testing breakpoint condition:' line to this:
> > >
> > > Error in testing condition for breakpoint NUMBER:
> >
> > Here, because we're now referring to a particular breakpoint,
> > I believe the spelling should be "condition for Breakpoint NUMBER:",
> > with uppercase 'B'. Maybe Eli can comment on this, too.
>
> No, capitalized "Breakpoint" would read wrong English-wise in that
> case.
For me to better understand the rule, wouldn't it be the same as
"see in figure 5" vs. "see in Figure 5", or "given in section 2.1"
vs. "given in Section 2.1"?
-Baris
Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928
"Aktemur, Tankut Baris" <tankut.baris.aktemur@intel.com> writes:
> On Thursday, January 19, 2023 12:34 PM, Eli Zaretskii wrote:
>> > From: "Aktemur, Tankut Baris" <tankut.baris.aktemur@intel.com>
>> > Date: Thu, 19 Jan 2023 10:54:16 +0000
>> >
>> > On Wednesday, January 18, 2023 5:18 PM, Andrew Burgess wrote:
>> > ...
>> > > So, in this commit, in preparation for the later commits, I propose to
>> > > change the 'Error in testing breakpoint condition:' line to this:
>> > >
>> > > Error in testing condition for breakpoint NUMBER:
>> >
>> > Here, because we're now referring to a particular breakpoint,
>> > I believe the spelling should be "condition for Breakpoint NUMBER:",
>> > with uppercase 'B'. Maybe Eli can comment on this, too.
>>
>> No, capitalized "Breakpoint" would read wrong English-wise in that
>> case.
>
> For me to better understand the rule, wouldn't it be the same as
> "see in figure 5" vs. "see in Figure 5", or "given in section 2.1"
> vs. "given in Section 2.1"?
Given the number of corrections I get for my doc edits, this should be
taken with a pinch of salt, but ...
... in the examples you give "Figure 5" and "Section 2.1" would be the
actual name of a thing, e.g. there will be a figure somewhere with the
title "Figure 5" and a section somewhere titled "Section 2.1", thus the
capitalisation is correct because you're referencing a named thing.
In the breakpoint case, what we're referencing isn't _named_ Breakpoint
5, it just is the 5th breakpoint.
At least, that's what I'd do unless told different :)
Thanks,
Andrew
> From: Andrew Burgess <aburgess@redhat.com>
> Date: Wed, 25 Jan 2023 16:49:11 +0000
>
> "Aktemur, Tankut Baris" <tankut.baris.aktemur@intel.com> writes:
>
> >> No, capitalized "Breakpoint" would read wrong English-wise in that
> >> case.
> >
> > For me to better understand the rule, wouldn't it be the same as
> > "see in figure 5" vs. "see in Figure 5", or "given in section 2.1"
> > vs. "given in Section 2.1"?
>
> Given the number of corrections I get for my doc edits, this should be
> taken with a pinch of salt, but ...
>
> ... in the examples you give "Figure 5" and "Section 2.1" would be the
> actual name of a thing, e.g. there will be a figure somewhere with the
> title "Figure 5" and a section somewhere titled "Section 2.1", thus the
> capitalisation is correct because you're referencing a named thing.
>
> In the breakpoint case, what we're referencing isn't _named_ Breakpoint
> 5, it just is the 5th breakpoint.
Yes, that's correct. "Breakpoint" is not a proper name here, it's
just a word.
@@ -5542,7 +5542,8 @@ bpstat_check_breakpoint_conditions (bpstat *bs, thread_info *thread)
catch (const gdb_exception &ex)
{
exception_fprintf (gdb_stderr, ex,
- "Error in testing breakpoint condition:\n");
+ "Error in testing condition for breakpoint %d:\n",
+ b->number);
}
}
else
new file mode 100644
@@ -0,0 +1,30 @@
+/* Copyright 2022 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ 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/>. */
+
+int
+foo ()
+{
+ return 0; /* Breakpoint here. */
+}
+
+int
+main ()
+{
+ int res = foo ();
+
+ return res;
+}
new file mode 100644
@@ -0,0 +1,83 @@
+# Copyright 2022 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/>.
+
+# Check the format of the error message given when a breakpoint
+# condition fails.
+#
+# In this case the breakpoint condition does not make use of inferior
+# function calls, instead, the expression used for the breakpoint
+# condition will throw an error when evaluated.
+#
+# We check that the correct breakpoint number appears in the error
+# message, and that the error is reported at the correct source
+# location.
+
+standard_testfile
+
+if { [prepare_for_testing "failed to prepare" ${binfile} "${srcfile}" \
+ {debug}] == -1 } {
+ return
+}
+
+# This test relies on reading address zero triggering a SIGSEGV.
+if { [is_address_zero_readable] } {
+ return
+}
+
+# Where the breakpoint will be placed.
+set bp_line [gdb_get_line_number "Breakpoint here"]
+
+proc run_test { cond_eval } {
+ clean_restart ${::binfile}
+
+ if {![runto_main]} {
+ fail "run to main"
+ return -1
+ }
+
+ if { $cond_eval != "auto" } {
+ gdb_test_no_output "set breakpoint condition-evaluation ${cond_eval}"
+ }
+
+ # Setup the conditional breakpoint and record its number.
+ gdb_breakpoint "${::srcfile}:${::bp_line} if (*(int *) 0) == 0"
+ set bp_num [get_integer_valueof "\$bpnum" "*UNKNOWN*"]
+
+ gdb_test "continue" \
+ [multi_line \
+ "Continuing\\." \
+ "Error in testing condition for breakpoint ${bp_num}:" \
+ "Cannot access memory at address 0x0" \
+ "" \
+ "Breakpoint ${bp_num}, foo \\(\\) at \[^\r\n\]+:${::bp_line}" \
+ "${::decimal}\\s+\[^\r\n\]+Breakpoint here\[^\r\n\]+"]
+}
+
+# If we're using a remote target then conditions could be evaulated
+# locally on the host, or on the remote target. Otherwise, conditions
+# are always evaluated locally (which is what auto will select).
+#
+# NOTE: 'target' is not included here for remote targets as a
+# gdbserver bug prevents the test from passing. This will be fixed in
+# the next commit, and this test updated.
+if { [gdb_is_remote_or_extended_remote_target] } {
+ set cond_eval_modes { "host" }
+} else {
+ set cond_eval_modes { "auto" }
+}
+
+foreach_with_prefix cond_eval $cond_eval_modes {
+ run_test $cond_eval
+}
@@ -18,7 +18,7 @@
#
# (gdb) continue
# Continuing.
-# Error in testing breakpoint condition:
+# Error in testing condition for breakpoint NUM:
# Selected thread is running.
#
# Catchpoint 3 (signal SIGUSR1), 0x0000003615e35877 in __GI_raise (sig=10) at raise.c:56
@@ -281,7 +281,7 @@ proc misc_tests {resolver_attr resolver_debug final_debug} {
# Also test a former patch regression:
# Continuing.
- # Error in testing breakpoint condition:
+ # Error in testing condition for breakpoint NUM:
# Attempt to take address of value not located in memory.
#
# Breakpoint 2, main () at ./gdb.base/gnu-ifunc.c:33
@@ -188,7 +188,7 @@ with_test_prefix "finish in normal frame" {
gdb_test "python TestBreakpoint()" "TestBreakpoint init" "set BP in condition"
gdb_test "continue" \
- "test don't stop: 1.*test don't stop: 2.*test stop.*Error in testing breakpoint condition.*The program being debugged stopped while in a function called from GDB.*" \
+ "test don't stop: 1.*test don't stop: 2.*test stop.*Error in testing condition for breakpoint ${::decimal}.*The program being debugged stopped while in a function called from GDB.*" \
"stop in condition function"
gdb_test "continue" "Continuing.*" "finish condition evaluation"
@@ -9332,5 +9332,13 @@ proc has_dependency { file dep } {
return [regexp $dep $output]
}
+# Return true if we are currently testing the 'remote' or
+# 'extended-remote' targets.
+proc gdb_is_remote_or_extended_remote_target {} {
+ return [target_info exists gdb_protocol]
+ && ([target_info gdb_protocol] == "remote"
+ || [target_info gdb_protocol] == "extended-remote")
+}
+
# Always load compatibility stuff.
load_lib future.exp