This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[Patch] Fix memory corruption when using multiple hardware watchpoints.
- From: David Daney <ddaney at avtrex dot com>
- To: gdb-patches at sourceware dot org
- Date: Wed, 10 Sep 2008 13:14:34 -0700
- Subject: [Patch] Fix memory corruption when using multiple hardware watchpoints.
In bpstat_stop_status there is special code to clear the breakpoint_at
element for a hardware watchpoint if it could be invalidated by a
remove_breakpoints(), insert_breakpoints() pair. The comment explains
that we do this to "Prevent further code from trying to use it."
The problem with the current code is that it assumes that there is only
a single hardware breakpoint and breaks out of the loop when it is
found. If there are multiple hardware breakpoints, any but the first
are left with breakpoint_at pointing at now freed memory leading to Bad
Things if the memory happens to get clobbered.
My fix is to continue through the entire list clearing breakpoint_at for
*all* hardware watchpoints and then outside of the loop calling
remove_breakpoints(), insert_breakpoints() if any were found.
Testing on x86_64-pc-linux-gnu. OK to commit (if no regressions)?
2008-09-10 David Daney <ddaney@avtrex.com>
* breakpoint.c (bpstat_stop_status): Clear breakpoint_at for
all hardware bpstats.
Index: breakpoint.c
===================================================================
RCS file: /cvs/src/src/gdb/breakpoint.c,v
retrieving revision 1.350
diff -u -p -r1.350 breakpoint.c
--- breakpoint.c 8 Sep 2008 21:57:42 -0000 1.350
+++ breakpoint.c 10 Sep 2008 19:56:58 -0000
@@ -3054,6 +3054,7 @@ bpstat_stop_status (CORE_ADDR bp_addr, p
/* Pointer to the last thing in the chain currently. */
bpstat bs = root_bs;
int ix;
+ int need_remove_insert;
ALL_BP_LOCATIONS (bl)
{
@@ -3146,6 +3147,7 @@ bpstat_stop_status (CORE_ADDR bp_addr, p
if (bs->stop)
break;
+ need_remove_insert = 0;
if (bs == NULL)
for (bs = root_bs->next; bs != NULL; bs = bs->next)
if (!bs->stop
@@ -3158,11 +3160,15 @@ bpstat_stop_status (CORE_ADDR bp_addr, p
location is no longer used by the watchpoint. Prevent
further code from trying to use it. */
bs->breakpoint_at = NULL;
- remove_breakpoints ();
- insert_breakpoints ();
- break;
+ need_remove_insert = 1;
}
+ if (need_remove_insert)
+ {
+ remove_breakpoints ();
+ insert_breakpoints ();
+ }
+
return root_bs->next;
}