mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-12-12 14:37:43 +00: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>
|
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
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
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
|
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;
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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 ()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -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" \
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user