aboutsummaryrefslogtreecommitdiff
path: root/gdb/breakpoint.c
diff options
context:
space:
mode:
authorMohamed Bouhaouel <mohamed.bouhaouel@intel.com>2023-06-30 10:10:15 +0200
committerTom Tromey <tromey@adacore.com>2023-09-19 06:56:53 -0600
commit093da43d2adb4497dfec8afbb4eeaf2425668fdd (patch)
tree17a7c274bf741c4888997021519c2ccf0e17da02 /gdb/breakpoint.c
parent12f567bcb640285b0afab74e2ac8d471a175722d (diff)
downloadfsf-binutils-gdb-093da43d2adb4497dfec8afbb4eeaf2425668fdd.zip
fsf-binutils-gdb-093da43d2adb4497dfec8afbb4eeaf2425668fdd.tar.gz
fsf-binutils-gdb-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.c14
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