This is the mail archive of the gdb-patches@sourceware.org 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]
Other format: [Raw text]

RFC: MI - Detecting change of string contents with variable objects


This post follows on from a thread earlier this month on the GDB mailing list
called "memory address ranges (-var-create)"

Currently variable objects treat strings as pointers so -var-update only
detects a change of address or, if the child is created, when the first
character changes.  The patch below detects when the contents change which is
more useful.  I've only tested it for C, but I guess it could work for other
languages that variable objects handle (C++, Java).  The function
value_get_value gets both the address and string value but it's probably better
to just get the string value directly.

-- 
Nick                                           http://www.inet.net.nz/~nickrob


*** varobj.c	11 Dec 2006 08:13:03 +1300	1.65
--- varobj.c	18 Dec 2006 15:06:23 +1300	
*************** struct varobj
*** 101,106 ****
--- 101,107 ----
    /* The type of this variable. This may NEVER be NULL. */
    struct type *type;
  
+ 
    /* The value of this expression or subexpression.  This may be NULL. 
       Invariant: if type_changeable (this) is non-zero, the value is either
       NULL, or not lazy.  */
*************** struct varobj
*** 126,131 ****
--- 127,135 ----
  
    /* Was this variable updated via a varobj_set_value operation */
    int updated;
+ 
+   /* Last string value, if appropriate */
+   char *string_value;
  };
  
  /* Every variable keeps a linked list of its children, described
*************** static int variable_editable (struct var
*** 233,238 ****
--- 237,244 ----
  
  static char *my_value_of_variable (struct varobj *var);
  
+ static char *value_get_value (struct value* value);
+ 
  static int type_changeable (struct varobj *var);
  
  /* C implementation */
*************** install_new_value (struct varobj *var, s
*** 983,1003 ****
  	      
  	      if (!value_contents_equal (var->value, value))
  		changed = 1;
  	    }
  	}
      }
!     
    /* We must always keep the new value, since children depend on it.  */
    if (var->value != NULL)
      value_free (var->value);
    var->value = value;
    var->updated = 0;
!   
    gdb_assert (!var->value || value_type (var->value));
  
    return changed;
  }
-   
  
  /* Update the values for a variable and its children.  This is a
     two-pronged attack.  First, re-parse the value for the root's
--- 989,1025 ----
  	      
  	      if (!value_contents_equal (var->value, value))
  		changed = 1;
+ 
+ 	      if (variable_language (var) == vlang_c &&
+ 		  !strcmp (varobj_get_type (var), "char *"))
+ 		{
+ 		  if (var->string_value)
+ 		    {
+ 		      if (strcmp (var->string_value, value_get_value (value)))
+ 			{
+ 			  free (var->string_value);
+ 			  var->string_value =
+ 			    xstrdup (value_get_value (value));
+ 			  changed = 1;
+ 			}
+ 		    }
+ 		  else
+ 		    var->string_value = xstrdup (value_get_value (value));
+ 		}
  	    }
  	}
      }
! 
    /* We must always keep the new value, since children depend on it.  */
    if (var->value != NULL)
      value_free (var->value);
    var->value = value;
    var->updated = 0;
! 
    gdb_assert (!var->value || value_type (var->value));
  
    return changed;
  }
  
  /* Update the values for a variable and its children.  This is a
     two-pronged attack.  First, re-parse the value for the root's
*************** new_variable (void)
*** 1470,1475 ****
--- 1492,1498 ----
    var->format = 0;
    var->root = NULL;
    var->updated = 0;
+   var->string_value = NULL;
  
    return var;
  }
*************** my_value_of_variable (struct varobj *var
*** 1785,1790 ****
--- 1808,1827 ----
    return (*var->root->lang->value_of_variable) (var);
  }
  
+ static char *
+ value_get_value (struct value* value)
+ {
+   long dummy;
+   struct ui_file *stb = mem_fileopen ();
+   struct cleanup *old_chain = make_cleanup_ui_file_delete (stb);
+   char *thevalue;
+ 	    
+   common_val_print (value, stb, 0, 1, 0, 0);
+   thevalue = ui_file_xstrdup (stb, &dummy);
+   do_cleanups (old_chain);
+   return thevalue;
+ }
+ 
  /* Return non-zero if changes in value of VAR
     must be detected and reported by -var-update.
     Return zero is -var-update should never report


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