diff options
author | Michael Snyder <msnyder@vmware.com> | 2000-03-21 01:27:34 +0000 |
---|---|---|
committer | Michael Snyder <msnyder@vmware.com> | 2000-03-21 01:27:34 +0000 |
commit | 2e70b7b9621d412ac2a8ed58f9476a521a01508a (patch) | |
tree | 5087565b1d10b1ba596aed7478cf066a1456e29b /gdb/breakpoint.c | |
parent | 2000-03-20 Michael Snyder <msnyder@cleaver.cygnus.com> (diff) | |
download | binutils-gdb-2e70b7b9621d412ac2a8ed58f9476a521a01508a.tar.gz binutils-gdb-2e70b7b9621d412ac2a8ed58f9476a521a01508a.tar.bz2 binutils-gdb-2e70b7b9621d412ac2a8ed58f9476a521a01508a.zip |
2000-03-20 Eli Zaretskii <eliz@is.elta.co.il>
* 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.
Diffstat (limited to 'gdb/breakpoint.c')
-rw-r--r-- | gdb/breakpoint.c | 130 |
1 files changed, 85 insertions, 45 deletions
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 2ad3a78a983..b77a404d1a1 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) |