mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-23 18:14:13 +08:00
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.
This commit is contained in:
parent
58b19776a6
commit
3a1115a0cc
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
18
gdb/eval.c
18
gdb/eval.c
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -54,6 +54,13 @@ struct foo4
|
||||
};
|
||||
struct foo4 foo4;
|
||||
|
||||
struct foo5
|
||||
{
|
||||
struct { int x; } *p;
|
||||
};
|
||||
|
||||
struct foo5 *nullptr;
|
||||
|
||||
void marker1 ()
|
||||
{
|
||||
}
|
||||
|
@ -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" \
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user