summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog7
-rw-r--r--gdb/breakpoint.c8
-rw-r--r--gdb/testsuite/ChangeLog8
-rw-r--r--gdb/testsuite/gdb.base/watchpoint.c3
-rw-r--r--gdb/testsuite/gdb.base/watchpoint.exp9
-rw-r--r--gdb/valarith.c18
-rw-r--r--gdb/value.h2
7 files changed, 52 insertions, 3 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 5c9586be699..b6a5034e2fd 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,10 @@
+2009-12-30 Thiago Jung Bauermann <bauerman@br.ibm.com>
+
+ * valarith.c (value_equal_contents): New function.
+ * value.h (value_equal_contents): Declare.
+ * breakpoint.c (watchpoint_check): Use value_equal_contents
+ instead of value_equal.
+
2009-12-30 Stan Shebs <stan@codesourcery.com>
Add default-collect variable.
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index f041e647c0d..5c605422a5f 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -3174,7 +3174,7 @@ watchpoints_triggered (struct target_waitstatus *ws)
#define BP_TEMPFLAG 1
#define BP_HARDWAREFLAG 2
-/* Check watchpoint condition. */
+/* Evaluate watchpoint condition expression and check if its value changed. */
static int
watchpoint_check (void *p)
@@ -3245,8 +3245,12 @@ watchpoint_check (void *p)
struct value *new_val;
fetch_watchpoint_value (b->exp, &new_val, NULL, NULL);
+
+ /* We use value_equal_contents instead of value_equal because the latter
+ coerces an array to a pointer, thus comparing just the address of the
+ array instead of its contents. This is not what we want. */
if ((b->val != NULL) != (new_val != NULL)
- || (b->val != NULL && !value_equal (b->val, new_val)))
+ || (b->val != NULL && !value_equal_contents (b->val, new_val)))
{
if (new_val != NULL)
{
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 13da3d3136a..33aee0831c3 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,11 @@
+2009-12-30 Thiago Jung Bauermann <bauerman@br.ibm.com>
+
+ * gdb.base/watchpoint.exp (test_watchpoint_in_big_blob): New function.
+ (top level): Call test_watchpoint_in_big_blob.
+ * gdb.base/watchpoint.c (buf): Change size to value too big for hardware
+ watchpoints.
+ (func3): Write to buf.
+
2009-12-29 Stan Shebs <stan@codesourcery.com>
* gdb.trace/actions.exp: Test default-collect.
diff --git a/gdb/testsuite/gdb.base/watchpoint.c b/gdb/testsuite/gdb.base/watchpoint.c
index bba97fad99d..9275d88d929 100644
--- a/gdb/testsuite/gdb.base/watchpoint.c
+++ b/gdb/testsuite/gdb.base/watchpoint.c
@@ -30,7 +30,7 @@ int ival2 = -1;
int ival3 = -1;
int ival4 = -1;
int ival5 = -1;
-char buf[10];
+char buf[30] = "testtesttesttesttesttesttestte";
struct foo
{
int val;
@@ -95,6 +95,7 @@ func3 ()
x = 1; /* second x assignment */
y = 1;
y = 2;
+ buf[26] = 3;
}
int
diff --git a/gdb/testsuite/gdb.base/watchpoint.exp b/gdb/testsuite/gdb.base/watchpoint.exp
index 9fee73b6c38..ff11a4f7eda 100644
--- a/gdb/testsuite/gdb.base/watchpoint.exp
+++ b/gdb/testsuite/gdb.base/watchpoint.exp
@@ -678,6 +678,13 @@ proc test_inaccessible_watchpoint {} {
}
}
+proc test_watchpoint_in_big_blob {} {
+ global gdb_prompt
+
+ gdb_test "watch buf" ".*atchpoint \[0-9\]+: buf"
+ gdb_test "cont" "Continuing.*atchpoint \[0-9\]+: buf\r\n\r\nOld value = .*testte\".*" "watchpoint on buf hit"
+}
+
# Start with a fresh gdb.
gdb_exit
@@ -842,6 +849,8 @@ if [initialize] then {
}
test_watchpoint_and_breakpoint
+
+ test_watchpoint_in_big_blob
}
# Restore old timeout
diff --git a/gdb/valarith.c b/gdb/valarith.c
index a9c875d907a..2b5d116e493 100644
--- a/gdb/valarith.c
+++ b/gdb/valarith.c
@@ -1397,6 +1397,24 @@ value_equal (struct value *arg1, struct value *arg2)
}
}
+/* Compare values based on their raw contents. Useful for arrays since
+ value_equal coerces them to pointers, thus comparing just the address
+ of the array instead of its contents. */
+
+int
+value_equal_contents (struct value *arg1, struct value *arg2)
+{
+ struct type *type1, *type2;
+
+ type1 = check_typedef (value_type (arg1));
+ type2 = check_typedef (value_type (arg2));
+
+ return (TYPE_CODE (type1) == TYPE_CODE (type2)
+ && TYPE_LENGTH (type1) == TYPE_LENGTH (type2)
+ && memcmp (value_contents (arg1), value_contents (arg2),
+ TYPE_LENGTH (type1)) == 0);
+}
+
/* Simulate the C operator < by returning 1
iff ARG1's contents are less than ARG2's. */
diff --git a/gdb/value.h b/gdb/value.h
index 993f05bd050..c0acccd2232 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -563,6 +563,8 @@ extern struct internalvar *lookup_internalvar (const char *name);
extern int value_equal (struct value *arg1, struct value *arg2);
+extern int value_equal_contents (struct value *arg1, struct value *arg2);
+
extern int value_less (struct value *arg1, struct value *arg2);
extern int value_logical_not (struct value *arg1);