pybind11:静态进程退出时出现段错误 py::object
pybind11: segfault on process exit with static py::object
我正在使用 pybind11 在 C++ 中创建一个模块,然后将其导入到 Python 程序中。这是 运行通过 CPython 中的普通脚本,而不是嵌入式解释器。
在我的模块中,我有一个定义静态 py::object
:
的函数
void some_function() {
static const py::object my_object = ...
}
这在 运行 时工作正常,但当进程退出时出现段错误。如果我将 py::object
更改为 py::handle
,它会起作用。所以看起来当 object
析构函数试图减少引用计数时我们正在崩溃。
我相信我的模块将在 Python 解释器关闭(后进先出顺序)之前被卸载(并且静态对象的析构函数将执行),所以那时 [=27] 应该是安全的=] 这个析构函数。如果不是这种情况,除了故意泄漏对象外,我该如何确保安全(确保我的清理发生在 Python 之前)?
两种可能的解决方案:
您可以定义 pybind11 模块的静态成员或 class,而不是本地静态对象。然后对象的生命周期与绑定相关联,绑定由 python 解释器管理并正确销毁。
另一种方法是使用 pythonic atexit
回调 (Here's an example) 手动销毁对象。
你说得对,C++ 对象保证按 LIFO 顺序析构,但这并不限制 Python 解释器。 python 解释器在 C/C++ 展开之前使用函数 Py_FinalizeEx
关闭。
我正在使用 pybind11 在 C++ 中创建一个模块,然后将其导入到 Python 程序中。这是 运行通过 CPython 中的普通脚本,而不是嵌入式解释器。
在我的模块中,我有一个定义静态 py::object
:
void some_function() {
static const py::object my_object = ...
}
这在 运行 时工作正常,但当进程退出时出现段错误。如果我将 py::object
更改为 py::handle
,它会起作用。所以看起来当 object
析构函数试图减少引用计数时我们正在崩溃。
我相信我的模块将在 Python 解释器关闭(后进先出顺序)之前被卸载(并且静态对象的析构函数将执行),所以那时 [=27] 应该是安全的=] 这个析构函数。如果不是这种情况,除了故意泄漏对象外,我该如何确保安全(确保我的清理发生在 Python 之前)?
两种可能的解决方案:
您可以定义 pybind11 模块的静态成员或 class,而不是本地静态对象。然后对象的生命周期与绑定相关联,绑定由 python 解释器管理并正确销毁。
另一种方法是使用 pythonic atexit
回调 (Here's an example) 手动销毁对象。
你说得对,C++ 对象保证按 LIFO 顺序析构,但这并不限制 Python 解释器。 python 解释器在 C/C++ 展开之前使用函数 Py_FinalizeEx
关闭。