我正在尝试在C中构建一个程序,它具有许多依赖于各种共享库的可选功能。
在我们的异构计算集群中,并非所有系统上的所有库都可用(或最新)。
示例是来自较新的glibc(sched_getcpu@@GLIBC_2.6
,__sched_cpucount@@GLIBC_2.6
)或整个共享库的符号,这些符号可能可用也可能不可用(libnuma
,libR
,{{1} })。
我知道我可以使用libpbs
加载带有libdl
和dlopen
的符号,但是对于越来越多的符号(目前大约30个)这样做是很乏味的充其量。
据我所知,Linux中的共享库默认是延迟加载的,因此在实际使用之前不应该使用符号。
但如果我提前检查它,那么它在执行开始时失败:
dlsym
在包含所有库的编译系统上:
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <dlfcn.h>
#include <sched.h>
int main() {
void *lib_handle;
int (*fn)(void);
int x;
char *error;
lib_handle = dlopen("libc.so.6", RTLD_LAZY);
if (!lib_handle)
{
fprintf(stderr, "%s\n", dlerror());
exit(1);
}
fn = dlsym(lib_handle, "sched_getcpu");
if ((error = dlerror()) != NULL)
{
fprintf(stderr, "%s\n", error);
exit(1);
}
printf("%d\n", sched_getcpu());
return 0;
}
在另一个GLIBC版本较新的系统上:
$ icc test.c
$ ./a.out
10
如果我注释掉实际调用$ ./a.out
./a.out: /lib64/libc.so.6: version `GLIBC_2.6' not found (required by ./a.out)
的行,那么我会选择较小的系统:
sched_getcpu
那么,有没有办法强制只在使用时加载库,并在使用它们的块之前进行类似的检查?
答案 0 :(得分:1)
不是glibc。这是一个自动防故障装置,它不会让你自己陷入困境。如果GLIBC_2.6
符号未定义并查找,即使没有其他缺少的符号,您也可能从glibc(数据损坏和崩溃)获得垃圾结果,因为它不是向前兼容的。
如果你需要glibc级别的兼容性,你需要针对最低的通用版本进行构建。