This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Fix frozen variable objects laziness
- From: Vladimir Prus <vladimir at codesourcery dot com>
- To: gdb-patches at sources dot redhat dot com
- Date: Thu, 27 Sep 2007 22:05:22 +0400
- Subject: Fix frozen variable objects laziness
I've just noticed that gdb mainline has grown some
subtle bugs in the handling of frozen variable objects.
1. The install_new_value always calls value_get_print_value,
which fetches the value. It means that it's not possible
to have read-sensitive variable object that are read only
on user request.
2. In the case where a value for variable object is not
yet fetched, and we -var-update it, we enter install_new_value
and go via this path:
if (initial && changeable)
...
else if (changeable)
{
if (var->updated)
{
.....
}
else
{
if (var->not_fetched && value_lazy (var->value))
{
/* This is a frozen varobj and the value was never read.
Presumably, UI shows some "never read" indicator.
Now that we've fetched the real value, we need to report
this varobj as changed so that UI can show the real
value. */
changed = 1;
}
And the var->print_value is never updated.
The attached patch, fixes that by:
1. Updating var->print_value in a single place at the end of
install_new_value.
2. Not getting print_value at all for lazy value.
The attached patch fixes that. Approved by Daniel Jacobowitz and
checked in.
- Volodya
Index: ChangeLog
===================================================================
RCS file: /cvs/src/src/gdb/ChangeLog,v
retrieving revision 1.8719
diff -u -p -r1.8719 ChangeLog
--- ChangeLog 26 Sep 2007 18:44:55 -0000 1.8719
+++ ChangeLog 27 Sep 2007 18:03:03 -0000
@@ -1,5 +1,12 @@
2007-09-26 Vladimir Prus <vladimir@codesourcery.com>
+ * varobj.c (install_new_value): Don't
+ call value_get_print_value when a value is
+ lazy. Update the print_value member in a
+ single place.
+
+2007-09-26 Vladimir Prus <vladimir@codesourcery.com>
+
* breakpoint.c (create_breakpoint): Set
condition on each location, not on the first
location of breakpoint.
Index: varobj.c
===================================================================
RCS file: /cvs/src/src/gdb/varobj.c,v
retrieving revision 1.95
diff -u -p -r1.95 varobj.c
--- varobj.c 31 Aug 2007 19:01:17 -0000 1.95
+++ varobj.c 27 Sep 2007 18:03:04 -0000
@@ -985,6 +985,7 @@ install_new_value (struct varobj *var, s
int need_to_fetch;
int changed = 0;
int intentionally_not_fetched = 0;
+ char *print_value = NULL;
/* We need to know the varobj's type to decide if the value should
be fetched or not. C++ fake children (public/protected/private) don't have
@@ -1042,12 +1043,17 @@ install_new_value (struct varobj *var, s
}
}
+ /* Below, we'll be comparing string rendering of old and new
+ values. Don't get string rendering if the value is
+ lazy -- if it is, the code above has decided that the value
+ should not be fetched. */
+ if (value && !value_lazy (value))
+ print_value = value_get_print_value (value, var->format);
+
/* If the type is changeable, compare the old and the new values.
If this is the initial assignment, we don't have any old value
to compare with. */
- if (initial && changeable)
- var->print_value = value_get_print_value (value, var->format);
- else if (changeable)
+ if (!initial && changeable)
{
/* If the value of the varobj was changed by -var-set-value, then the
value in the varobj and in the target is the same. However, that value
@@ -1055,8 +1061,6 @@ install_new_value (struct varobj *var, s
-var-update. So need to the varobj as changed. */
if (var->updated)
{
- xfree (var->print_value);
- var->print_value = value_get_print_value (value, var->format);
changed = 1;
}
else
@@ -1077,26 +1081,16 @@ install_new_value (struct varobj *var, s
;
else if (var->value == NULL || value == NULL)
{
- xfree (var->print_value);
- var->print_value = value_get_print_value (value, var->format);
changed = 1;
}
else
{
- char *print_value;
gdb_assert (!value_lazy (var->value));
gdb_assert (!value_lazy (value));
- print_value = value_get_print_value (value, var->format);
gdb_assert (var->print_value != NULL && print_value != NULL);
if (strcmp (var->print_value, print_value) != 0)
- {
- xfree (var->print_value);
- var->print_value = print_value;
- changed = 1;
- }
- else
- xfree (print_value);
+ changed = 1;
}
}
}
@@ -1105,6 +1099,9 @@ install_new_value (struct varobj *var, s
if (var->value != NULL && var->value != value)
value_free (var->value);
var->value = value;
+ if (var->print_value)
+ xfree (var->print_value);
+ var->print_value = print_value;
if (value && value_lazy (value) && intentionally_not_fetched)
var->not_fetched = 1;
else