This is the mail archive of the gdb-patches@sourceware.cygnus.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Watching complex expressions patch



  I think that the approach of VALUE_LAZY for the watchpoint is completely
wrong !

  I propose here a patch that completely change the mecanism of which
memory must be 
watched :

   if you have a struct  t { int a,b,c;}
and you set a watch to t.c
you only want to get stopped if t.c changes not if t.a or t.b changes
but currently using the VALUE_LAZY seems to be quite unsure 
  On  go32 target,
the code wanted to watch first t.c and then this entire t struct and that
is wrong of course !

  So my mecanism remembers the last memory that has been set a watch 
and after reject all watches of bigger memory regions including that memory !

  For more complex watch, with intermediate value that can change
like if p is a pointer to the above struct t
   watch p->c
  will the watch both current location of t.c (if p is set to &t)
and location of p as it is not inside the memory region of t.c itself !
(Even if you imagine that you have complicated case where the same memory is 
fetched several times it still should work correctly !)


Index: breakpoint.c
===================================================================
RCS file: /cvs/gdb/gdb/gdb/breakpoint.c,v
retrieving revision 1.1.1.16
diff -b -c -r1.1.1.16 breakpoint.c
*** breakpoint.c	1999/11/02 04:44:13	1.1.1.16
--- breakpoint.c	1999/11/04 10:30:09
***************
*** 951,956 ****
--- 951,959 ----
  
  	if (within_current_scope)
  	  {
+          CORE_ADDR last_lval_address = 0;
+          int last_lval_size = 0;
+          int last_type = 0;
  	    /* Evaluate the expression and cut the chain of values
  	       produced off from the value chain.
  
***************
*** 967,977 ****
  	    /* Look at each value on the value chain.  */
  	    for (; v; v = v->next)
  	      {
! 		/* If it's a memory location, and GDB actually needed
!                    its contents to evaluate the expression, then we
!                    must watch it.  */
! 		if (VALUE_LVAL (v) == lval_memory
! 		    && ! VALUE_LAZY (v))
  		  {
  		    CORE_ADDR addr;
  		    int len, type;
--- 970,982 ----
  	    /* Look at each value on the value chain.  */
  	    for (; v; v = v->next)
  	      {
! 		  /* If it's a memory location, then we must watch it.  */
!         if ((VALUE_LVAL (v) == lval_memory) &&
!         /* Unless its a bigger part from a small part we want to
!            watch */
!             !((VALUE_ADDRESS (v) + VALUE_OFFSET (v) <= last_lval_address) &&
!               (VALUE_ADDRESS (v) + VALUE_OFFSET (v) + TYPE_LENGTH
(VALUE_TYPE (v))
!                 >= last_lval_address + last_lval_size)))
  		  {
  		    CORE_ADDR addr;
  		    int len, type;
***************
*** 983,988 ****
--- 988,997 ----
  		      type = hw_read;
  		    else if (b->type == bp_access_watchpoint)
  		      type = hw_access;
+           /* Non terminal are only important if
+              their value changes */
+           if (last_type)
+             type = hw_write;
  
  		    val = target_insert_watchpoint (addr, len, type);
  		    if (val == -1)
***************
*** 991,996 ****
--- 1000,1008 ----
  			break;
  		      }
  		    val = 0;
+           last_lval_size = len;
+           last_lval_address = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
+           last_type = type;
  		  }
  	      }
  	    /* Failure to insert a watchpoint on any memory value in the
***************
*** 1309,1323 ****
  	   && !b->duplicate)
      {
        value_ptr v, n;
  
        b->inserted = (is == mark_inserted);
        /* Walk down the saved value chain.  */
        for (v = b->val_chain; v; v = v->next)
  	{
  	  /* For each memory reference remove the watchpoint
  	     at that address.  */
! 	  if (VALUE_LVAL (v) == lval_memory
! 	      && ! VALUE_LAZY (v))
  	    {
  	      CORE_ADDR addr;
  	      int len, type;
--- 1321,1352 ----
  	   && !b->duplicate)
      {
        value_ptr v, n;
+       CORE_ADDR last_lval_address = 0;
+       int last_lval_size = 0;
+       int last_type = 0;
  
        b->inserted = (is == mark_inserted);
        /* Walk down the saved value chain.  */
        for (v = b->val_chain; v; v = v->next)
  	{
  	  /* For each memory reference remove the watchpoint
+ 	     at that address.  */
+ 		  /* If it's a memory location, then we must watch it.  */
+         if ((VALUE_LVAL (v) == lval_memory) &&
+         /* Unless its a bigger part from a small part we want to
+            watch */
+             !((VALUE_ADDRESS (v) + VALUE_OFFSET (v) <= last_lval_address) &&
+               (VALUE_ADDRESS (v) + VALUE_OFFSET (v) + TYPE_LENGTH
(VALUE_TYPE (v))
+                 >= last_lval_address + last_lval_size)))
+ 	  /* For each memory reference remove the watchpoint
  	     at that address.  */
! 		  /* If it's a memory location, then we must watch it.  */
!         if ((VALUE_LVAL (v) == lval_memory) &&
!         /* Unless its a bigger part from a small part we want to
!            watch */
!             !((VALUE_ADDRESS (v) + VALUE_OFFSET (v) <= last_lval_address) &&
!               (VALUE_ADDRESS (v) + VALUE_OFFSET (v) + TYPE_LENGTH
(VALUE_TYPE (v))
!                 >= last_lval_address + last_lval_size)))
  	    {
  	      CORE_ADDR addr;
  	      int len, type;
***************
*** 1329,1339 ****
--- 1358,1373 ----
  		type = hw_read;
  	      else if (b->type == bp_access_watchpoint)
  		type = hw_access;
+          if (last_type)
+            type = hw_write;
  
  	      val = target_remove_watchpoint (addr, len, type);
  	      if (val == -1)
  		b->inserted = 1;
  	      val = 0;
+          last_lval_size = len;
+          last_lval_address = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
+          last_type = type;
  	    }
  	}
        /* Failure to remove any of the hardware watchpoints comes here.  */




Pierre Muller
Institut Charles Sadron
6,rue Boussingault
F 67083 STRASBOURG CEDEX (France)
mailto:muller@ics.u-strasbg.fr
Phone : (33)-3-88-41-40-07  Fax : (33)-3-88-41-40-99

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]