101

在我们的产品中,我们发布了一些动态链接到“libpam”等系统库的 linux 二进制文件。在某些客户系统上,当程序运行时,我们在 stderr 上收到以下错误:

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

应用程序运行良好并执行动态库中的代码。所以这不是一个致命的错误,它实际上只是一个警告。

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

有谁知道是什么导致了这个错误?...我如何诊断原因?...以及我们如何更改可执行文件以避免此问题?

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

4

5 回答 5

70

“没有可用的版本信息”意味着共享对象上的库版本号较低。例如,如果您构建二进制文件的机器上的 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。

于 2008-10-01T05:57:23.387 回答
33

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

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

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

更多信息可以在 Ulrich Dreppers "ELF Symbol Versioning"中找到。

于 2016-08-09T12:42:01.593 回答
4

Fwiw,我在安装了 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 等。

于 2010-08-02T12:33:20.487 回答
3

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

以我的经验,当针对 Linux 系统的广阔领域时,在你愿意支持的最旧版本上构建你的包,因为更多的系统倾向于向后兼容,你的应用程序将继续工作。实际上,这是库版本控制的全部原因 - 确保向后兼容性。

于 2008-10-01T06:26:56.747 回答
1

你已经看到吗?原因似乎是其中一方的一个非常旧的 libpam,可能是那个客户。

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

于 2008-09-26T04:42:33.040 回答