PR varobj/28131 points out a crash in the varobj deletion code. It
took a while to reproduce this, but essentially what happens is that a
top-level varobj deletes its root object, then deletes the "dynamic"
object. However, deletion of the dynamic object may cause
~py_varobj_iter to run, which in turn uses gdbpy_enter_varobj:
gdbpy_enter_varobj::gdbpy_enter_varobj (const struct varobj *var)
: gdbpy_enter (var->root->exp->gdbarch, var->root->exp->language_defn)
{
}
However, because var->root has already been destroyed, this is
invalid.
I've added a new test case. This doesn't reliably crash, but the
problem can easily be seen under valgrind (and, I presume, with ASAN,
though I did not try this).
Tested on x86-64 Fedora 32. I also propose putting this on the GDB 11
branch, with a suitable ChangeLog entry of course.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28131
(cherry picked from commit
4d0754c5f572b01cf2fe6c8ab292adba83331cbc)
gdb/ChangeLog
2021-08-02 Tom Tromey <tromey@adacore.com>
PR varobj/28131
* varobj.c (~varobj): Delete 'dynamic' before 'root'.
gdb/testsuite/ChangeLog
2021-08-02 Tom Tromey <tromey@adacore.com>
PR varobj/28131
* gdb.python/py-mi-var-info-path-expression.exp: Add regression
test.
+2021-08-02 Tom Tromey <tromey@adacore.com>
+
+ PR varobj/28131
+ * varobj.c (~varobj): Delete 'dynamic' before 'root'.
+
2021-08-02 Shahab Vahedi <shahab@synopsys.com>
PR gdb/28104
+2021-08-02 Tom Tromey <tromey@adacore.com>
+
+ PR varobj/28131
+ * gdb.python/py-mi-var-info-path-expression.exp: Add regression
+ test.
+
2021-07-26 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
PR gdb/28076
mi_gdb_test "-var-info-path-expression c1.car.atom.ival" \
"\\^error,msg=\".*\"" \
"-var-info-path-expression c1.car.atom.ival"
+
+
+# Regression test for a crasher that would occur when deleting a
+# varobj that held an iterator that hadn't yet been completed.
+# See PR varobj/28131.
+mi_gdb_test "-var-create c1_again * &c1" \
+ "\\^done.*" \
+ "-var-create c1_again * &c1"
+mi_gdb_test "-var-list-children c1_again 0 1" \
+ "\\^done,numchild=\"1\",children=.child=\{name=\"c1_again.car\".*" \
+ "-var-list-children c1_again"
+mi_delete_varobj c1_again "delete c1_again"
}
#endif
+ /* This must be deleted before the root object, because Python-based
+ destructors need access to some components. */
+ delete var->dynamic;
+
if (is_root_p (var))
delete var->root;
-
- delete var->dynamic;
}
/* Return the type of the value that's stored in VAR,