diff options
author | Mohamed Bouhaouel <mohamed.bouhaouel@intel.com> | 2023-06-30 10:10:15 +0200 |
---|---|---|
committer | Tom Tromey <tromey@adacore.com> | 2023-09-19 06:56:53 -0600 |
commit | 093da43d2adb4497dfec8afbb4eeaf2425668fdd (patch) | |
tree | 17a7c274bf741c4888997021519c2ccf0e17da02 /gdb/breakpoint.c | |
parent | 12f567bcb640285b0afab74e2ac8d471a175722d (diff) | |
download | binutils-093da43d2adb4497dfec8afbb4eeaf2425668fdd.zip binutils-093da43d2adb4497dfec8afbb4eeaf2425668fdd.tar.gz binutils-093da43d2adb4497dfec8afbb4eeaf2425668fdd.tar.bz2 |
gdb, breakpoint: add a destructor to the watchpoint struct
Make sure to unlink the related breakpoint when the watchpoint instance
is deleted. This prevents having a wp-related breakpoint that is
linked to a NULL watchpoint (e.g. the watchpoint instance is being
deleted when the 'watch' command fails). With the below scenario,
having such a left out breakpoint will lead to a GDB hang, and this
is due to an infinite loop when deleting all inferior breakpoints.
Scenario:
(gdb) set can-use-hw-watchpoints 0
(gdb) awatch <SCOPE VAR>
Can't set read/access watchpoint when hardware watchpoints are disabled.
(gdb) rwatch <SCOPE VAR>
Can't set read/access watchpoint when hardware watchpoints are disabled.
(gdb) <continue the program until the end>
>> HANG <<
Signed-off-by: Mohamed Bouhaouel <mohamed.bouhaouel@intel.com>
Reviewed-by: Bruno Larsen <blarsen@redhat.com>
Diffstat (limited to 'gdb/breakpoint.c')
-rw-r--r-- | gdb/breakpoint.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index c429af4..4b3999a 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -9817,6 +9817,20 @@ break_range_command (const char *arg, int from_tty) install_breakpoint (false, std::move (br), true); } +/* See breakpoint.h. */ + +watchpoint::~watchpoint () +{ + /* Make sure to unlink the destroyed watchpoint from the related + breakpoint ring. */ + + breakpoint *bpt = this; + while (bpt->related_breakpoint != this) + bpt = bpt->related_breakpoint; + + bpt->related_breakpoint = this->related_breakpoint; +} + /* Return non-zero if EXP is verified as constant. Returned zero means EXP is variable. Also the constant detection may fail for some constant expressions and in such case still falsely return |