summaryrefslogtreecommitdiffstats
path: root/Modules/gcmodule.c
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2019-10-07 22:09:31 (GMT)
committerGitHub <noreply@github.com>2019-10-07 22:09:31 (GMT)
commit1b1845569539db5c1a6948a5d32daea381f1e35f (patch)
tree9e9b867120a68e7f1f2c1f270dd102a6297adca6 /Modules/gcmodule.c
parent7775349895088a7ae68cecf0c74cf817f15e2c74 (diff)
downloadcpython-1b1845569539db5c1a6948a5d32daea381f1e35f.zip
cpython-1b1845569539db5c1a6948a5d32daea381f1e35f.tar.gz
cpython-1b1845569539db5c1a6948a5d32daea381f1e35f.tar.bz2
bpo-38392: PyObject_GC_Track() validates object in debug mode (GH-16615)
In debug mode, PyObject_GC_Track() now calls tp_traverse() of the object type to ensure that the object is valid: test that objects visited by tp_traverse() are valid. Fix pyexpat.c: only track the parser in the GC once the parser is fully initialized.
Diffstat (limited to 'Modules/gcmodule.c')
-rw-r--r--Modules/gcmodule.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c
index 107ce39..2cbf573 100644
--- a/Modules/gcmodule.c
+++ b/Modules/gcmodule.c
@@ -1922,6 +1922,18 @@ _PyGC_Dump(PyGC_Head *g)
_PyObject_Dump(FROM_GC(g));
}
+static int
+visit_validate(PyObject *op, void *parent_raw)
+{
+ PyObject *parent = _PyObject_CAST(parent_raw);
+ if (_PyObject_IsFreed(op)) {
+ _PyObject_ASSERT_FAILED_MSG(parent,
+ "PyObject_GC_Track() object is not valid");
+ }
+ return 0;
+}
+
+
/* extension modules might be compiled with GC support so these
functions must always be available */
@@ -1935,6 +1947,13 @@ PyObject_GC_Track(void *op_raw)
"by the garbage collector");
}
_PyObject_GC_TRACK(op);
+
+#ifdef Py_DEBUG
+ /* Check that the object is valid: validate objects traversed
+ by tp_traverse() */
+ traverseproc traverse = Py_TYPE(op)->tp_traverse;
+ (void)traverse(op, visit_validate, op);
+#endif
}
void