Python共享库:RTLD_GLOBAL段错误

时间:2013-12-31 00:16:25

标签: python numpy scipy shared-libraries python-import

我使用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
  1. 为什么会这样?发生了什么事?
  2. 在什么条件下可能需要设置RTLD_GLOBAL?我使用的代码包含comment“#以下是允许POSIX”dlopen“功能工作所需的邪恶咒语。我不明白。如果知道更好的解决方案,请转发到PyOpenMM代码维护者。“当我删除sys.setdlopenflags(flags | ctypes.RTLD_GLOBAL)行时,一切似乎都可以正常使用库,所以这可能是特定于某些python版本或平台?

1 个答案:

答案 0 :(得分:3)

您正在使用f2py工具中的错误,该工具用于构建SciPy。在此处查看更多详细信息:https://github.com/numpy/numpy/issues/2521

不幸的是,您只能通过重建SciPy或删除RTLD_GLOBAL标志来解决问题。

NumPy和SciPy都在使用符号PyArray_APIRTLD_GLOBAL标志强制SciPy(尝试)导出自己的副本。这会导致冲突和段错误。 (如果有人能够更详细地解释这一点,我很想知道)

RTLD_GLOBAL会使共享库中的符号公开并可用于重定位。当您通过dlopen()导入多个使用彼此符号的单独库时,需要这样做。在Python中,当单个项目(PyOpenMM)由几个想要共享其中一个提供的公共功能的二进制子模块组成时,就会出现这种情况。 “一切似乎都运行正常”这一事实可能只是意味着您没有使用任何需要共享功能的东西 - 或者PyOpenMM实际上不再需要它。