RFC: fix PR 14386
Tom Tromey
tromey@redhat.com
Wed Aug 1 18:11:00 GMT 2012
This fixes PR python/14386.
I'd like to commit this to the trunk and the 7.5 branch; the latter
because it is a reasonably obvious, low-risk, and useful bug fix.
The bug here is that a certain libstdc++ pretty-printer doesn't work in
MI.
What is going on is that the printer in question returns a Python list
object from its 'children' method. This is perfectly fine. However,
the varobj code uses PyIter_Check on the returned object, and this
evaluates to false for a list.
I think this is arguably a bug in Python, so I filed:
http://bugs.python.org/issue15529
Meanwhile, it seems safest not to call PyIter_Check. We certainly don't
need to -- the CLI doesn't -- because we can just call PyObject_GetIter
and react appropriately if that fails.
Built and tested on x86-64 Fedora 16.
New test case included.
Tom
commit 4074f681d23d3ee12c92bbe128e55f9e0d5a142e
Author: Tom Tromey <tromey@redhat.com>
Date: Wed Aug 1 10:30:11 2012 -0600
fix PR python/14386
PR python/14386:
* varobj.c (update_dynamic_varobj_children): Don't call
PyIter_Check.
* gdb.python/py-mi.exp: Add test for printer whose children
are a list.
* gdb.python/py-prettyprint.c (struct children_as_list): New.
(main): New variable children_as_list.
* gdb.python/py-prettyprint.py (class pp_children_as_list):
New.
(register_pretty_printers): Register new printer.
diff --git a/gdb/testsuite/gdb.python/py-mi.exp b/gdb/testsuite/gdb.python/py-mi.exp
index a792e44..e7034a1 100644
--- a/gdb/testsuite/gdb.python/py-mi.exp
+++ b/gdb/testsuite/gdb.python/py-mi.exp
@@ -289,6 +289,10 @@ mi_gdb_test "-var-evaluate-expression me" \
"\\^done,value=\"<error reading variable: Cannot access memory.>.*\"" \
"evaluate me varobj"
+# Regression test for python/14836.
+mi_create_dynamic_varobj children_as_list children_as_list \
+ "printer whose children are returned as a list"
+
# C++ MI tests
gdb_exit
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}-cxx" \
diff --git a/gdb/testsuite/gdb.python/py-prettyprint.c b/gdb/testsuite/gdb.python/py-prettyprint.c
index 1ff9e05..b1a12b1 100644
--- a/gdb/testsuite/gdb.python/py-prettyprint.c
+++ b/gdb/testsuite/gdb.python/py-prettyprint.c
@@ -48,6 +48,10 @@ struct hint_error {
int x;
};
+struct children_as_list {
+ int x;
+};
+
#ifdef __cplusplus
struct S : public s {
int zs;
@@ -252,6 +256,7 @@ main ()
struct ns ns, ns2;
struct lazystring estring, estring2;
struct hint_error hint_error;
+ struct children_as_list children_as_list;
nstype.elements = narray;
nstype.len = 0;
diff --git a/gdb/testsuite/gdb.python/py-prettyprint.py b/gdb/testsuite/gdb.python/py-prettyprint.py
index b02b90f..6e960e6 100644
--- a/gdb/testsuite/gdb.python/py-prettyprint.py
+++ b/gdb/testsuite/gdb.python/py-prettyprint.py
@@ -174,6 +174,18 @@ class pp_hint_error:
def display_hint (self):
raise Exception("hint failed")
+class pp_children_as_list:
+ "Throw error from display_hint"
+
+ def __init__(self, val):
+ self.val = val
+
+ def to_string(self):
+ return 'children_as_list_val'
+
+ def children (self):
+ return [('one', 1)]
+
class pp_outer:
"Print struct outer"
@@ -282,6 +294,9 @@ def register_pretty_printers ():
pretty_printers_dict[re.compile ('^struct hint_error$')] = pp_hint_error
pretty_printers_dict[re.compile ('^hint_error$')] = pp_hint_error
+ pretty_printers_dict[re.compile ('^struct children_as_list$')] = pp_children_as_list
+ pretty_printers_dict[re.compile ('^children_as_list$')] = pp_children_as_list
+
pretty_printers_dict[re.compile ('^memory_error$')] = MemoryErrorString
pretty_printers_dict[re.compile ('^eval_type_s$')] = pp_eval_type
diff --git a/gdb/varobj.c b/gdb/varobj.c
index a75a40d..71b6436 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -1114,9 +1114,6 @@ update_dynamic_varobj_children (struct varobj *var,
make_cleanup_py_decref (children);
- if (!PyIter_Check (children))
- error (_("Returned value is not iterable"));
-
Py_XDECREF (var->child_iter);
var->child_iter = PyObject_GetIter (children);
if (!var->child_iter)
More information about the Gdb-patches
mailing list