gnu/124970: gdb(1): gdb crashes after setting hardware watchpoint

Dorr H. Clark dclark at engr.scu.edu
Wed Oct 8 07:56:54 UTC 2008


We believe that the problem reported in PR 124970 has been fixed in gdb 6.2.1. 

The latest port for gdb6 is 6.6.1 in 7.0-Release.  However, 7.0 was distributed 
with the 6.1.1 release of gdb.  We recommend that the gdb port in the 7.x 
release series be upgraded to address this issue.  Note that FreeBSD 6.3 
also has the same version of gdb with the same problem.

What follows is a detailed discussion of the issue and a patch.

In addition to patching gdb itself, switching locally to gdb 6.6.1 is
another workaround for users concerned about this bug.

Problem:
When control reaches the end of scope for hardware watchpoint, the value chain
is not freed. Thus, when the program reaches the end, the value chain still
exists and when non-existent fields in it are dereferenced, a segmentation 
fault ensues. 

Solution:
In the following solution, the deletion of watchpoint is moved to
delete_breakpoint(). This routine is invoked when the watchpoint reaches the end
of scope. Thus the value chain has been removed when the program finishes and it
will no longer cause a segmentation fault.

Ramnath Duggirala
Engineer

Dorr H. Clark
Advisor

Graduate School of Engineering
Santa Clara University
Santa Clara, CA

http://www.cse.scu.edu/~dclark/coen_284_FreeBSD/124970.txt

Patch ( contrib/gdb/gdb/breakpoint.c ):

--- breakpoint.c.orig	2008-10-08 00:34:23.000000000 +0000
+++ breakpoint.c	2008-10-08 00:34:26.000000000 +0000
@@ -745,6 +745,23 @@
   return 0;
 }
 
+/* Helper routine: free the value chain for a breakpoint (watchpoint).  */
+
+static void free_valchain (struct bp_location *b)
+{
+  struct value *v;
+  struct value *n;
+
+  /* Free the saved value chain.  We will construct a new one
+     the next time the watchpoint is inserted.  */
+  for (v = b->owner->val_chain; v; v = n)
+    {
+      n = v->next;
+      value_free (v);
+    }
+  b->owner->val_chain = NULL;
+}
+
 /* Insert a low-level "breakpoint" of some type.  BPT is the breakpoint.
    Any error messages are printed to TMP_ERROR_STREAM; and DISABLED_BREAKS,
    PROCESS_WARNING, and HW_BREAKPOINT_ERROR are used to report problems.
@@ -919,6 +936,8 @@
 
       if (within_current_scope)
 	{
+	  free_valchain (bpt);
+
 	  /* Evaluate the expression and cut the chain of values
 	     produced off from the value chain.
 
@@ -1504,15 +1523,6 @@
       if ((is == mark_uninserted) && (b->inserted))
 	warning ("Could not remove hardware watchpoint %d.",
 		 b->owner->number);
-
-      /* Free the saved value chain.  We will construct a new one
-         the next time the watchpoint is inserted.  */
-      for (v = b->owner->val_chain; v; v = n)
-	{
-	  n = v->next;
-	  value_free (v);
-	}
-      b->owner->val_chain = NULL;
     }
   else if ((b->owner->type == bp_catch_fork ||
 	    b->owner->type == bp_catch_vfork ||
@@ -6866,13 +6876,15 @@
   if (bpt->type == bp_none)
     return;
 
-  if (delete_breakpoint_hook)
-    delete_breakpoint_hook (bpt);
+  if (deprecated_delete_breakpoint_hook)
+    deprecated_delete_breakpoint_hook (bpt);
   breakpoint_delete_event (bpt->number);
 
   if (bpt->loc->inserted)
     remove_breakpoint (bpt->loc, mark_inserted);
 
+  free_valchain (bpt->loc);
+
   if (breakpoint_chain == bpt)
     breakpoint_chain = bpt->next;
 
 





More information about the freebsd-bugs mailing list