linux动态链接程序的“无可用版本信息”错误是什么意思?


87

在我们的产品中,我们提供了一些Linux二进制文件,这些二进制文件可以动态链接到系统库,例如“ libpam”。在某些客户系统上,程序运行时在stderr上会出现以下错误:

./authpam: /lib/libpam.so.0: no version information available (required by authpam)

该应用程序运行良好,并从动态库执行代码。因此,这不是致命错误,实际上只是警告。

当系统安装的库缺少我们的可执行文件期望的东西时,我认为这是来自动态链接器的错误。我对动态链接过程的内部知识了解不多...搜索该主题并没有太大帮助。:(

有人知道导致此错误的原因吗?...我如何诊断原因?...以及如何更改可执行文件来避免此问题?

更新:客户已升级到最新版本的debian“测试”,并且发生了相同的错误。因此,它不是一个过时的libpam库。我想我想了解链接器在抱怨什么?如何调查根本原因等?

Answers:


64

“没有可用的版本信息”表示库版本号在共享库上较低。例如,如果您在生成二进制文件的计算机上的major.minor.patch号为7.15.5,而在安装计算机上的major.minor.patch号为7.12.1,则ld将打印警告。

您可以通过编译与目标操作系统随附的共享库版本匹配的库(标头和共享库)来解决此问题。例如,如果您要安装到RedHat 3.4.6-9,则不想在Debian 4.1.1-21上进行编译。这是大多数发行版附带特定Linux发行版编号的原因之一。

否则,您可以静态链接。但是,您不想使用PAM之类的方法来执行此操作,因此您实际上想安装一个与客户的生产环境相匹配的开发环境(或至少安装并链接到正确的库版本)。

建议重命名.so文件(用版本号填充它们)源于共享库未使用版本符号的时间。因此,不要指望使用.so.nnn命名方案会有所帮助(很多-如果您的系统已被删除,可能会有所帮助。)

最后一个选择是使用自定义链接脚本使用具有不同次要版本号的库进行编译:http : //www.redhat.com/docs/manuals/enterprise/RHEL-4-Manual/gnu-linker/scripts。 html

为此,您需要编写一个自定义脚本,并且需要一个使用该自定义脚本针对客户的共享对象运行ld的自定义安装程序。这要求您的客户在其生产系统上具有gcc或ld。


20

来自glibc动态链接器的此消息的实际含义是,提到的库(/lib/libpam.so.0在您的情况下)没有VERDEFELF部分,而二进制文件(authpam在您的情况下)在VERNEED此库的部分中有一些版本定义(大概是libpam.so.0)。您可以使用轻松查看它readelf,只需查看.gnu.version_d.gnu.version_r部分(或缺少部分)即可。

因此,这不是符号版本不匹配,因为如果二进制文件想要通过来获得某些特定版本VERNEED并且库没有在实际中提供它VERDEF,那将是一个硬链接器错误,并且二进制文件根本不会运行(像这样)相比于这个那个)。就是二进制文件需要某些版本,但是库没有提供有关其版本的任何信息。

实际上是什么意思?通常,在此示例中所看到的完全是什么-什么都做,只是忽略版本控制而已。事情会破裂吗?当然,是的,因此其他答案是正确的,因为在运行时应该使用与二进制文件在构建时链接到的库相同的库。

可以在Ulrich Dreppers的“ ELF符号版本控制”中找到更多信息。


4
我建议运行“ readelf -V <exePath>”以查看版本控制部分。通知资本V
Rayee Roded '17

我已经推断出这是对我自己构建并安装在并行前缀中的(系统的较新版本的)库发出警告的原因。我一直以为这是因为我使用LLVM工具链,但是我只是注意到使用系统gcc构建并不会自动将这些版本标签放入库中。我是否需要通过CFLAGS和/或LDFLAGS添加选项?
RJVB

4

首先,在安装了zenoss监视系统的系统上运行check_nrpe时遇到了这个问题。更令人困惑的是,它作为root用户而不是zenoss用户可以正常工作。

我发现zenoss用户的LD_LIBRARY_PATH导致其使用zenoss库,并发出了这些警告。即:

root@monitoring:$ echo $LD_LIBRARY_PATH

su - zenoss
zenoss@monitoring:/root$ echo $LD_LIBRARY_PATH
/usr/local/zenoss/python/lib:/usr/local/zenoss/mysql/lib:/usr/local/zenoss/zenoss/lib:/usr/local/zenoss/common/lib::
zenoss@monitoring:/root$ /usr/lib/nagios/plugins/check_nrpe -H 192.168.61.61 -p 6969 -c check_mq
/usr/lib/nagios/plugins/check_nrpe: /usr/local/zenoss/common/lib/libcrypto.so.0.9.8: no version information available (required by /usr/lib/libssl.so.0.9.8)
(...)
zenoss@monitoring:/root$ LD_LIBRARY_PATH= /usr/lib/nagios/plugins/check_nrpe -H 192.168.61.61 -p 6969 -c check_mq
(...)

所以无论如何,我想说的是:同样检查您的变量,例如LD_LIBRARY_PATH,LD_PRELOAD等。


3

您如何编译应用程序?什么编译器标志?

以我的经验,当针对广泛的Linux系统领域时,请在您愿意支持的最旧版本上构建您的软件包,并且由于更多的系统倾向于向后兼容,因此您的应用将继续运行。实际上,这就是进行库版本控制的全部原因-确保向后兼容。


1

你看到这个了吗?原因似乎是一方方面很老的libpam,可能是在那个客户上。

否则可能缺少该版本的链接:http : //www.linux.org/docs/ldp/howto/Program-Library-HOWTO/shared-libraries.html


我确实找到了那个,但并没有真正帮助理解原因。我认为这不是旧的pam库,因为它们已更新为最新的debian测试。

然后,也许您正在旧计算机上编译?:)您是否尝试在客户端计算机上进行编译?nondot.org/sabre/Mirrored/libtool-2.1a/libtool_toc.html#TOC36
Vinko Vrsalovic
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.