diff options
author | Andrew Burgess <aburgess@redhat.com> | 2023-03-28 11:24:58 +0100 |
---|---|---|
committer | Andrew Burgess <aburgess@redhat.com> | 2023-04-11 11:49:07 +0100 |
commit | 07c1c91de384f8fa7cad88acc71ac6a7b33cefcf (patch) | |
tree | 42eac7d2405b0a485344336ee7898775b8c56c98 /gdb/breakpoint.c | |
parent | 6abf2eeffa3771cf5dbd30fef79c9b7a8c39b973 (diff) | |
download | fsf-binutils-gdb-07c1c91de384f8fa7cad88acc71ac6a7b33cefcf.zip fsf-binutils-gdb-07c1c91de384f8fa7cad88acc71ac6a7b33cefcf.tar.gz fsf-binutils-gdb-07c1c91de384f8fa7cad88acc71ac6a7b33cefcf.tar.bz2 |
gdb: warn when converting h/w watchpoints to s/w
On amd64 (at least) if a user sets a watchpoint before the inferior
has started then GDB will assume that a hardware watchpoint can be
created.
When the inferior starts there is a chance that the watchpoint can't
actually be create as a hardware watchpoint, in which case (currently)
GDB will silently convert the watchpoint to a software watchpoint.
Here's an example session:
(gdb) p sizeof var
$1 = 4000
(gdb) watch var
Hardware watchpoint 1: var
(gdb) info watchpoints
Num Type Disp Enb Address What
1 hw watchpoint keep y var
(gdb) starti
Starting program: /home/andrew/tmp/watch
Program stopped.
0x00007ffff7fd3110 in _start () from /lib64/ld-linux-x86-64.so.2
(gdb) info watchpoints
Num Type Disp Enb Address What
1 watchpoint keep y var
(gdb)
Notice that before the `starti` command the watchpoint is showing as a
hardware watchpoint, but afterwards it is showing as a software
watchpoint. Additionally, note that we clearly told the user we
created a hardware watchpoint:
(gdb) watch var
Hardware watchpoint 1: var
I think this is bad. I used `starti`, but if the user did `start` or
even `run` then the inferior is going to be _very_ slow, which will be
unexpected -- after all, we clearly told the user that we created a
hardware watchpoint, and the manual clearly says that hardware
watchpoints are fast (at least compared to s/w watchpoints).
In this patch I propose adding a new warning which will be emitted
when GDB downgrades a h/w watchpoint to s/w. The session now looks
like this:
(gdb) p sizeof var
$1 = 4000
(gdb) watch var
Hardware watchpoint 1: var
(gdb) info watchpoints
Num Type Disp Enb Address What
1 hw watchpoint keep y var
(gdb) starti
Starting program: /home/andrew/tmp/watch
warning: watchpoint 1 downgraded to software watchpoint
Program stopped.
0x00007ffff7fd3110 in _start () from /lib64/ld-linux-x86-64.so.2
(gdb) info watchpoints
Num Type Disp Enb Address What
1 watchpoint keep y var
(gdb)
The important line is:
warning: watchpoint 1 downgraded to software watchpoint
It's not much, but hopefully it will be enough to indicate to the user
that something unexpected has occurred, and hopefully, they will not
be surprised when the inferior runs much slower than they expected.
I've added an amd64 only test in gdb.arch/, I didn't want to try
adding this as a global test as other architectures might be able to
support the watchpoint request in h/w.
Also the test is skipped for extended-remote boards as there's a
different set of options for limiting hardware watchpoints on remote
targets, and this test isn't about them.
Reviewed-By: Lancelot Six <lancelot.six@amd.com>
Diffstat (limited to 'gdb/breakpoint.c')
-rw-r--r-- | gdb/breakpoint.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index ebe9794..47f35c6 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -2143,6 +2143,21 @@ update_watchpoint (struct watchpoint *b, bool reparse) } } + /* Helper function to bundle possibly emitting a warning along with + changing the type of B to bp_watchpoint. */ + auto change_type_to_bp_watchpoint = [] (breakpoint *bp) + { + /* Only warn for breakpoints that have been assigned a +ve number, + anything else is either an internal watchpoint (which we don't + currently create) or has not yet been finalized, in which case + this change of type will be occurring before the user is told + the type of this watchpoint. */ + if (bp->type == bp_hardware_watchpoint && bp->number > 0) + warning (_("watchpoint %d downgraded to software watchpoint"), + bp->number); + bp->type = bp_watchpoint; + }; + /* Change the type of breakpoint between hardware assisted or an ordinary watchpoint depending on the hardware support and free hardware slots. Recheck the number of free hardware slots @@ -2200,7 +2215,7 @@ update_watchpoint (struct watchpoint *b, bool reparse) "resources for this watchpoint.")); /* Downgrade to software watchpoint. */ - b->type = bp_watchpoint; + change_type_to_bp_watchpoint (b); } else { @@ -2221,7 +2236,7 @@ update_watchpoint (struct watchpoint *b, bool reparse) "read/access watchpoint.")); } else - b->type = bp_watchpoint; + change_type_to_bp_watchpoint (b); loc_type = (b->type == bp_watchpoint? bp_loc_software_watchpoint : bp_loc_hardware_watchpoint); |