gdb/
authorThiago Jung Bauermann <bauerman@br.ibm.com>
Wed, 30 Dec 2009 17:33:35 +0000 (17:33 +0000)
committerThiago Jung Bauermann <bauerman@br.ibm.com>
Wed, 30 Dec 2009 17:33:35 +0000 (17:33 +0000)
* 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.

gdb/testsuite/
* 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.

gdb/ChangeLog
gdb/breakpoint.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/watchpoint.c
gdb/testsuite/gdb.base/watchpoint.exp
gdb/valarith.c
gdb/value.h

index 5c9586be6998312f96d2400d3634a21e3fa277ec..b6a5034e2fd03b0d4e308d7329903923ae497627 100644 (file)
@@ -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.
index f041e647c0d199f4e3218ca67580f907e4460aba..5c605422a5f340965fd80e8c49aa6d251395847b 100644 (file)
@@ -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)
            {
index 13da3d3136a6d86a3304c579f887286cee987332..33aee0831c31d2742a005dd8de99f1812e895800 100644 (file)
@@ -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.
index bba97fad99de867bd981a6437cb50c035752ebb9..9275d88d929fbe1613c28e14d9f4d2b4ba140aeb 100644 (file)
@@ -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
index 9fee73b6c38235d9aeacbc8878d572c3b81afe28..ff11a4f7eda25da32f18d5f9c44506799e8e9569 100644 (file)
@@ -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
index a9c875d907a1956887c02025754195551fcaf3f2..2b5d116e4935dd0bec669c33365f24b9a7752dc8 100644 (file)
@@ -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.  */
 
index 993f05bd050b26388e4578dae860b9bfe4552b64..c0acccd2232868213c11ec6c0ca48dbc4f141ae5 100644 (file)
@@ -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);