【问题标题】:How does a dlopen'ed library resolve its undefined symbols?dlopen'ed 库如何解析其未定义的符号?
【发布时间】:2016-07-20 12:09:22
【问题描述】:

我创作了一个“dlopens”另一个共享库(我不是其作者/所有者)的共享库

我的共享库被一个可执行文件(我不是其作者/所有者)“dlopened”

所以层次结构是:exe dlopen 是我的库,我的库 dlopen 是另一个库。

我的库 dlopen 使用的库使用 openssl。然而,这个库的作者似乎没有链接 openssl 库——也许假设该库的用户会链接。

因此,当我尝试 dlopen 他们的库时,我遇到了未定义的符号错误。

即使我将 openssl 库链接到我的库中,我仍然会收到未定义符号错误。

我的问题有两个:

1) 当需要openssl的库被dlopen'ed时,它是否只知道'看'向exe来进行符号解析?

2) 我的库中是否有我需要的特殊链接器标志,在 openssl 中链接?

谢谢。

【问题讨论】:

  • 也许系统只是找不到SSL 库,它们在标准位置吗?您可以尝试将 LD_LIBRARY_PATH 设置为 SSL 库。

标签: c++ linux dlopen


【解决方案1】:

很可能依赖于 OpenSSL 的库以动态方式执行此操作。您可以使用库.so 上的ldd command 来确认这一点。如果您无法在此处发现对 OpenSSL 的依赖关系,则可能意味着该库手动加载 OpenSSL(通过自身手动调用 dlopen),在这种情况下您无法做太多事情 - 请联系库维护人员以进行修复。

如果依赖项确实显示为ldd 输出的一部分,则意味着操作系统负责加载它。这方面的规则冗长而复杂,但您需要了解的最重要的事情是LD_LIBRARY_PATHrpath

前者允许用户指定系统范围的目录列表,加载程序将在其中查找要加载的.so 文件。后者是内置在库本身中的路径列表,加载器将考虑这些路径。

通常希望库维护者设置他们的 rpath,以便在正确安装所有依赖项的情况下正确加载库。毕竟,依靠用户以某种方式设置他们的LD_LIBRARY_PATH并不是很方便。 Here's how you can inspect the .sos rpath.

因此,您需要确保以下几点:机器上是否安装了 OpenSSL,版本是否正确,以及它是否位于加载程序可以搜索的位置。这可能有点乏味,最终可能不清楚是谁的错是这些东西没有加载,但希望这些信息足以帮助您找到解决方案。

【讨论】:

  • 是的,它已安装并位于标准位置 - /usr/lib64。感谢您的反馈
【解决方案2】:

问题确实在于具有未定义符号的共享库。这可以工作,但不可移植,并且在更改链接器时可能会中断(例如黄金与普通 ld)。

如果他们需要符号,他们需要链接到 openssl。如果他们想独立于库(可能动态地切换与 ABI 兼容的 openssl 分支——请注意,只是一个疯狂的猜测)他们应该自己通过 dlopen 访问 openssl 实现并通过 dlsym 手动解析符号。假设动态链接器会神奇地“传播”符号。

现在,可能有办法让这项工作发挥作用。

dlopen 库中符号的“可用性”在您 dlopen 时控制,其中包括通过the RTLD_LOCAL / RTLD_GLOBAL flags

因此,您可以在 dlopen 需要 openssl 的库之前尝试使用 RTLD_GLOBAL dlopen openssl。

【讨论】:

  • 感谢您的反馈。是的 - 如果我在打开需要它的库之前打开 openssl 库,那么一切正常。我想知道是否有办法避免这样做,因为它似乎应该有。谢谢。
  • 有一个办法:不要像你依赖的库那样故意破坏动态链接过程。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-15
  • 2015-02-08
  • 1970-01-01
  • 2011-02-08
  • 1970-01-01
相关资源
最近更新 更多