Avoid crash in varobj deletion
authorTom Tromey <tromey@adacore.com>
Fri, 30 Jul 2021 17:18:36 +0000 (11:18 -0600)
committerTom Tromey <tromey@adacore.com>
Mon, 2 Aug 2021 15:48:58 +0000 (09:48 -0600)
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.

gdb/ChangeLog
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.python/py-mi-var-info-path-expression.exp
gdb/varobj.c

index 3138024753b5afc9f40cb63d9ed652a392053fe5..b8f06a7878f174ceafffe515c7a2eea18cc04117 100644 (file)
@@ -1,3 +1,8 @@
+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
index 8be35e315a4178869e756eee45ff4ebe9e4894ce..b0fc59256333cb95e0b41ea5fdd9d092130ba4b7 100644 (file)
@@ -1,3 +1,9 @@
+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
index 2688851dbcc25b58ee3fb1450a337272dc33848e..4328c599321f01d81cf05d6b26ba74bdabd1f3fe 100644 (file)
@@ -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"
index 7928d90bef3959e95e905ac33cdd68fb80d90514..d0c857a69060644b225f3072b96c90a44b6d1548 100644 (file)
@@ -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,
This page took 0.040302 seconds and 4 git commands to generate.