linux动态链接器出现的"没有可用的版本信息"错误是什么意思?
在我们的产品中,我们提供了一些Linux二进制文件,这些二进制文件可动态链接到系统库,例如" libpam"。在某些客户系统上,程序运行时,在stderr上会出现以下错误:
./authpam: /lib/libpam.so.0: no version information available (required by authpam)
该应用程序运行良好,并从动态库执行代码。因此,这不是致命错误,实际上只是警告。
当系统安装的库缺少我们的可执行文件期望的东西时,我认为这是来自动态链接器的错误。我对动态链接过程的内部知识了解不多...搜索该主题并没有多大帮助。 :(
有人知道导致此错误的原因吗? ...我如何诊断原因? ...以及如何更改可执行文件来避免此问题?
更新:客户已升级到最新版本的debian"测试",并且发生了相同的错误。因此,它不是一个过时的libpam库。我想我想了解链接器在抱怨什么?我如何调查根本原因等?
解决方案
你看过这个吗?原因似乎是一方方面很老的libpam,可能是在那个客户上。
否则可能缺少该版本的链接:http://www.linux.org/docs/ldp/howto/Program-Library-HOWTO/shared-libraries.html
"没有可用的版本信息"表示库版本号在共享库上较低。例如,如果在生成二进制文件的计算机上major.minor.patch号是7.15.5,而在安装计算机上major.minor.patch号是7.12.1,则ld将打印警告。
我们可以通过编译与目标OS附带的共享库版本匹配的库(标头和共享库)来解决此问题。例如,如果我们要安装到RedHat 3.4.6-9,则不想在Debian 4.1.1-21上进行编译。这是大多数发行版附带特定Linux发行版编号的原因之一。
否则,我们可以静态链接。但是,我们不想使用PAM之类的方法来执行此操作,因此我们实际上想安装与客户的生产环境相匹配的开发环境(或者至少安装并链接到正确的库版本)。
建议重命名.so文件(用版本号填充它们)源于共享库未使用版本符号的时间。因此,不要指望使用.so.n.n.n命名方案会有所帮助(如果系统已被废弃,这可能会有所帮助。)
最后一个选择是使用自定义链接脚本使用具有不同次要版本号的库进行编译:
http://www.redhat.com/docs/manuals/enterprise/RHEL-4-Manual/gnu-linker/scripts.html
为此,我们需要编写一个自定义脚本,并且需要一个使用该自定义脚本针对客户的共享对象运行ld的自定义安装程序。这要求客户在其生产系统上具有gcc或者ld。
我们如何编译应用程序?什么编译器标志?
以我的经验,当针对广泛的Linux系统领域时,请在我们愿意支持的最旧版本上构建软件包,并且由于更多的系统倾向于向后兼容,因此应用将继续运行。实际上,这就是库版本控制确保向后兼容的全部原因。
首先,在安装了zenoss监视系统的系统上运行check_nrpe时遇到了这个问题。更令人困惑的是,它作为root用户而不是zenoss用户可以正常工作。
我发现zenoss用户的LD_LIBRARY_PATH导致其使用zenoss库,并发出了这些警告。 IE:
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等。