6

さまざまな共有ライブラリに依存する多くのオプション機能を持つ C でプログラムを構築しようとしています。

私たちのヘテロジニアス コンピューティング クラスターでは、これらのライブラリのすべてがすべてのシステムで利用できる (または最新の状態である) わけではありません。

例としては、新しい glibc のシンボル ( sched_getcpu@@GLIBC_2.6__sched_cpucount@@GLIBC_2.6)、または利用できる場合と利用できない場合がある共有ライブラリ全体 ( libnumalibRlibpbs) があります。

とを使用libdlしてシンボルをロードできることはわかっていますが、増え続けるシンボル (現時点では約 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 に答える