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:
Tom Tromey 2013-08-02 16:41:08 +00:00
parent 58b19776a6
commit 3a1115a0cc
8 changed files with 44 additions and 13 deletions

View File

@ -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> 2013-08-02 Andrew Burgess <aburgess@broadcom.com>
* mi/mi-interp.c (mi_interpreter_resume): Remove call to * mi/mi-interp.c (mi_interpreter_resume): Remove call to

View File

@ -1807,7 +1807,7 @@ update_watchpoint (struct watchpoint *b, int reparse)
struct value *val_chain, *v, *result, *next; struct value *val_chain, *v, *result, *next;
struct program_space *frame_pspace; 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 /* Avoid setting b->val if it's already set. The meaning of
b->val is 'the last value' user saw, and we should update b->val is 'the last value' user saw, and we should update
@ -4822,7 +4822,7 @@ watchpoint_check (void *p)
return WP_VALUE_CHANGED; return WP_VALUE_CHANGED;
mark = value_mark (); 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 /* We use value_equal_contents instead of value_equal because
the latter coerces an array to a pointer, thus comparing just 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; exp_valid_block = innermost_block;
mark = value_mark (); mark = value_mark ();
fetch_subexp_value (exp, &pc, &val, &result, NULL); fetch_subexp_value (exp, &pc, &val, &result, NULL, just_location);
if (just_location) if (just_location)
{ {

View File

@ -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 in *VAL_CHAIN. RESULTP and VAL_CHAIN may be NULL if the caller does
not need them. not need them.
If a memory error occurs while evaluating the expression, *RESULTP will If PRESERVE_ERRORS is true, then exceptions are passed through.
be set to NULL. *RESULTP may be a lazy value, if the result could Otherwise, if PRESERVE_ERRORS is false, then if a memory error
not be read from memory. It is used to determine whether a value occurs while evaluating the expression, *RESULTP will be set to
is user-specified (we should watch the whole value) or intermediate 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). (we should watch only the bit used to locate the final value).
If the final value, or any intermediate value, could not be read 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 void
fetch_subexp_value (struct expression *exp, int *pc, struct value **valp, 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; struct value *mark, *new_mark, *result;
volatile struct gdb_exception ex; volatile struct gdb_exception ex;
@ -210,13 +213,14 @@ fetch_subexp_value (struct expression *exp, int *pc, struct value **valp,
} }
if (ex.reason < 0) 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 inaccessible memory to still be created; otherwise, throw the
error to some higher catcher. */ error to some higher catcher. */
switch (ex.error) switch (ex.error)
{ {
case MEMORY_ERROR: case MEMORY_ERROR:
break; if (!preserve_errors)
break;
default: default:
throw_exception (ex); throw_exception (ex);
break; break;

View File

@ -1952,7 +1952,7 @@ check_condition (CORE_ADDR watch_addr, struct expression *cond,
if (cond->elts[0].opcode != BINOP_EQUAL) if (cond->elts[0].opcode != BINOP_EQUAL)
return 0; 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); num_accesses_left = num_memory_accesses (left_chain);
if (left_val == NULL || num_accesses_left < 0) if (left_val == NULL || num_accesses_left < 0)
@ -1962,7 +1962,7 @@ check_condition (CORE_ADDR watch_addr, struct expression *cond,
return 0; 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); num_accesses_right = num_memory_accesses (right_chain);
if (right_val == NULL || num_accesses_right < 0) if (right_val == NULL || num_accesses_right < 0)

View File

@ -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> 2013-08-01 Doug Evans <dje@google.com>
PR symtab/15691 PR symtab/15691

View File

@ -54,6 +54,13 @@ struct foo4
}; };
struct foo4 foo4; struct foo4 foo4;
struct foo5
{
struct { int x; } *p;
};
struct foo5 *nullptr;
void marker1 () void marker1 ()
{ {
} }

View File

@ -603,6 +603,9 @@ proc test_watch_location {} {
gdb_breakpoint [gdb_get_line_number "func5 breakpoint here"] gdb_breakpoint [gdb_get_line_number "func5 breakpoint here"]
gdb_continue_to_breakpoint "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 "watch -location *x" "atchpoint .*: .*" "watch -location .x"
gdb_test "continue" \ gdb_test "continue" \

View File

@ -728,7 +728,8 @@ extern struct value *evaluate_subexpression_type (struct expression *exp,
extern void fetch_subexp_value (struct expression *exp, int *pc, extern void fetch_subexp_value (struct expression *exp, int *pc,
struct value **valp, struct value **resultp, 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); extern char *extract_field_op (struct expression *exp, int *subexp);