This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[patch] Fix segfault on a failed watchpoint update
- From: Jan Kratochvil <jan dot kratochvil at redhat dot com>
- To: gdb-patches at sourceware dot org
- Date: Sun, 2 Mar 2008 09:40:50 +0100
- Subject: [patch] Fix segfault on a failed watchpoint update
Hi,
currently GDB HEAD segfaults during one case for the PIE inferiors (failing as
it is the unpatched CVS HEAD), segfault fix attached.
Regards,
Jan
crash reproducibility:
$ runtest --target_board=unix/-fPIE/-pie gdb.base/watchpoint.exp
WARNING: Couldn't find the global config file.
Test Run By jkratoch on Sun Mar 2 09:31:14 2008
Native configuration is x86_64-unknown-linux-gnu
=== gdb tests ===
Schedule of variations:
unix/-fPIE/-pie
Running target unix/-fPIE/-pie
Using /usr/share/dejagnu/baseboards/unix.exp as board description file for target.
Using /usr/share/dejagnu/config/unix.exp as generic interface file for target.
Using ../.././gdb/testsuite/config/unix.exp as tool-and-target-specific interface file.
Running ../.././gdb/testsuite/gdb.base/watchpoint.exp ...
FAIL: gdb.base/watchpoint.exp: run to marker1 in test_simple_watchpoint
ERROR: Process no longer exists
ERROR: Couldn't send disable 3 to GDB.
ERROR: Delete all breakpoints in delete_breakpoints (timeout)
ERROR: Delete all breakpoints in delete_breakpoints (timeout)
FAIL: gdb.base/watchpoint.exp: watch tests suppressed
FAIL: gdb.base/watchpoint.exp: (timeout) disable fast watches
FAIL: gdb.base/watchpoint.exp: (timeout) show disable fast watches
FAIL: gdb.base/watchpoint.exp: (timeout) set slow conditional watch
FAIL: gdb.base/watchpoint.exp: (timeout) trigger slow conditional watch
FAIL: gdb.base/watchpoint.exp: (timeout) rwatch disallowed when can-use-hw-watchpoints cleared
ERROR: Delete all breakpoints in delete_breakpoints (timeout)
=== gdb Summary ===
# of expected passes 7
# of unexpected failures 7
# of unresolved testcases 5
.../sources/gdb/testsuite/../../gdb/gdb version 6.8.50.20080302-cvs -nx
...
(gdb) PASS: gdb.base/watchpoint.exp: disable watchpoint in test_simple_watchpoint
run
Starting program: /home/jkratoch/redhat/sources/gdb/testsuite/gdb.base/watchpoint
Error in re-setting breakpoint 1: Cannot access memory at address 0x86c
Error in re-setting breakpoint 2: Cannot access memory at address 0x872
Error in re-setting breakpoint 3: Cannot access memory at address 0x20127c
Error in re-setting breakpoint 1: Cannot access memory at address 0x86c
Error in re-setting breakpoint 2: Cannot access memory at address 0x872
Error in re-setting breakpoint 3: Cannot access memory at address 0x20127c
Error in re-setting breakpoint 1: Cannot access memory at address 0x86c
Error in re-setting breakpoint 2: Cannot access memory at address 0x872
Error in re-setting breakpoint 3: Cannot access memory at address 0x20127c
Program exited normally.
(gdb) FAIL: gdb.base/watchpoint.exp: run to marker1 in test_simple_watchpoint
info watch
*** glibc detected *** /home/jkratoch/redhat/sources/gdb/testsuite/../../gdb/gdb: double free or corruption (!prev): 0x00000000023f9d20 ***
======= Backtrace: =========
/lib64/libc.so.6[0x3b98672832]
/lib64/libc.so.6(cfree+0x8c)[0x3b98675f2c]
/home/jkratoch/redhat/sources/gdb/testsuite/../../gdb/gdb(xfree+0x1c)[0x44efb6]
/home/jkratoch/redhat/sources/gdb/testsuite/../../gdb/gdb(free_all_values+0x2a)[0x4cd65a]
/home/jkratoch/redhat/sources/gdb/testsuite/../../gdb/gdb(execute_command+0x26)[0x44b9df]
...
2008-03-02 Jan Kratochvil <jan.kratochvil@redhat.com>
* breakpoint.c (update_watchpoint): Move B->VAL setting behind the
VALUE_CONTENTS call.
--- ./gdb/breakpoint.c 27 Feb 2008 20:27:49 -0000 1.304
+++ ./gdb/breakpoint.c 2 Mar 2008 08:27:20 -0000
@@ -913,13 +917,15 @@ update_watchpoint (struct breakpoint *b,
during evaluation, and set watchoints at addresses as needed.
Those values are explicitly deleted here. */
v = evaluate_expression (b->exp);
+ /* Fetch the value first as if ti fails and breaks out by the exception
+ there will be no stale V left in B->VAL. */
+ value_contents (v);
/* Avoid setting b->val if it's already set. The meaning of
b->val is 'the last value' user saw, and we should update
it only if we reported that last value to user. As it
happens, the code that reports it updates b->val directly. */
if (b->val == NULL)
b->val = v;
- value_contents (v);
value_release_to_mark (mark);
/* Look at each value on the value chain. */