来自 linux 动态链接器的“无可用版本信息”错误是什么意思?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/137773/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What does the "no version information available" error from linux dynamic linker mean?
提问by
In our product we ship some linux binaries that dynamically link to system libraries like "libpam". On some customer systems we get the following error on stderr when the program runs:
在我们的产品中,我们提供了一些动态链接到系统库(如“libpam”)的 linux 二进制文件。在某些客户系统上,当程序运行时,我们会在 stderr 上收到以下错误:
./authpam: /lib/libpam.so.0: no version information available (required by authpam)
The application runs fine and executes code from the dynamic library. So this is not a fatal error, it's really just a warning.
应用程序运行良好并执行动态库中的代码。所以这不是致命错误,它实际上只是一个警告。
I figure that this is error comes from the dynamic linker when the system installed library is missing something our executable expects. I don't know much about the internals of the dynamic linking process ... and googling the topic doesn't help much. :(
当系统安装的库缺少我们的可执行文件所期望的东西时,我认为这是来自动态链接器的错误。我对动态链接过程的内部原理知之甚少……搜索该主题并没有多大帮助。:(
Anyone know what causes this error? ... how I can diagnose the cause? ... and how we could change our executables to avoid this problem?
有谁知道是什么导致了这个错误?...我如何诊断原因?...以及我们如何更改我们的可执行文件来避免这个问题?
Update: The customer upgraded to the latest version of debian "testing" and the same error occurred. So it's not an out of date libpam library. I guess I'd like to understand what the linker is complaining about? How can I investigate the underlying cause, etc?
更新:客户升级到最新版本的debian“testing”,出现同样的错误。所以它不是过时的 libpam 库。我想我想了解链接器在抱怨什么?我如何调查根本原因等?
回答by Vinko Vrsalovic
Have you seen thisalready? The cause seems to be a very old libpam on one of the sides, probably on that customer.
你见过这个了吗?原因似乎是其中一侧的一个非常旧的 libpam,可能是该客户。
Or the links for the version might be missing : http://www.linux.org/docs/ldp/howto/Program-Library-HOWTO/shared-libraries.html
或者版本的链接可能丢失:http: //www.linux.org/docs/ldp/howto/Program-Library-HOWTO/shared-libraries.html
回答by Chris
The "no version information available" means that the library version number is lower on the shared object. For example, if your major.minor.patch number is 7.15.5 on the machine where you build the binary, and the major.minor.patch number is 7.12.1 on the installation machine, ld will print the warning.
“无可用版本信息”表示共享对象上的库版本号较低。例如,如果您构建二进制文件的机器上的major.minor.patch 编号是7.15.5,而安装机器上的major.minor.patch 编号是7.12.1,ld 将打印警告。
You can fix this by compiling with a library (headers and shared objects) that matches the shared object version shipped with your target OS. E.g., if you are going to install to RedHat 3.4.6-9 you don't want to compile on Debian 4.1.1-21. This is one of the reasons that most distributions ship for specific linux distro numbers.
您可以通过使用与目标操作系统附带的共享对象版本匹配的库(头文件和共享对象)进行编译来解决此问题。例如,如果您要安装到 RedHat 3.4.6-9,您不想在 Debian 4.1.1-21 上编译。这是大多数发行版针对特定 linux 发行版编号的原因之一。
Otherwise, you can statically link. However, you don't want to do this with something like PAM, so you want to actually install a development environment that matches your client's production environment (or at least install and link against the correct library versions.)
否则,您可以静态链接。但是,您不想使用 PAM 之类的东西来执行此操作,因此您希望实际安装与客户生产环境匹配的开发环境(或至少安装并链接到正确的库版本。)
Advice you get to rename the .so files (padding them with version numbers,) stems from a time when shared object libraries did not use versioned symbols. So don't expect that playing with the .so.n.n.n naming scheme is going to help (much - it might help if you system has been trashed.)
重命名 .so 文件(用版本号填充它们)的建议源于共享对象库不使用版本化符号的时候。所以不要指望使用 .so.nnn 命名方案会有所帮助(很多 - 如果您的系统被破坏,它可能会有所帮助。)
You last option will be compiling with a library with a different minor version number, using a custom linking script: http://www.redhat.com/docs/manuals/enterprise/RHEL-4-Manual/gnu-linker/scripts.html
您的最后一个选项是使用自定义链接脚本编译具有不同次要版本号的库:http: //www.redhat.com/docs/manuals/enterprise/RHEL-4-Manual/gnu-linker/scripts。 html
To do this, you'll need to write a custom script, and you'll need a custom installer that runs ld against your client's shared objects, using the custom script. This requires that your client have gcc or ld on their production system.
为此,您需要编写一个自定义脚本,并且您需要一个自定义安装程序,该程序使用自定义脚本针对客户端的共享对象运行 ld。这要求您的客户在其生产系统上具有 gcc 或 ld。
回答by Ted Percival
How are you compiling your app? What compiler flags?
你是如何编译你的应用程序的?什么编译器标志?
In my experience, when targeting the vast realm of Linux systems out there, build your packages on the oldest version you are willing to support, and because more systems tend to be backwards compatible, your app will continue to work. Actually this is the whole reason for library versioning - ensuring backward compatibility.
根据我的经验,当针对 Linux 系统的广阔领域时,请在您愿意支持的最旧版本上构建您的软件包,并且由于更多系统倾向于向后兼容,您的应用程序将继续工作。实际上,这就是库版本控制的全部原因——确保向后兼容。
回答by Dieter_be
Fwiw, I had this problem when running check_nrpe on a system that had the zenoss monitoring system installed. To add to the confusion, it worked fine as root user but not as zenoss user.
Fwiw,我在安装了 zenoss 监控系统的系统上运行 check_nrpe 时遇到了这个问题。更令人困惑的是,它作为 root 用户运行良好,但作为 zenoss 用户运行不正常。
I found out that the zenoss user had an LD_LIBRARY_PATH that caused it to use zenoss libraries, which issue these warnings. Ie:
我发现 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
(...)
So anyway, what I'm trying to say: check your variables like LD_LIBRARY_PATH, LD_PRELOAD etc as well.
所以无论如何,我想说的是:检查你的变量,如 LD_LIBRARY_PATH、LD_PRELOAD 等。
回答by Roman Khimov
What this message from the glibc dynamic linker actually means is that the library mentioned (/lib/libpam.so.0
in your case) doesn't have the VERDEF
ELF section while the binary (authpam
in your case) has some version definitions in VERNEED
section for this library (presumably, libpam.so.0
). You can easily see it with readelf
, just look at .gnu.version_d
and .gnu.version_r
sections (or lack thereof).
来自 glibc 动态链接器的这条消息实际上意味着提到的库(/lib/libpam.so.0
在您的情况下)没有VERDEF
ELF 部分,而二进制文件(authpam
在您的情况下)在VERNEED
该库的部分(大概是)中有一些版本定义libpam.so.0
。您可以使用 轻松查看它readelf
,只需查看.gnu.version_d
和.gnu.version_r
部分(或缺少部分)。
So it's not a symbol version mismatch, because if the binary wanted to get some specific version via VERNEED
and the library didn't provide it in its actual VERDEF
, that would be a hard linker error and the binary wouldn't run at all (like thiscompared to thisor that). It's that the binary wants some versions, but the library doesn't provide any information about its versions.
所以这不是符号版本不匹配,因为如果二进制文件想要通过它获得某个特定版本VERNEED
而库没有在其实际中提供它VERDEF
,那将是一个硬链接器错误并且二进制文件根本不会运行(像这样与这个或那个相比)。二进制文件需要一些版本,但库不提供有关其版本的任何信息。
What does it mean in practice? Usually, exactly what is seen in this example — nothing, things just work ignoring versioning. Could things break? Of course, yes, so the other answers are correct in the fact that one should use the same libraries at runtime as the ones the binary was linked to at build time.
这在实践中意味着什么?通常,正是在这个例子中看到的——什么都没有,事情只是在忽略版本控制。事情会破裂吗?当然,是的,所以其他答案是正确的,因为在运行时应该使用与二进制文件在构建时链接到的库相同的库。
More information could be found in Ulrich Dreppers "ELF Symbol Versioning".
更多信息可以在 Ulrich Dreppers "ELF Symbol Versioning" 中找到。