6

我正在尝试用 C 构建一个程序,该程序具有许多依赖于各种共享库的可选功能。

在我们的异构计算集群中,并非所有这些库在所有系统上都可用(或最新)。

sched_getcpu@@GLIBC_2.6示例是来自较新 glibc ( , ) 或整个共享库的符号,__sched_cpucount@@GLIBC_2.6它们可能可用也可能不可用 ( libnuma, libR, libpbs)。

我知道我可以用andlibdl来加载符号,但是对于越来越多的符号(目前大约 30 个)这样做充其量是乏味的。dlopendlsym

据我了解,Linux 中的共享库默认是延迟加载的,因此在实际使用之前不需要符号。

但是,如果我尝试提前检查,那么它在执行开始时会失败:

#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;
}

在具有所有库的编译系统上:

$ icc test.c
$ ./a.out
10

在另一个具有较新版本 GLIBC 的系统上:

$ ./a.out 
./a.out: /lib64/libc.so.6: version `GLIBC_2.6' not found (required by ./a.out)

如果我注释掉实际调用的行,sched_getcpu那么我会在较小的系统上得到:

$ ./a.out 
/lib64/libc.so.6: undefined symbol: sched_getcpu

那么,有没有办法强制库仅在使用时加载并在使用它们的块之前进行此类检查?

4

1 回答 1

1

不使用 glibc。这是一个故障保险装置,它已经到位,这样你就不会在脚上开枪了。如果GLIBC_2.6没有定义和查找符号,即使没有其他丢失的符号,您也可能会从 glibc(数据损坏和崩溃)中得到垃圾结果,因为它不向前兼容。

如果您需要 glibc 级别的兼容性,则需要针对最低通用版本进行构建。

于 2012-12-18T18:19:58.253 回答