mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-27 07:32:02 +00:00
326deef2ae
* Fix segfault when reloading interpreter with external modules When embedding the interpreter and loading external modules in that embedded interpreter, the external module correctly shares its internals_ptr with the one in the embedded interpreter. When the interpreter is shut down, however, only the `internals_ptr` local to the embedded code is actually reset to nullptr: the external module remains set. The result is that loading an external pybind11 module, letting the interpreter go through a finalize/initialize, then attempting to use something in the external module fails because this external module is still trying to use the old (destroyed) internals. This causes undefined behaviour (typically a segfault). This commit fixes it by adding a level of indirection in the internals path, converting the local internals variable to `internals **` instead of `internals *`. With this change, we can detect a stale internals pointer and reload the internals pointer (either from a capsule or by creating a new internals instance). (No issue number: this was reported on gitter by @henryiii and @aoloe).
24 lines
554 B
C++
24 lines
554 B
C++
#include <pybind11/pybind11.h>
|
|
|
|
namespace py = pybind11;
|
|
|
|
/* Simple test module/test class to check that the referenced internals data of external pybind11
|
|
* modules aren't preserved over a finalize/initialize.
|
|
*/
|
|
|
|
PYBIND11_MODULE(external_module, m) {
|
|
class A {
|
|
public:
|
|
A(int value) : v{value} {};
|
|
int v;
|
|
};
|
|
|
|
py::class_<A>(m, "A")
|
|
.def(py::init<int>())
|
|
.def_readwrite("value", &A::v);
|
|
|
|
m.def("internals_at", []() {
|
|
return reinterpret_cast<uintptr_t>(&py::detail::get_internals());
|
|
});
|
|
}
|