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.
+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
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
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
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)
{
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
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;
}
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;
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)
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)
+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
};
struct foo4 foo4;
+struct foo5
+{
+ struct { int x; } *p;
+};
+
+struct foo5 *nullptr;
+
void marker1 ()
{
}
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" \
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);