aboutsummaryrefslogtreecommitdiff
path: root/gdb/breakpoint.c
diff options
context:
space:
mode:
authorMichael Snyder <msnyder@vmware.com>2000-03-21 01:27:34 +0000
committerMichael Snyder <msnyder@vmware.com>2000-03-21 01:27:34 +0000
commit2e70b7b9621d412ac2a8ed58f9476a521a01508a (patch)
tree5087565b1d10b1ba596aed7478cf066a1456e29b /gdb/breakpoint.c
parent9d1f7ab2c8992e290f1821a8ebd9298df9d1d077 (diff)
downloadgdb-2e70b7b9621d412ac2a8ed58f9476a521a01508a.zip
gdb-2e70b7b9621d412ac2a8ed58f9476a521a01508a.tar.gz
gdb-2e70b7b9621d412ac2a8ed58f9476a521a01508a.tar.bz2
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.c130
1 files changed, 85 insertions, 45 deletions
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)