535451a
2008-07-10  Jan Kratochvil  <jan.kratochvil@redhat.com>
dd1aa7b
535451a
	* breakpoint.c (fetch_watchpoint_value): New comment on unreachable
535451a
	values.
535451a
	(watch_command_1): New variable VAL_CHAIN.  Refuse constant watchpoints.
535451a
	* gdbtypes.h (TYPE_CODE_FUNC): New comment regarding pointers to it.
dd1aa7b
535451a
2008-07-10  Jan Kratochvil  <jan.kratochvil@redhat.com>
dd1aa7b
dd1aa7b
	* gdb.texinfo (Set Watchpoints): Document constant value watchpoints.
dd1aa7b
535451a
2008-07-10  Jan Kratochvil  <jan.kratochvil@redhat.com>
dd1aa7b
535451a
	* gdb.base/watchpoint.exp: Call TEST_CONSTANT_WATCHPOINT.
535451a
	(test_constant_watchpoint): New function.
535451a
	(test_inaccessible_watchpoint): Cleanup (delete) the watchpoint.
535451a
	Test also a double-indirection watchpoint.
535451a
	gdb.base/watchpoint.c (global_ptr_ptr): New variable.
535451a
	(func4): New testing code for GLOBAL_PTR_PTR.
dd1aa7b
8b1b3fd
Index: gdb-6.8/gdb/breakpoint.c
8b1b3fd
===================================================================
8b1b3fd
--- gdb-6.8.orig/gdb/breakpoint.c	2008-07-14 10:28:30.000000000 +0200
8b1b3fd
+++ gdb-6.8/gdb/breakpoint.c	2008-07-14 10:28:36.000000000 +0200
8b1b3fd
@@ -846,7 +846,15 @@ is_hardware_watchpoint (struct breakpoin
535451a
    If VAL_CHAIN is non-NULL, *VAL_CHAIN will be released from the
535451a
    value chain.  The caller must free the values individually.  If
535451a
    VAL_CHAIN is NULL, all generated values will be left on the value
535451a
-   chain.  */
535451a
+   chain.
535451a
+   
535451a
+   Inferior unreachable values return:
535451a
+   Inferior `int *intp = NULL;' with `watch *intp':
535451a
+     *VALP is NULL, *RESULTP contains lazy LVAL_MEMORY address 0, *VAL_CHAIN
535451a
+     contains the *RESULTP element and also INTP as LVAL_MEMORY.
535451a
+   Inferior `int **intpp = NULL;' with `watch **intpp':
535451a
+     *VALP is NULL, *RESULTP is NULL, *VAL_CHAIN contains lazy LVAL_MEMORY
535451a
+     address 0 and also INTPP as LVAL_MEMORY.  */
535451a
 
535451a
 static void
535451a
 fetch_watchpoint_value (struct expression *exp, struct value **valp,
8b1b3fd
@@ -5705,7 +5713,7 @@ watch_command_1 (char *arg, int accessfl
dd1aa7b
   struct symtab_and_line sal;
dd1aa7b
   struct expression *exp;
dd1aa7b
   struct block *exp_valid_block;
dd1aa7b
-  struct value *val, *mark;
535451a
+  struct value *val, *mark, *val_chain;
dd1aa7b
   struct frame_info *frame;
dd1aa7b
   struct frame_info *prev_frame = NULL;
dd1aa7b
   char *exp_start = NULL;
8b1b3fd
@@ -5791,6 +5799,27 @@ watch_command_1 (char *arg, int accessfl
dd1aa7b
   exp_valid_block = innermost_block;
dd1aa7b
   mark = value_mark ();
535451a
   fetch_watchpoint_value (exp, &val, NULL, NULL);
dd1aa7b
+
535451a
+  /* VALUE_MARK gets us the same value as FETCH_WATCHPOINT_VALUE's VAL_CHAIN
535451a
+     parameter.  Just this way we do not have to VALUE_FREE the chained VALUEs
535451a
+     ourselves.  */
535451a
+  for (val_chain = value_mark ();
535451a
+       val_chain != mark;
535451a
+       val_chain = value_next (val_chain))
535451a
+    if ((VALUE_LVAL (val_chain) == lval_memory
535451a
+	 && TYPE_CODE (value_type (val_chain)) != TYPE_CODE_FUNC)
535451a
+	|| VALUE_LVAL (val_chain) == lval_register)
535451a
+      break;
535451a
+  if (val_chain == mark)
dd1aa7b
+    {
dd1aa7b
+      int len;
dd1aa7b
+      
dd1aa7b
+      len = exp_end - exp_start;
dd1aa7b
+      while (len > 0 && isspace (exp_start[len - 1]))
dd1aa7b
+	len--;
dd1aa7b
+      error (_("Cannot watch constant value %.*s."), len, exp_start);
dd1aa7b
+    }
535451a
+  /* Break the values chain only after its check above.  */
dd1aa7b
   if (val != NULL)
dd1aa7b
     release_value (val);
dd1aa7b
 
8b1b3fd
Index: gdb-6.8/gdb/gdbtypes.h
8b1b3fd
===================================================================
8b1b3fd
--- gdb-6.8.orig/gdb/gdbtypes.h	2008-07-14 10:28:30.000000000 +0200
8b1b3fd
+++ gdb-6.8/gdb/gdbtypes.h	2008-07-14 10:28:36.000000000 +0200
535451a
@@ -69,7 +69,22 @@ enum type_code
535451a
     TYPE_CODE_UNION,		/* C union or Pascal variant part */
535451a
     TYPE_CODE_ENUM,		/* Enumeration type */
535451a
     TYPE_CODE_FLAGS,		/* Bit flags type */
535451a
-    TYPE_CODE_FUNC,		/* Function type */
535451a
+
535451a
+    /* Function type.  It is not a pointer to a function.  Function reference
535451a
+       by its name (such as `printf') has this type.  C automatically converts
535451a
+       this function type to a pointer to function for any operation except
535451a
+       `sizeof (function_type)' or `&function_type' (unary &).
535451a
+       `sizeof (function_type)' is undefined in C.  But GCC provides extension
535451a
+       (info '(gcc)Pointer Arith') defining its size as 1 byte.  DWARF does not
535451a
+       define its size but GDB defines the size the GCC compatible way - GDB
535451a
+       function MAKE_FUNCTION_TYPE.  The address itself is not modifiable.
535451a
+       As the function type has size 1 but its real value has `sizeof
535451a
+       (CORE_ADDR)' we cannot use NOT_LVAL category because the address would
535451a
+       not fit in the VALUE_CONTENTS_RAW container of its VALUE.  We use
535451a
+       LVAL_MEMORY (and its VALUE_ADDRESS field) for it but we must be careful
535451a
+       it is not lvalue, it is the only non-modifiable LVAL_MEMORY.  */
535451a
+    TYPE_CODE_FUNC,
535451a
+
535451a
     TYPE_CODE_INT,		/* Integer type */
535451a
 
535451a
     /* Floating type.  This is *NOT* a complex type.  Beware, there are parts
8b1b3fd
Index: gdb-6.8/gdb/doc/gdb.texinfo
8b1b3fd
===================================================================
8b1b3fd
--- gdb-6.8.orig/gdb/doc/gdb.texinfo	2008-07-14 10:28:29.000000000 +0200
8b1b3fd
+++ gdb-6.8/gdb/doc/gdb.texinfo	2008-07-14 10:28:36.000000000 +0200
8b1b3fd
@@ -3267,6 +3267,18 @@ This command prints a list of watchpoint
dd1aa7b
 it is the same as @code{info break} (@pxref{Set Breaks}).
dd1aa7b
 @end table
dd1aa7b
 
dd1aa7b
+If you watch for a change in a numerically entered address you need to
dd1aa7b
+dereference it as the address itself is just a constant number which will never
535451a
+change.  @value{GDBN} refuses to create a watchpoint that watches
535451a
+a never-changing value:
dd1aa7b
+
dd1aa7b
+@smallexample
dd1aa7b
+(@value{GDBP}) watch 0x600850
dd1aa7b
+Cannot watch constant value 0x600850.
dd1aa7b
+(@value{GDBP}) watch *(int *) 0x600850
dd1aa7b
+Watchpoint 1: *(int *) 6293584
dd1aa7b
+@end smallexample
dd1aa7b
+
dd1aa7b
 @value{GDBN} sets a @dfn{hardware watchpoint} if possible.  Hardware
dd1aa7b
 watchpoints execute very quickly, and the debugger reports a change in
dd1aa7b
 value at the exact instruction where the change occurs.  If @value{GDBN}
8b1b3fd
Index: gdb-6.8/gdb/testsuite/gdb.base/watchpoint.c
8b1b3fd
===================================================================
8b1b3fd
--- gdb-6.8.orig/gdb/testsuite/gdb.base/watchpoint.c	2008-07-14 10:28:30.000000000 +0200
8b1b3fd
+++ gdb-6.8/gdb/testsuite/gdb.base/watchpoint.c	2008-07-14 10:28:36.000000000 +0200
535451a
@@ -40,6 +40,7 @@ struct foo struct1, struct2, *ptr1, *ptr
535451a
 int doread = 0;
535451a
 
535451a
 char *global_ptr;
535451a
+char **global_ptr_ptr;
dd1aa7b
 
535451a
 void marker1 ()
535451a
 {
535451a
@@ -118,6 +119,10 @@ func4 ()
535451a
   buf[0] = 3;
535451a
   global_ptr = buf;
535451a
   buf[0] = 7;
535451a
+  buf[1] = 5;
535451a
+  global_ptr_ptr = &global_ptr;
535451a
+  buf[0] = 9;
535451a
+  global_ptr++;
535451a
 }
535451a
 
535451a
 int main ()
8b1b3fd
Index: gdb-6.8/gdb/testsuite/gdb.base/watchpoint.exp
8b1b3fd
===================================================================
8b1b3fd
--- gdb-6.8.orig/gdb/testsuite/gdb.base/watchpoint.exp	2008-07-14 10:28:30.000000000 +0200
8b1b3fd
+++ gdb-6.8/gdb/testsuite/gdb.base/watchpoint.exp	2008-07-14 10:28:36.000000000 +0200
535451a
@@ -644,7 +644,21 @@ proc test_watchpoint_and_breakpoint {} {
535451a
 	}
535451a
     }
535451a
 }
535451a
-    
535451a
+
535451a
+proc test_constant_watchpoint {} {
535451a
+    global gdb_prompt
535451a
+
535451a
+	gdb_test "watch 5" "Cannot watch constant value 5." "number is constant"
535451a
+	gdb_test "watch marker1" "Cannot watch constant value marker1." \
535451a
+		 "marker1 is constant"
535451a
+	gdb_test "watch count + 6" ".*atchpoint \[0-9\]+: count \\+ 6"
535451a
+	gdb_test "set \$expr_breakpoint_number = \$bpnum" ""
535451a
+	gdb_test "delete \$expr_breakpoint_number" ""
535451a
+	gdb_test "watch 7 + count" ".*atchpoint \[0-9\]+: 7 \\+ count"
535451a
+	gdb_test "set \$expr_breakpoint_number = \$bpnum" ""
535451a
+	gdb_test "delete \$expr_breakpoint_number" ""
535451a
+}
535451a
+
535451a
 proc test_inaccessible_watchpoint {} {
535451a
     global gdb_prompt
535451a
 
535451a
@@ -653,7 +667,8 @@ proc test_inaccessible_watchpoint {} {
535451a
 
535451a
     if [runto func4] then {
535451a
 	gdb_test "watch *global_ptr" ".*atchpoint \[0-9\]+: \\*global_ptr"
535451a
-	gdb_test "next" ".*global_ptr = buf.*"
535451a
+	gdb_test "set \$global_ptr_breakpoint_number = \$bpnum" ""
535451a
+	gdb_test "next" ".*global_ptr = buf.*" "global_ptr next"
535451a
 	gdb_test_multiple "next" "next over ptr init" {
535451a
 	    -re ".*atchpoint \[0-9\]+: \\*global_ptr\r\n\r\nOld value = .*\r\nNew value = 3 .*\r\n.*$gdb_prompt $" {
535451a
 		# We can not test for <unknown> here because NULL may be readable.
535451a
@@ -666,6 +681,28 @@ proc test_inaccessible_watchpoint {} {
535451a
 		pass "next over buffer set"
535451a
 	    }
535451a
 	}
535451a
+	gdb_test "delete \$global_ptr_breakpoint_number" ""
535451a
+	gdb_test "watch **global_ptr_ptr" ".*atchpoint \[0-9\]+: \\*\\*global_ptr_ptr"
535451a
+	gdb_test "set \$global_ptr_ptr_breakpoint_number = \$bpnum" ""
535451a
+	gdb_test "next" ".*global_ptr_ptr = &global_ptr.*" "gloabl_ptr_ptr next"
535451a
+	gdb_test_multiple "next" "next over global_ptr_ptr init" {
535451a
+	    -re ".*atchpoint \[0-9\]+: \\*\\*global_ptr_ptr\r\n\r\nOld value = .*\r\nNew value = 7 .*\r\n.*$gdb_prompt $" {
535451a
+		# We can not test for <unknown> here because NULL may be readable.
535451a
+		# This test does rely on *NULL != 7.
535451a
+		pass "next over global_ptr_ptr init"
535451a
+	    }
535451a
+	}
535451a
+	gdb_test_multiple "next" "next over global_ptr_ptr buffer set" {
535451a
+	    -re ".*atchpoint \[0-9\]+: \\*\\*global_ptr_ptr\r\n\r\nOld value = 7 .*\r\nNew value = 9 .*\r\n.*$gdb_prompt $" {
535451a
+		pass "next over global_ptr_ptr buffer set"
535451a
+	    }
535451a
+	}
535451a
+	gdb_test_multiple "next" "next over global_ptr_ptr pointer advance" {
535451a
+	    -re ".*atchpoint \[0-9\]+: \\*\\*global_ptr_ptr\r\n\r\nOld value = 9 .*\r\nNew value = 5 .*\r\n.*$gdb_prompt $" {
535451a
+		pass "next over global_ptr_ptr pointer advance"
535451a
+	    }
535451a
+	}
535451a
+	gdb_test "delete \$global_ptr_ptr_breakpoint_number" ""
535451a
     }
535451a
 }
8b1b3fd
 
8b1b3fd
@@ -834,6 +871,17 @@ if [initialize] then {
535451a
     }
535451a
 
535451a
     test_watchpoint_and_breakpoint
535451a
+
535451a
+    # See above.
535451a
+    if [istarget "mips-idt-*"] then {
535451a
+	gdb_exit
535451a
+	gdb_start
535451a
+	gdb_reinitialize_dir $srcdir/$subdir
535451a
+	gdb_load $binfile
535451a
+	initialize
535451a
+    }
dd1aa7b
+
535451a
+    test_constant_watchpoint
535451a
 }
dd1aa7b
 
535451a
 # Restore old timeout