This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Fix watch -location crash on inaccessible memory
- From: Pedro Alves <pedro at codesourcery dot com>
- To: gdb-patches at sourceware dot org
- Date: Tue, 9 Nov 2010 18:29:59 +0000
- Subject: Fix watch -location crash on inaccessible memory
GDB is crashing dereferencing a NULL pointer if you try to watch an
inaccessible location with watch -location:
(top-gdb) bt 5
#0 0x0000000000541d2a in value_type (value=0x0) at ../../src/gdb/value.c:354
#1 0x0000000000551668 in value_addr (arg1=0x0) at ../../src/gdb/valops.c:1557
#2 0x000000000052e540 in watch_command_1 (arg=0xbac22b "", accessflag=0, from_tty=1, just_location=1)
at ../../src/gdb/breakpoint.c:8129
#3 0x000000000052ef3b in watch_maybe_just_location (arg=0xbac220 "*global_ptr", accessflag=0, from_tty=1)
at ../../src/gdb/breakpoint.c:8411
#4 0x000000000052ef65 in watch_command (arg=0xbac216 "-location *global_ptr", from_tty=1)
at ../../src/gdb/breakpoint.c:8417
(More stack frames follow...)
fetch_subexp_value's val "out" argument is only set to
non-NULL if the value was un-lazied successfully (that is, fetched
from memory). If we want to get at the address of the
expression, the lazy value is enough (we don't need the actual
value of the expression), and that's what the 4th parameter of
fetch_subexp_value gives us.
Fixed thus. Applied. New test included.
--
Pedro Alves
2010-11-09 Pedro Alves <pedro@codesourcery.com>
gdb/
* breakpoint.c (watch_command_1): Get a pointer of the lazy
version of the expression's value, even if reading the value from
memory fails. When creating a -location watchpoint, get the
value's address from the lazy value pointer.
gdb/testsuite/
* gdb.base/watchpoint.exp: Test "watch -location" with an
innacessible location.
---
gdb/breakpoint.c | 6 +++---
gdb/testsuite/gdb.base/watchpoint.exp | 5 +++++
2 files changed, 8 insertions(+), 3 deletions(-)
Index: src/gdb/breakpoint.c
===================================================================
--- src.orig/gdb/breakpoint.c 2010-10-16 01:01:59.000000000 +0100
+++ src/gdb/breakpoint.c 2010-11-09 17:25:12.000000000 +0000
@@ -8022,7 +8022,7 @@ watch_command_1 (char *arg, int accessfl
struct breakpoint *b, *scope_breakpoint = NULL;
struct expression *exp;
struct block *exp_valid_block = NULL, *cond_exp_valid_block = NULL;
- struct value *val, *mark;
+ struct value *val, *mark, *result;
struct frame_info *frame;
char *exp_start = NULL;
char *exp_end = NULL;
@@ -8121,12 +8121,12 @@ watch_command_1 (char *arg, int accessfl
exp_valid_block = innermost_block;
mark = value_mark ();
- fetch_subexp_value (exp, &pc, &val, NULL, NULL);
+ fetch_subexp_value (exp, &pc, &val, &result, NULL);
if (just_location)
{
exp_valid_block = NULL;
- val = value_addr (val);
+ val = value_addr (result);
release_value (val);
value_free_to_mark (mark);
}
Index: src/gdb/testsuite/gdb.base/watchpoint.exp
===================================================================
--- src.orig/gdb/testsuite/gdb.base/watchpoint.exp 2010-11-09 16:20:40.000000000 +0000
+++ src/gdb/testsuite/gdb.base/watchpoint.exp 2010-11-09 16:23:55.000000000 +0000
@@ -683,6 +683,11 @@ proc test_inaccessible_watchpoint {} {
"$watchpoint_msg \[0-9\]+: \\*\\(int \\*\\) 0"
delete_breakpoints
+ # The same, but using -location through an indirection.
+ gdb_test "watch -location *global_ptr" \
+ "$watchpoint_msg \[0-9\]+: \-location: \\*global_ptr"
+ delete_breakpoints
+
# This step requires two HW watchpoints. Since PPC Server only has
# a single one, it will use a SW watchpoint in this case.
if [istarget powerpc64-*] {