我使用python swig包装的C ++库。在它的__init__.py
文件中,在导入包含实现代码的共享对象文件之前,它sets dlopen标记RTLD_GLOBAL。
这导致随后将scipy.linalg导入到segfault,至少在我的机器上。我认为这种行为取决于scipy的构建方式以及与之相关的内容。
# minimal example of what's going on
$ cat test.py
import sys
import ctypes
flags = sys.getdlopenflags()
sys.setdlopenflags(flags | ctypes.RTLD_GLOBAL)
import scipy.linalg
$ python test.py
[1] 16886 segmentation fault (core dumped) python test.py
sys.setdlopenflags(flags | ctypes.RTLD_GLOBAL)
行时,一切似乎都可以正常使用库,所以这可能是特定于某些python版本或平台?答案 0 :(得分:3)
您正在使用f2py工具中的错误,该工具用于构建SciPy。在此处查看更多详细信息:https://github.com/numpy/numpy/issues/2521
不幸的是,您只能通过重建SciPy或删除RTLD_GLOBAL
标志来解决问题。
NumPy和SciPy都在使用符号PyArray_API
,RTLD_GLOBAL
标志强制SciPy(尝试)导出自己的副本。这会导致冲突和段错误。
(如果有人能够更详细地解释这一点,我很想知道)
RTLD_GLOBAL
会使共享库中的符号公开并可用于重定位。当您通过dlopen()导入多个使用彼此符号的单独库时,需要这样做。在Python中,当单个项目(PyOpenMM)由几个想要共享其中一个提供的公共功能的二进制子模块组成时,就会出现这种情况。 “一切似乎都运行正常”这一事实可能只是意味着您没有使用任何需要共享功能的东西 - 或者PyOpenMM实际上不再需要它。