linuxdynamic连接器的“无版本信息”错误是什么意思?

在我们的产品中,我们提供了一些dynamic链接到像“libpam”这样的系统库的linux二进制文件。 在某些客户系统上,当程序运行时,我们在stderr上得到以下错误:

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

应用程序运行正常,并执行dynamic库中的代码。 所以这不是一个致命的错误,它只是一个警告。

我认为这是错误来自dynamic链接器,当系统安装库缺less我们的可执行文件预期的东西。 我对dynamic链接过程的内部知识并不了解,并且使用这个主题search并没有什么帮助。 🙁

任何人知道是什么原因造成这个错 …我如何诊断原因? …以及我们如何改变我们的可执行文件,以避免这个问题?

更新:客户升级到最新版本的debian“testing”,发生同样的错误。 所以这不是一个过时的libpam库。 我想我想了解链接器在抱怨什么? 我如何调查潜在的原因等?

“无版本信息”表示共享库上的版本号较低。 例如,如果您在构build二进制文件的机器上的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这样的工具来实现这一点,所以您想要实际安装一个与客户端的生产环境相匹配的开发环境(或者至less安装并链接到正确的库版本)。

build议您重新命名.so文件(填充版本号),源于共享对象库不使用版本化符号的时间。 所以,不要指望使用.so.nnn命名scheme来帮助(很多 – 如果你的系统被破坏,这可能会有帮助)。

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

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

这个来自glibcdynamic链接器的信息实际上意味着提到的库( /lib/libpam.so.0 )没有VERDEF ELF部分,而二进制文件(在你的情况下是authpam )有一些版本定义VERNEED部分这个库(大概是libpam.so.0 )。 你可以用readelf轻松地看到它,只要看看.gnu.version_d.gnu.version_r部分(或缺乏)。

所以这不是一个符号版本不匹配,因为如果二进制文件想通过VERNEED得到一些特定的版本,而库没有在它的实际VERDEF提供它,那将是一个硬链接器错误,二进制文件根本不会运行比如这个或那个 )。 这是二进制想要一些版本,但图书馆没有提供任何有关其版本的信息。

这在实践中意味着什么? 通常,正是在这个例子中看到什么 – 没有什么,只是忽略版本的工作。 事情能打破吗? 当然,是的,所以其他的答案是正确的,因为在运行时应该使用与二进制文件在编译时链接的库相同的库。

更多信息可以在Ulrich Dreppers的“ELF Symbol Versioning”中find 。

Fwiw,在安装了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 (...) 

所以无论如何,我想说的是:检查你的variables,如LD_LIBRARY_PATH,LD_PRELOAD等。

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

根据我的经验,当针对Linux系统的巨大领域时,在您愿意支持的最旧版本上构build软件包,并且由于更多的系统往往是向后兼容的,您的应用程序将继续工作。 实际上,这是库版本化的全部原因 – 确保向后兼容性。

你有看过吗? 这个事业似乎是一个很老的libpam,可能在这个客户身上。

或者该版本的链接可能会丢失: http : //www.linux.org/docs/ldp/howto/Program-Library-HOWTO/shared-libraries.html