This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
RFC: MI - Detecting change of string contents with variable objects
- From: Nick Roberts <nickrob at snap dot net dot nz>
- To: gdb-patches at sources dot redhat dot com
- Date: Mon, 18 Dec 2006 15:37:40 +1300
- Subject: 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