mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 12:03:41 +08:00
Avoid crash in varobj deletion
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
This commit is contained in:
parent
c894449a79
commit
4d0754c5f5
@ -85,3 +85,15 @@ mi_gdb_test "-var-list-children c1.car.atom" \
|
||||
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"
|
||||
|
@ -1844,10 +1844,12 @@ varobj::~varobj ()
|
||||
}
|
||||
#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,
|
||||
|
Loading…
Reference in New Issue
Block a user