Date: Wed, 8 Oct 2008 08:30:09 GMT From: "Dorr H. Clark" <dclark@engr.scu.edu> To: freebsd-bugs@FreeBSD.org Subject: Re: gnu/124970: gdb(1): gdb crashes after setting hardware watchpoint Message-ID: <200810080830.m988U9Wb029575@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR gnu/124970; it has been noted by GNATS. From: "Dorr H. Clark" <dclark@engr.scu.edu> To: bug-followup@FreeBSD.org Cc: freebsd-bugs@FreeBSD.org, Victor Sudakov <sudakov@sibptus.tomsk.ru> Subject: Re: gnu/124970: gdb(1): gdb crashes after setting hardware watchpoint Date: Wed, 8 Oct 2008 00:56:50 -0700 (PDT) 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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200810080830.m988U9Wb029575>