This is the mail archive of the
archer@sourceware.org
mailing list for the Archer project.
[python] fix PR 10615
- From: Tom Tromey <tromey at redhat dot com>
- To: Project Archer <archer at sourceware dot org>
- Date: Wed, 09 Sep 2009 10:00:49 -0600
- Subject: [python] fix PR 10615
- Reply-to: Tom Tromey <tromey at redhat dot com>
I'm checking this in on the python branch.
This fixes PR 10615, a bug where a change to a struct-valued child of a
dynamic varobj would not properly be reported by -var-update.
Tom
2009-09-09 Tom Tromey <tromey@redhat.com>
PR mi/10615:
* varobj.c (install_dynamic_child): Add 'unchanged' argument.
(update_dynamic_varobj_children): Likewise.
(varobj_get_num_children): Update.
(varobj_list_children): Update.
(varobj_update): Add unchanged children to update list.
2009-09-09 Tom Tromey <tromey@redhat.com>
* gdb.python/python-prettyprint.c (struct substruct): New type.
(struct outerstruct): Likewise.
(substruct_test): New function.
(main): Call it.
* gdb.python/python-mi.exp: Add regression tests.
* gdb.python/python-prettyprint.py (pp_outer): New class.
(register_pretty_printers): Update.
diff --git a/gdb/testsuite/gdb.python/python-mi.exp b/gdb/testsuite/gdb.python/python-mi.exp
index 7791775..0178270 100644
--- a/gdb/testsuite/gdb.python/python-mi.exp
+++ b/gdb/testsuite/gdb.python/python-mi.exp
@@ -192,6 +192,29 @@ mi_varobj_update_dynamic container \
}
mi_continue_to_line \
+ [gdb_get_line_number {MI outer breakpoint here} ${testfile}.c] \
+ "step to outer breakpoint"
+
+mi_create_dynamic_varobj outer outer \
+ "create outer varobj"
+
+mi_list_varobj_children outer {
+ { outer.s s 2 "struct substruct" }
+ { outer.x x 0 "int" }
+} "list children of outer"
+
+mi_list_varobj_children outer.s {
+ { outer.s.a a 0 int }
+ { outer.s.b b 0 int }
+} "list children of outer.s"
+
+mi_next "next over outer update"
+
+mi_gdb_test "-var-update outer" \
+ ".done,changelist=.{name=\"outer.s.a\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"}." \
+ "update after updating element of outer"
+
+mi_continue_to_line \
[gdb_get_line_number {Another MI breakpoint} ${testfile}.c] \
"step to second breakpoint"
diff --git a/gdb/testsuite/gdb.python/python-prettyprint.c b/gdb/testsuite/gdb.python/python-prettyprint.c
index adf66b5..bf41ebc 100644
--- a/gdb/testsuite/gdb.python/python-prettyprint.c
+++ b/gdb/testsuite/gdb.python/python-prettyprint.c
@@ -82,6 +82,29 @@ class Derived : public Vbase1, public Vbase2, public Vbase3
#endif
+struct substruct {
+ int a;
+ int b;
+};
+
+struct outerstruct {
+ struct substruct s;
+ int x;
+};
+
+struct outerstruct
+substruct_test (void)
+{
+ struct outerstruct outer;
+ outer.s.a = 0;
+ outer.s.b = 0;
+ outer.x = 0;
+
+ outer.s.a = 3; /* MI outer breakpoint here */
+
+ return outer;
+}
+
typedef struct string_repr
{
struct whybother
@@ -212,6 +235,8 @@ main ()
add_item (&c2, 2222);
add_item (&c2, 3333);
+
+ substruct_test ();
do_nothing ();
#endif
diff --git a/gdb/testsuite/gdb.python/python-prettyprint.py b/gdb/testsuite/gdb.python/python-prettyprint.py
index c3e0dc4..2f070d8 100644
--- a/gdb/testsuite/gdb.python/python-prettyprint.py
+++ b/gdb/testsuite/gdb.python/python-prettyprint.py
@@ -112,6 +112,19 @@ class pp_ns:
def display_hint (self):
return 'string'
+class pp_outer:
+ "Print struct outer"
+
+ def __init__ (self, val):
+ self.val = val
+
+ def to_string (self):
+ return "x = %s" % self.val['x']
+
+ def children (self):
+ yield 's', self.val['s']
+ yield 'x', self.val['x']
+
def lookup_function (val):
"Look-up and return a pretty-printer that can print val."
@@ -170,6 +183,10 @@ def register_pretty_printers ():
pretty_printers_dict[re.compile ('^struct ns$')] = pp_ns
pretty_printers_dict[re.compile ('^ns$')] = pp_ns
+
+ pretty_printers_dict[re.compile ('^struct outerstruct$')] = pp_outer
+ pretty_printers_dict[re.compile ('^outerstruct$')] = pp_outer
+
pretty_printers_dict = {}
register_pretty_printers ()
diff --git a/gdb/varobj.c b/gdb/varobj.c
index e1dec23..7dad226 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -899,6 +899,7 @@ static void
install_dynamic_child (struct varobj *var,
VEC (varobj_p) **changed,
VEC (varobj_p) **new,
+ VEC (varobj_p) **unchanged,
int *cchanged,
int index,
const char *name,
@@ -920,6 +921,8 @@ install_dynamic_child (struct varobj *var,
if (changed)
VEC_safe_push (varobj_p, *changed, existing);
}
+ else if (unchanged)
+ VEC_safe_push (varobj_p, *unchanged, existing);
}
}
@@ -944,6 +947,7 @@ static int
update_dynamic_varobj_children (struct varobj *var,
VEC (varobj_p) **changed,
VEC (varobj_p) **new,
+ VEC (varobj_p) **unchanged,
int *cchanged,
int update_children,
int to)
@@ -1027,7 +1031,7 @@ update_dynamic_varobj_children (struct varobj *var,
error (_("Invalid item from the child list"));
v = convert_value_from_python (py_v);
- install_dynamic_child (var, changed, new,
+ install_dynamic_child (var, changed, new, unchanged,
cchanged, i, name, v);
do_cleanups (inner);
}
@@ -1077,7 +1081,7 @@ varobj_get_num_children (struct varobj *var)
/* If we have a dynamic varobj, don't report -1 children.
So, try to fetch some children first. */
- update_dynamic_varobj_children (var, NULL, NULL, &dummy, 0, 0);
+ update_dynamic_varobj_children (var, NULL, NULL, NULL, &dummy, 0, 0);
}
else
var->num_children = number_of_children (var);
@@ -1103,7 +1107,7 @@ varobj_list_children (struct varobj *var, int *from, int *to)
/* This, in theory, can result in the number of children changing without
frontend noticing. But well, calling -var-list-children on the same
varobj twice is not something a sane frontend would do. */
- update_dynamic_varobj_children (var, NULL, NULL, &children_changed,
+ update_dynamic_varobj_children (var, NULL, NULL, NULL, &children_changed,
0, *to);
restrict_range (var->children, from, to);
return var->children;
@@ -1739,7 +1743,7 @@ VEC(varobj_update_result) *varobj_update (struct varobj **varp, int explicit)
invoked. */
if (v->pretty_printer)
{
- VEC (varobj_p) *changed = 0, *new = 0;
+ VEC (varobj_p) *changed = 0, *new = 0, *unchanged = 0;
int i, children_changed;
varobj_p tmp;
@@ -1758,7 +1762,8 @@ VEC(varobj_update_result) *varobj_update (struct varobj **varp, int explicit)
it. */
if (!varobj_has_more (v, 0))
{
- update_dynamic_varobj_children (v, NULL, NULL, &dummy, 0, 0);
+ update_dynamic_varobj_children (v, NULL, NULL, NULL,
+ &dummy, 0, 0);
if (varobj_has_more (v, 0))
r.changed = 1;
}
@@ -1771,7 +1776,7 @@ VEC(varobj_update_result) *varobj_update (struct varobj **varp, int explicit)
/* If update_dynamic_varobj_children returns 0, then we have
a non-conforming pretty-printer, so we skip it. */
- if (update_dynamic_varobj_children (v, &changed, &new,
+ if (update_dynamic_varobj_children (v, &changed, &new, &unchanged,
&children_changed, 1, v->to))
{
if (children_changed || new)
@@ -1786,12 +1791,22 @@ VEC(varobj_update_result) *varobj_update (struct varobj **varp, int explicit)
r.value_installed = 1;
VEC_safe_push (varobj_update_result, stack, &r);
}
+ for (i = 0; VEC_iterate (varobj_p, unchanged, i, tmp); ++i)
+ {
+ if (!tmp->frozen)
+ {
+ varobj_update_result r = {tmp};
+ r.value_installed = 1;
+ VEC_safe_push (varobj_update_result, stack, &r);
+ }
+ }
if (r.changed || r.children_changed)
VEC_safe_push (varobj_update_result, result, &r);
- /* Free CHANGED, but not NEW, because NEW has been put
- into the result vector. */
+ /* Free CHANGED and UNCHANGED, but not NEW, because NEW
+ has been put into the result vector. */
VEC_free (varobj_p, changed);
+ VEC_free (varobj_p, unchanged);
continue;
}