What version (or hash if on master) of pybind11 are you using?
2.10.1
Problem description
Calling a pure virtual method that is bound via a PYBIND11_OVERRIDE_PURE trampoline implementation, where there is no corresponding Python implementation, calls into pybind11::pybind11_fail in order to throw an exception notifying the user that this pure virtual method has not been overridden.
The pybind11::pybind11_fail function has an assert(!PyErr_Occurred()) line, which obviously only (usually) affects Debug builds.
If the method releases the GIL before the C++ body (py::call_guard<py::gil_scoped_release>{}), then when that assertion is triggered in a Debug build, the CPython tstate is NULL and we get a segfault.
Required prerequisites
What version (or hash if on master) of pybind11 are you using?
2.10.1
Problem description
Calling a pure virtual method that is bound via a
PYBIND11_OVERRIDE_PURE
trampoline implementation, where there is no corresponding Python implementation, calls intopybind11::pybind11_fail
in order to throw an exception notifying the user that this pure virtual method has not been overridden.The
pybind11::pybind11_fail
function has anassert(!PyErr_Occurred())
line, which obviously only (usually) affects Debug builds.If the method releases the GIL before the C++ body (
py::call_guard<py::gil_scoped_release>{}
), then when that assertion is triggered in a Debug build, the CPythontstate
isNULL
and we get a segfault.This appears to be caused by a change in CPython https://github.com/python/cpython/pull/17080 / https://bugs.python.org/issue38733 - which indicates this affects Python 3.9+. I.e.
Reproducible example code
Confirmed the following behaves as expected in Python 3.8, but segfaults in Python 3.9
CMakeLists.txt
segfaulty.cpp
Test, assuming pybind11 and Python are discoverable and Python 3.9 is the discovered Python version
The yields
on Python 3.9, and
on Python 3.8.
Is this a regression? Put the last known working version here if it is.
Not a regression