【问题标题】:Linux Shared Object Library LinkageLinux 共享对象库链接
【发布时间】:2016-05-11 14:22:06
【问题描述】:

我有一个我想使用的库。我没有它的源代码,但它包含我想使用的功能。它是一个普通的 x86-64 共享对象,其中包含一些 JNI 代码,没有什么特别之处。我现在的问题是库引用了libm.so。现在发生的事情很奇怪,我没想到。当我尝试运行它时,它告诉我 libm.so 有一个无效的 ELF 标头,这是有道理的,因为 libm.so 只是 libm.so.6 的参考文件,它是实际的库文件。

现在我的问题是如何纠正?我真的很惊讶操作系统没有正确处理这个问题,因为每个程序都会引用libm.so 而不是libm.so.6,因为它至少应该在某种程度上独立于版本。

编辑:我做了一个stracelibm.so 似乎只是冰山一角...我的库引用了许多常见的Linux 标准库。而且由于我在 JRE 中执行它,它只在 JRE 的目录中搜索,这当然是完全错误的。而且由于该库是从 Android 应用程序中获取的,因此原始 makefile 可能具有库的路径,这些路径也没有任何意义……必须对这个问题进行更多分析才能解决。

【问题讨论】:

  • 作为实际文件的符号链接的库与任何其他符号链接一样工作。一定有其他问题导致错误。至于错误,您能否复制粘贴完整且未经编辑的实际错误,并将其显示在问题正文中?也许还显示用于链接的命令行(链接失败?或者尝试运行程序时失败?)。

标签: linux shared-libraries elf


【解决方案1】:

导入应该是libm.so.6。导入libm.so 只能在编译时进行。生成的 ELF 应该导入前者。

这称为 ABI 版本。这是为了确保如果您与某个版本的库链接,您只会获得与您链接的版本兼容的实际导入。关于该数字何时更改有一些复杂的规则(有关更多详细信息,请参阅soname)。

很遗憾,您没有提出任何实际问题。这并不能解释您的导入失败的原因。如果 ELF 标头错误,那么您可能在错误的位置寻找它(更准确地说,发送 ld.so 来寻找它)。

我会使用strace 运行我的代码,以查看实际打开了哪些文件。然后,在其上运行file,查看平台是否匹配(可能是 64 位可执行文件试图打开 32 位库,反之亦然)。

【讨论】:

  • 我对 strace 进行了更多分析,实际上看起来 JRE 找到了所有库,打开它们然后再次关闭它们。它甚至在正确的位置找到正确的文件(它看起来很晚,但它查看 /usr/lib 并且所有 x64 lib 文件。我有点回到第一步。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-25
  • 2013-04-13
  • 2018-07-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多