Commit f7ca5efb authored by Stefan Behnel's avatar Stefan Behnel

Disable GC during hacked calls to PyType_Ready() that simulate a heap type for...

Disable GC during hacked calls to PyType_Ready() that simulate a heap type for an actual non-heap type, because it can lead to crashes if GC visits such a hacked type.
Closes https://github.com/cython/cython/issues/3603
parent b177f229
...@@ -55,6 +55,31 @@ static int __Pyx_PyType_Ready(PyTypeObject *t) { ...@@ -55,6 +55,31 @@ static int __Pyx_PyType_Ready(PyTypeObject *t) {
} }
#if PY_VERSION_HEX >= 0x03050000 #if PY_VERSION_HEX >= 0x03050000
{
// Make sure GC does not pick up our non-heap type as heap type with this hack!
PyObject *ret, *py_status;
int gc_was_enabled;
PyObject *gc = PyImport_Import(PYUNICODE("gc"));
if (unlikely(!gc)) return -1;
py_status = PyObject_CallMethodObjArgs(gc, PYUNICODE("isenabled"), NULL);
if (unlikely(!py_status)) {
Py_DECREF(gc);
return -1;
}
gc_was_enabled = __Pyx_PyObject_IsTrue(py_status);
Py_DECREF(py_status);
if (gc_was_enabled > 0) {
ret = PyObject_CallMethodObjArgs(gc, PYUNICODE("disable"), NULL);
if (unlikely(!ret)) {
Py_DECREF(gc);
return -1;
}
Py_DECREF(ret);
} else if (unlikely(gc_was_enabled == -1)) {
Py_DECREF(gc);
return -1;
}
// As of https://bugs.python.org/issue22079 // As of https://bugs.python.org/issue22079
// PyType_Ready enforces that all bases of a non-heap type are // PyType_Ready enforces that all bases of a non-heap type are
// non-heap. We know that this is the case for the solid base but // non-heap. We know that this is the case for the solid base but
...@@ -69,6 +94,25 @@ static int __Pyx_PyType_Ready(PyTypeObject *t) { ...@@ -69,6 +94,25 @@ static int __Pyx_PyType_Ready(PyTypeObject *t) {
#if PY_VERSION_HEX >= 0x03050000 #if PY_VERSION_HEX >= 0x03050000
t->tp_flags &= ~Py_TPFLAGS_HEAPTYPE; t->tp_flags &= ~Py_TPFLAGS_HEAPTYPE;
if (gc_was_enabled) {
PyObject *t, *v, *tb;
PyErr_Fetch(&t, &v, &tb);
ret = PyObject_CallMethodObjArgs(gc, PYUNICODE("enable"), NULL);
if (likely(ret || r == -1)) {
Py_XDECREF(ret);
// do not overwrite exceptions raised by PyType_Ready() above
PyErr_Restore(t, v, tb);
} else {
// PyType_Ready() succeeded, but gc.enable() failed.
Py_XDECREF(t);
Py_XDECREF(v);
Py_XDECREF(tb);
r = -1;
}
}
Py_DECREF(gc);
}
#endif #endif
return r; return r;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment