diff options
author | Tom Tromey <tromey@redhat.com> | 2013-08-02 16:41:08 +0000 |
---|---|---|
committer | Tom Tromey <tromey@redhat.com> | 2013-08-02 16:41:08 +0000 |
commit | 3a1115a0cc0a0a98555ba99df76ad9bcfee08759 (patch) | |
tree | 7bd5d53c3fa5d8723edfa7193d43c3ec43f9d932 /gdb | |
parent | 58b19776a6713e101fb71fab79ea70fa9af19e3a (diff) | |
download | gdb-3a1115a0cc0a0a98555ba99df76ad9bcfee08759.zip gdb-3a1115a0cc0a0a98555ba99df76ad9bcfee08759.tar.gz gdb-3a1115a0cc0a0a98555ba99df76ad9bcfee08759.tar.bz2 |
fix PR symtab/15719
This patch fixes PR symtab/15719.
The bug is that "watch -location" crashes on a certain expression.
The problem is that fetch_subexp_value is catching an exception.
For ordinary watchpoints this is ok; but for location watchpoints,
it is better for the exception to propagate.
Built and regtested on x86-64 Fedora 18.
New test case included.
PR symtab/15719:
* breakpoint.c (update_watchpoint, watchpoint_check)
(watch_command_1): Update.
* eval.c (fetch_subexp_value): Add "preserve_errors"
parameter.
* ppc-linux-nat.c (check_condition): Update.
* value.h (fetch_subexp_value): Update.
* gdb.base/watchpoint.c (struct foo5): New.
(nullptr): New global.
* gdb.base/watchpoint.exp (test_watch_location): Add test.
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 10 | ||||
-rw-r--r-- | gdb/breakpoint.c | 6 | ||||
-rw-r--r-- | gdb/eval.c | 18 | ||||
-rw-r--r-- | gdb/ppc-linux-nat.c | 4 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/watchpoint.c | 7 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/watchpoint.exp | 3 | ||||
-rw-r--r-- | gdb/value.h | 3 |
8 files changed, 44 insertions, 13 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 4e39273..af34dec 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,13 @@ +2013-08-02 Tom Tromey <tromey@redhat.com> + + PR symtab/15719: + * breakpoint.c (update_watchpoint, watchpoint_check) + (watch_command_1): Update. + * eval.c (fetch_subexp_value): Add "preserve_errors" + parameter. + * ppc-linux-nat.c (check_condition): Update. + * value.h (fetch_subexp_value): Update. + 2013-08-02 Andrew Burgess <aburgess@broadcom.com> * mi/mi-interp.c (mi_interpreter_resume): Remove call to diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 1e89407..eec7b7c 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -1807,7 +1807,7 @@ update_watchpoint (struct watchpoint *b, int reparse) struct value *val_chain, *v, *result, *next; struct program_space *frame_pspace; - fetch_subexp_value (b->exp, &pc, &v, &result, &val_chain); + fetch_subexp_value (b->exp, &pc, &v, &result, &val_chain, 0); /* Avoid setting b->val if it's already set. The meaning of b->val is 'the last value' user saw, and we should update @@ -4822,7 +4822,7 @@ watchpoint_check (void *p) return WP_VALUE_CHANGED; mark = value_mark (); - fetch_subexp_value (b->exp, &pc, &new_val, NULL, NULL); + fetch_subexp_value (b->exp, &pc, &new_val, NULL, NULL, 0); /* We use value_equal_contents instead of value_equal because the latter coerces an array to a pointer, thus comparing just @@ -11010,7 +11010,7 @@ watch_command_1 (const char *arg, int accessflag, int from_tty, exp_valid_block = innermost_block; mark = value_mark (); - fetch_subexp_value (exp, &pc, &val, &result, NULL); + fetch_subexp_value (exp, &pc, &val, &result, NULL, just_location); if (just_location) { @@ -171,10 +171,12 @@ evaluate_subexpression_type (struct expression *exp, int subexp) in *VAL_CHAIN. RESULTP and VAL_CHAIN may be NULL if the caller does not need them. - If a memory error occurs while evaluating the expression, *RESULTP will - be set to NULL. *RESULTP may be a lazy value, if the result could - not be read from memory. It is used to determine whether a value - is user-specified (we should watch the whole value) or intermediate + If PRESERVE_ERRORS is true, then exceptions are passed through. + Otherwise, if PRESERVE_ERRORS is false, then if a memory error + occurs while evaluating the expression, *RESULTP will be set to + NULL. *RESULTP may be a lazy value, if the result could not be + read from memory. It is used to determine whether a value is + user-specified (we should watch the whole value) or intermediate (we should watch only the bit used to locate the final value). If the final value, or any intermediate value, could not be read @@ -189,7 +191,8 @@ evaluate_subexpression_type (struct expression *exp, int subexp) void fetch_subexp_value (struct expression *exp, int *pc, struct value **valp, - struct value **resultp, struct value **val_chain) + struct value **resultp, struct value **val_chain, + int preserve_errors) { struct value *mark, *new_mark, *result; volatile struct gdb_exception ex; @@ -210,13 +213,14 @@ fetch_subexp_value (struct expression *exp, int *pc, struct value **valp, } if (ex.reason < 0) { - /* Ignore memory errors, we want watchpoints pointing at + /* Ignore memory errors if we want watchpoints pointing at inaccessible memory to still be created; otherwise, throw the error to some higher catcher. */ switch (ex.error) { case MEMORY_ERROR: - break; + if (!preserve_errors) + break; default: throw_exception (ex); break; diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c index 1f3f080..c518f77 100644 --- a/gdb/ppc-linux-nat.c +++ b/gdb/ppc-linux-nat.c @@ -1952,7 +1952,7 @@ check_condition (CORE_ADDR watch_addr, struct expression *cond, if (cond->elts[0].opcode != BINOP_EQUAL) return 0; - fetch_subexp_value (cond, &pc, &left_val, NULL, &left_chain); + fetch_subexp_value (cond, &pc, &left_val, NULL, &left_chain, 0); num_accesses_left = num_memory_accesses (left_chain); if (left_val == NULL || num_accesses_left < 0) @@ -1962,7 +1962,7 @@ check_condition (CORE_ADDR watch_addr, struct expression *cond, return 0; } - fetch_subexp_value (cond, &pc, &right_val, NULL, &right_chain); + fetch_subexp_value (cond, &pc, &right_val, NULL, &right_chain, 0); num_accesses_right = num_memory_accesses (right_chain); if (right_val == NULL || num_accesses_right < 0) diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 25a1b01..6ae1f5b 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2013-08-02 Tom Tromey <tromey@redhat.com> + + * gdb.base/watchpoint.c (struct foo5): New. + (nullptr): New global. + * gdb.base/watchpoint.exp (test_watch_location): Add test. + 2013-08-01 Doug Evans <dje@google.com> PR symtab/15691 diff --git a/gdb/testsuite/gdb.base/watchpoint.c b/gdb/testsuite/gdb.base/watchpoint.c index e887f99..92fb3b1 100644 --- a/gdb/testsuite/gdb.base/watchpoint.c +++ b/gdb/testsuite/gdb.base/watchpoint.c @@ -54,6 +54,13 @@ struct foo4 }; struct foo4 foo4; +struct foo5 +{ + struct { int x; } *p; +}; + +struct foo5 *nullptr; + void marker1 () { } diff --git a/gdb/testsuite/gdb.base/watchpoint.exp b/gdb/testsuite/gdb.base/watchpoint.exp index e0f7adc..e0d4f81 100644 --- a/gdb/testsuite/gdb.base/watchpoint.exp +++ b/gdb/testsuite/gdb.base/watchpoint.exp @@ -603,6 +603,9 @@ proc test_watch_location {} { gdb_breakpoint [gdb_get_line_number "func5 breakpoint here"] gdb_continue_to_breakpoint "func5 breakpoint here" + gdb_test "watch -location nullptr->p->x" \ + "Cannot access memory at address 0x0" + gdb_test "watch -location *x" "atchpoint .*: .*" "watch -location .x" gdb_test "continue" \ diff --git a/gdb/value.h b/gdb/value.h index 5e00c89..599850e 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -728,7 +728,8 @@ extern struct value *evaluate_subexpression_type (struct expression *exp, extern void fetch_subexp_value (struct expression *exp, int *pc, struct value **valp, struct value **resultp, - struct value **val_chain); + struct value **val_chain, + int preserve_errors); extern char *extract_field_op (struct expression *exp, int *subexp); |