我有一个名为main的简单程序:
#include <iostream>
#include "random.h"
int main()
{
std::cout << "The program has started\n";
return get_another_random_number();
}get_another_random_number()函数位于共享库的新版本中,但只安装了旧版本。程序开始运行,但在稍后查找失败时崩溃。
$ ./main
The program has started
./main: symbol lookup error: ./main: undefined symbol: _Z25get_another_random_numberv例如,如果librandom.so.1.3.1包含一个名为get_another_random_number()的函数,但是main是在只安装了librandom.so.1.2.5的服务器上执行的,就会发生这种情况。这些库的次要版本不同,因为1.3版本与库的1.2版本向后兼容,但是1.2缺少额外的功能。
在我自己的例子中,如果我运行readelf -d main | grep NEEDED,我得到:
0x0000000000000001 (NEEDED) Shared library: [librandom.so.1]
0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]因此,所有的东西都只与主要版本号相关联。
对于我的共享库,我将其放在/usr/lib/中并添加了符号链接:
lrwxrwxrwx 1 root root 23 Feb 7 14:25 /usr/lib/librandom.so -> /usr/lib/librandom.so.1
lrwxrwxrwx 1 root root 27 Feb 7 14:13 /usr/lib/librandom.so.1 -> /usr/lib/librandom.so.1.2.5
-rw-r--r-- 1 root root 7696 Feb 7 14:00 /usr/lib/librandom.so.1.2.5在库维护者、应用程序开发人员和系统管理员之间;谁负责避免程序崩溃?
main期间出现错误,说明当前安装的库的次要版本太低?发布于 2018-02-07 22:25:14
您没有误解版本号,这确实是一个符号查找通常需要的区域。
至于这是谁的责任,我要说的是,在现代系统中,它属于构建应用程序的人,而不是库:如果您将应用程序链接到ld -z now (至少在application上),动态链接器将在启动时解析所有符号,如果缺少任何符号,则会提前失败(因此您不需要自己添加手动检查)。通过将LD_BIND_NOW=1导出到环境中,您可以在程序链接之后启用这种行为(任何非空值都能工作,而且这不是Linux特有的)。
这种问题通常由包管理系统来处理:它们保持广泛的元数据描述符号的版本需求,并生成适当的版本依赖关系。库作者也有可能帮助改善这种情况,但这需要付出很大的努力;请参阅GNU的特殊版本符号(经常出现在错误消息中的GLIBC_...符号),以及对版本符号的全面处理。
https://unix.stackexchange.com/questions/422664
复制相似问题