From 2e70b7b9621d412ac2a8ed58f9476a521a01508a Mon Sep 17 00:00:00 2001 From: Michael Snyder Date: Tue, 21 Mar 2000 01:27:34 +0000 Subject: 2000-03-20 Eli Zaretskii * breakpoint.c (insert_breakpoints, remove_breakpoint) (bpstat_stop_status, can_use_hardware_watchpoint): Don't insert, remove, or check status of hardware watchpoints for entire structs and arrays unless the user explicitly asked to watch that struct or array. (insert_breakpoints): Try to insert watchpoints for all the values on the value chain, even if some of them fail to insert. * values.c (value_primitive_field): Set the offset in struct value we return when the field is a packed bitfield. --- gdb/ChangeLog | 13 ++++++ gdb/breakpoint.c | 130 ++++++++++++++++++++++++++++++++++++------------------- gdb/values.c | 2 + 3 files changed, 100 insertions(+), 45 deletions(-) (limited to 'gdb') diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 18f51a9..2d12618 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,16 @@ +2000-03-20 Eli Zaretskii + + * breakpoint.c (insert_breakpoints, remove_breakpoint) + (bpstat_stop_status, can_use_hardware_watchpoint): Don't insert, + remove, or check status of hardware watchpoints for entire structs + and arrays unless the user explicitly asked to watch that struct + or array. + (insert_breakpoints): Try to insert watchpoints for all the values + on the value chain, even if some of them fail to insert. + + * values.c (value_primitive_field): Set the offset in struct value + we return when the field is a packed bitfield. + 2000-03-20 Michael Snyder * remote.c (remote_threads_extra_info): new function. diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 2ad3a78..b77a404 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -973,24 +973,39 @@ insert_breakpoints () if (VALUE_LVAL (v) == lval_memory && ! VALUE_LAZY (v)) { - CORE_ADDR addr; - int len, type; - - addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v); - len = TYPE_LENGTH (VALUE_TYPE (v)); - type = hw_write; - if (b->type == bp_read_watchpoint) - type = hw_read; - else if (b->type == bp_access_watchpoint) - type = hw_access; - - val = target_insert_watchpoint (addr, len, type); - if (val == -1) + struct type *vtype = check_typedef (VALUE_TYPE (v)); + + /* We only watch structs and arrays if user asked + for it explicitly, never if they just happen to + appear in the middle of some value chain. */ + if (v == b->val_chain + || (TYPE_CODE (vtype) != TYPE_CODE_STRUCT + && TYPE_CODE (vtype) != TYPE_CODE_ARRAY)) { - b->inserted = 0; - break; + CORE_ADDR addr; + int len, type; + + addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v); + len = TYPE_LENGTH (VALUE_TYPE (v)); + type = hw_write; + if (b->type == bp_read_watchpoint) + type = hw_read; + else if (b->type == bp_access_watchpoint) + type = hw_access; + + val = target_insert_watchpoint (addr, len, type); + if (val == -1) + { + /* Don't exit the loop, try to insert + every value on the value chain. That's + because we will be removing all the + watches below, and removing a + watchpoint we didn't insert could have + adverse effects. */ + b->inserted = 0; + } + val = 0; } - val = 0; } } /* Failure to insert a watchpoint on any memory value in the @@ -1326,21 +1341,28 @@ remove_breakpoint (b, is) if (VALUE_LVAL (v) == lval_memory && ! VALUE_LAZY (v)) { - CORE_ADDR addr; - int len, type; - - addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v); - len = TYPE_LENGTH (VALUE_TYPE (v)); - type = hw_write; - if (b->type == bp_read_watchpoint) - type = hw_read; - else if (b->type == bp_access_watchpoint) - type = hw_access; - - val = target_remove_watchpoint (addr, len, type); - if (val == -1) - b->inserted = 1; - val = 0; + struct type *vtype = check_typedef (VALUE_TYPE (v)); + + if (v == b->val_chain + || (TYPE_CODE (vtype) != TYPE_CODE_STRUCT + && TYPE_CODE (vtype) != TYPE_CODE_ARRAY)) + { + CORE_ADDR addr; + int len, type; + + addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v); + len = TYPE_LENGTH (VALUE_TYPE (v)); + type = hw_write; + if (b->type == bp_read_watchpoint) + type = hw_read; + else if (b->type == bp_access_watchpoint) + type = hw_access; + + val = target_remove_watchpoint (addr, len, type); + if (val == -1) + b->inserted = 1; + val = 0; + } } } /* Failure to remove any of the hardware watchpoints comes here. */ @@ -2570,14 +2592,21 @@ bpstat_stop_status (pc, not_a_breakpoint) if (VALUE_LVAL (v) == lval_memory && ! VALUE_LAZY (v)) { - CORE_ADDR vaddr; - - vaddr = VALUE_ADDRESS (v) + VALUE_OFFSET (v); - /* Exact match not required. Within range is sufficient. - */ - if (addr >= vaddr && - addr < vaddr + TYPE_LENGTH (VALUE_TYPE (v))) - found = 1; + struct type *vtype = check_typedef (VALUE_TYPE (v)); + + if (v == b->val_chain + || (TYPE_CODE (vtype) != TYPE_CODE_STRUCT + && TYPE_CODE (vtype) != TYPE_CODE_ARRAY)) + { + CORE_ADDR vaddr; + + vaddr = VALUE_ADDRESS (v) + VALUE_OFFSET (v); + /* Exact match not required. Within range is + sufficient. */ + if (addr >= vaddr && + addr < vaddr + TYPE_LENGTH (VALUE_TYPE (v))) + found = 1; + } } } if (found) @@ -5514,6 +5543,7 @@ can_use_hardware_watchpoint (v) struct value *v; { int found_memory_cnt = 0; + struct value *head = v; /* Did the user specifically forbid us to use hardware watchpoints? */ if (!can_use_hw_watchpoints) @@ -5551,13 +5581,23 @@ can_use_hardware_watchpoint (v) { /* Ahh, memory we actually used! Check if we can cover it with hardware watchpoints. */ - CORE_ADDR vaddr = VALUE_ADDRESS (v) + VALUE_OFFSET (v); - int len = TYPE_LENGTH (VALUE_TYPE (v)); + struct type *vtype = check_typedef (VALUE_TYPE (v)); + + /* We only watch structs and arrays if user asked for it + explicitly, never if they just happen to appear in a + middle of some value chain. */ + if (v == head + || (TYPE_CODE (vtype) != TYPE_CODE_STRUCT + && TYPE_CODE (vtype) != TYPE_CODE_ARRAY)) + { + CORE_ADDR vaddr = VALUE_ADDRESS (v) + VALUE_OFFSET (v); + int len = TYPE_LENGTH (VALUE_TYPE (v)); - if (!TARGET_REGION_OK_FOR_HW_WATCHPOINT (vaddr, len)) - return 0; - else - found_memory_cnt++; + if (!TARGET_REGION_OK_FOR_HW_WATCHPOINT (vaddr, len)) + return 0; + else + found_memory_cnt++; + } } } else if (v->lval != not_lval && v->modifiable == 0) diff --git a/gdb/values.c b/gdb/values.c index 6f2642e..760d2f8 100644 --- a/gdb/values.c +++ b/gdb/values.c @@ -802,6 +802,8 @@ value_primitive_field (arg1, offset, fieldno, arg_type) fieldno)); VALUE_BITPOS (v) = TYPE_FIELD_BITPOS (arg_type, fieldno) % 8; VALUE_BITSIZE (v) = TYPE_FIELD_BITSIZE (arg_type, fieldno); + VALUE_OFFSET (v) = VALUE_OFFSET (arg1) + offset + + TYPE_FIELD_BITPOS (arg_type, fieldno) / 8; } else if (fieldno < TYPE_N_BASECLASSES (arg_type)) { -- cgit v1.1