From a4c8e8068824062a43759f22ff0d22efe8996b82 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Thu, 31 Mar 2011 19:59:26 +0000 Subject: [PATCH] gdb * varobj.c (update_dynamic_varobj_children): Properly handle errors from iterator. gdb/testsuite * gdb.python/py-prettyprint.py (exception_flag): New global. (NoStringContainerPrinter._iterator.next): Check it. * gdb.python/py-prettyprint.c (main): New variable nstype2. * gdb.python/py-mi.exp: Set exception_flag and do more tests. --- gdb/ChangeLog | 5 +++ gdb/testsuite/ChangeLog | 7 +++ gdb/testsuite/gdb.python/py-mi.exp | 9 ++++ gdb/testsuite/gdb.python/py-prettyprint.c | 4 +- gdb/testsuite/gdb.python/py-prettyprint.py | 5 +++ gdb/varobj.c | 52 +++++++++++++++++++++- 6 files changed, 79 insertions(+), 3 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 2476919b65..8469059302 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2011-03-31 Tom Tromey + + * varobj.c (update_dynamic_varobj_children): Properly handle + errors from iterator. + 2011-03-31 Jan Kratochvil * dwarf2read.c (dwarf2_name): Initialize DEMANGLED. Avoid demangling diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 6cc74449a7..58f2a21f9a 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2011-03-31 Tom Tromey + + * gdb.python/py-prettyprint.py (exception_flag): New global. + (NoStringContainerPrinter._iterator.next): Check it. + * gdb.python/py-prettyprint.c (main): New variable nstype2. + * gdb.python/py-mi.exp: Set exception_flag and do more tests. + 2011-03-29 Tom Tromey * gdb.cp/anon-struct.cc: New file. diff --git a/gdb/testsuite/gdb.python/py-mi.exp b/gdb/testsuite/gdb.python/py-mi.exp index 02763f106b..629417b5dd 100644 --- a/gdb/testsuite/gdb.python/py-mi.exp +++ b/gdb/testsuite/gdb.python/py-mi.exp @@ -274,4 +274,13 @@ mi_gdb_test "-var-set-visualizer nscont gdb.default_visualizer" \ "\\^done" \ "choose default visualizer" +mi_gdb_test "python exception_flag = True" "" + +mi_create_dynamic_varobj nstype2 nstype2 \ + "create nstype2 varobj" + +mi_list_varobj_children nstype2 { + { {nstype2.} {} 6 {char \[6\]} } +} "list children after setting exception flag" + remote_file host delete ${remote_python_file} diff --git a/gdb/testsuite/gdb.python/py-prettyprint.c b/gdb/testsuite/gdb.python/py-prettyprint.c index 35c7500ed3..5f984338c3 100644 --- a/gdb/testsuite/gdb.python/py-prettyprint.c +++ b/gdb/testsuite/gdb.python/py-prettyprint.c @@ -212,7 +212,7 @@ main () const struct string_repr cstring = { { "const string" } }; /* Clearing by being `static' could invoke an other GDB C++ bug. */ struct nullstr nullstr; - nostring_type nstype; + nostring_type nstype, nstype2; struct ns ns, ns2; struct lazystring estring, estring2; @@ -283,5 +283,7 @@ main () nstype.elements[1] = 42; nstype.len = 2; + nstype2 = nstype; + return 0; /* break to inspect struct and union */ } diff --git a/gdb/testsuite/gdb.python/py-prettyprint.py b/gdb/testsuite/gdb.python/py-prettyprint.py index 873039a5bb..831a16373d 100644 --- a/gdb/testsuite/gdb.python/py-prettyprint.py +++ b/gdb/testsuite/gdb.python/py-prettyprint.py @@ -53,6 +53,9 @@ class ContainerPrinter: def children(self): return self._iterator(self.val['elements'], self.val['len']) +# Flag to make NoStringContainerPrinter throw an exception. +exception_flag = False + # Test a printer where to_string is None class NoStringContainerPrinter: class _iterator: @@ -67,6 +70,8 @@ class NoStringContainerPrinter: def next(self): if self.pointer == self.end: raise StopIteration + if exception_flag: + raise gdb.MemoryError, 'hi bob' result = self.pointer self.pointer = self.pointer + 1 return ('[%d]' % int (result - self.start), result.dereference()) diff --git a/gdb/varobj.c b/gdb/varobj.c index 124909a2ab..bfb3851d75 100644 --- a/gdb/varobj.c +++ b/gdb/varobj.c @@ -1026,6 +1026,7 @@ update_dynamic_varobj_children (struct varobj *var, for (; to < 0 || i < to + 1; ++i) { PyObject *item; + int force_done = 0; /* See if there was a leftover from last time. */ if (var->saved_item) @@ -1037,7 +1038,48 @@ update_dynamic_varobj_children (struct varobj *var, item = PyIter_Next (var->child_iter); if (!item) - break; + { + /* Normal end of iteration. */ + if (!PyErr_Occurred ()) + break; + + /* If we got a memory error, just use the text as the + item. */ + if (PyErr_ExceptionMatches (gdbpy_gdb_memory_error)) + { + PyObject *type, *value, *trace; + char *name_str, *value_str; + + PyErr_Fetch (&type, &value, &trace); + value_str = gdbpy_exception_to_string (type, value); + Py_XDECREF (type); + Py_XDECREF (value); + Py_XDECREF (trace); + if (!value_str) + { + gdbpy_print_stack (); + break; + } + + name_str = xstrprintf ("", i); + item = Py_BuildValue ("(ss)", name_str, value_str); + xfree (name_str); + xfree (value_str); + if (!item) + { + gdbpy_print_stack (); + break; + } + + force_done = 1; + } + else + { + /* Any other kind of error. */ + gdbpy_print_stack (); + break; + } + } /* We don't want to push the extra child on any report list. */ if (to < 0 || i < to) @@ -1051,7 +1093,10 @@ update_dynamic_varobj_children (struct varobj *var, inner = make_cleanup_py_decref (item); if (!PyArg_ParseTuple (item, "sO", &name, &py_v)) - error (_("Invalid item from the child list")); + { + gdbpy_print_stack (); + error (_("Invalid item from the child list")); + } v = convert_value_from_python (py_v); if (v == NULL) @@ -1071,6 +1116,9 @@ update_dynamic_varobj_children (struct varobj *var, element. */ break; } + + if (force_done) + break; } if (i < VEC_length (varobj_p, var->children))