在我们的产品中,我们发布了一些动态链接到"libpam"等系统库的linux二进制文件.在某些客户系统上,当程序运行时,我们在stderr上收到以下错误:
./authpam: /lib/libpam.so.0: no version information available (required by authpam)
应用程序运行正常并从动态库执行代码.所以这不是一个致命的错误,它只是一个警告.
我认为当系统安装库缺少我们的可执行文件期望的东西时,这是来自动态链接器的错误.我不太了解动态链接过程的内部结构......并且谷歌搜索主题并没有多大帮助.:(
任何人都知道导致此错误的原因 ......我怎么能诊断原因?...以及我们如何更改可执行文件以避免此问题?
更新:客户升级到最新版本的debian"testing"并发生了同样的错误.所以它不是一个过时的libpam库.我想我想了解链接器在抱怨什么?我该如何调查根本原因等?
"没有可用的版本信息"表示共享对象上的库版本号较低.例如,如果您在构建二进制文件的计算机上的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.
来自glibc动态链接器的这个消息实际上意味着所提到的库(/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"中找到.