【问题标题】:Python Shared Libraries: RTLD_GLOBAL segfaultPython 共享库:RTLD_GLOBAL 段错误
【发布时间】:2013-12-31 00:16:25
【问题描述】:

我使用 python swig 包装的 C++ 库。在它的__init__.py 文件中,它sets dlopen 标志RTLD_GLOBAL 在导入包含实现代码的共享对象文件之前。

这会导致后续导入 scipy.linalg 到段错误,至少在我的机器上是这样。我认为这种行为取决于 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 版本或平台的?

【问题讨论】:

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


    【解决方案1】:

    您遇到了 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 实际上不再需要这个。

    【讨论】:

    • 该问题似乎已在 numpy 存储库中得到解决——我不确定我是否直接尝试过,但这是否意味着我上面的测试代码不应使用最新的 numpy/scipy 进行段错误?
    • 可能,是的。我无法在最新版本上重现该问题
    猜你喜欢
    • 2011-06-30
    • 2018-03-23
    • 2023-03-12
    • 1970-01-01
    • 2010-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多