ldd出力に複数のGLIBCバージョンがあることはどういう意味ですか?

ldd出力に複数のGLIBCバージョンがあることはどういう意味ですか?

lddプログラムは、私の共有ライブラリに必要な共有ライブラリの一部が欠落していることを報告します。 (Red Hat Linux 7を使用する別のコンピュータで構築し、Red Hat Linux 6を使用する別のコンピュータで実行したい)

以下のバージョン情報セクションにはlibc.so.6の3つのエントリがあり、各エントリは括弧内に異なるバージョンがあります(GLIBC_2.14、GLIBC_2.4、およびGLIBC_2.2.5)。まず、マシンに接続されている共有ライブラリがインストールされていません。

私はLinuxに初めてアクセスし、トラブルシューティングはどこでもこの出力を解釈する方法を理解していません。以下はコマンドと出力です。

>ldd -v libAtlasUtilsPB.so
./libAtlasUtilsPB.so: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by ./libAtlasUtilsPB.so)
./libAtlasUtilsPB.so: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.18' not found (required by ./libAtlasUtilsPB.so)
./libAtlasUtilsPB.so: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by ./libAtlasUtilsPB.so)
    linux-vdso.so.1 =>  (0x00007fffa3dff000)
    librt.so.1 => /lib64/librt.so.1 (0x00007fea7a7b2000)
    libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007fea7a4ab000)
    libm.so.6 => /lib64/libm.so.6 (0x00007fea7a227000)
    libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fea7a011000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fea79df3000)
    libc.so.6 => /lib64/libc.so.6 (0x00007fea79a5f000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fea7ad17000)

    Version information:
    ./libAtlasUtilsPB.so:
            libgcc_s.so.1 (GCC_3.0) => /lib64/libgcc_s.so.1
            libm.so.6 (GLIBC_2.2.5) => /lib64/libm.so.6
            libpthread.so.0 (GLIBC_2.2.5) => /lib64/libpthread.so.0
            libc.so.6 (GLIBC_2.14) => not found
            libc.so.6 (GLIBC_2.4) => /lib64/libc.so.6
            libc.so.6 (GLIBC_2.2.5) => /lib64/libc.so.6
            libstdc++.so.6 (GLIBCXX_3.4.18) => not found
            libstdc++.so.6 (GLIBCXX_3.4.15) => not found
            libstdc++.so.6 (GLIBCXX_3.4.9) => /usr/lib64/libstdc++.so.6
            libstdc++.so.6 (GLIBCXX_3.4.11) => /usr/lib64/libstdc++.so.6
            libstdc++.so.6 (CXXABI_1.3) => /usr/lib64/libstdc++.so.6
            libstdc++.so.6 (GLIBCXX_3.4) => /usr/lib64/libstdc++.so.6

答え1

ldd引数に必要な共有ライブラリを一覧表示します。この-vオプションを使用すると、バージョン記号を含む利用可能なすべての情報が一覧表示されます。

テーブルの行

linux-vdso.so.1 =>  (0x00007fffa3dff000)
librt.so.1 => /lib64/librt.so.1 (0x00007fea7a7b2000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007fea7a4ab000)

必要なライブラリlibAtlasUtilsPB.soとあなたの場合、解析方法の両方をリストします。図書館見つけることができます。linux-vdso.so.1とても特別です。仮想図書館カーネルで提供されます。

テーブルの行

libgcc_s.so.1 (GCC_3.0) => /lib64/libgcc_s.so.1
libm.so.6 (GLIBC_2.2.5) => /lib64/libm.so.6
libpthread.so.0 (GLIBC_2.2.5) => /lib64/libpthread.so.0

必要なバージョン記号libAtlasUtilsPB.soとそれを解決する方法をリストします。これはldd項目が解決できない場所で、ここに「見つかりません」と表示され、出力の先頭にエラーメッセージが表示されます。

GLIBC_...などは、GLIBCXX_...GNU Cライブラリ、GCCライブラリなど、一部のライブラリで必要なバージョンを識別し、下位互換性を管理するために使用されるバージョンシンボルです。バイナリ(実行ファイルまたはライブラリ)は、ターゲットライブラリが実際に使用するシンボルに応じて複数のバージョンが必要な場合があります。特定のバイナリの要件を満たすには、必要なすべてのバージョンをサポートするライブラリを提供する必要があります。つまり要件リスト内の少なくとも最高のバージョン記号に一致するライブラリ。

複数のバージョンが必要な理由は、インポートされた各オブジェクト(関数など)がバージョンを持つことができ、特定のバイナリが使用するすべての関数の複数のバージョンにリンクできるためです。たとえば、私のシステムで2つのバージョンを持つサンプルを選択した/lib/x86_64-linux-gnu/libgcc_s.so.1場合ldd -v

/lib/x86_64-linux-gnu/libgcc_s.so.1:
        libc.so.6 (GLIBC_2.14) => /lib/x86_64-linux-gnu/libc.so.6
        libc.so.6 (GLIBC_2.2.5) => /lib/x86_64-linux-gnu/libc.so.6

libgcc_s.so.1の2つのバージョン記号が必要ですlibc.so.6。理由を調べるには、含まれている未定義のシンボルを調べる必要があります。インポートに必要なシンボルは次のとおりです。

$ objdump -T /lib/x86_64-linux-gnu/libgcc_s.so.1|grep -F '*UND*'
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.2.5 dl_iterate_phdr
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.2.5 free
0000000000000000  w   D  *UND*  0000000000000000              __pthread_key_create
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.2.5 abort
0000000000000000  w   D  *UND*  0000000000000000              _ITM_deregisterTMCloneTable
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.2.5 strlen
0000000000000000  w   D  *UND*  0000000000000000              pthread_getspecific
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.2.5 memset
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.2.5 calloc
0000000000000000  w   D  *UND*  0000000000000000              pthread_key_create
0000000000000000  w   D  *UND*  0000000000000000              __gmon_start__
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.14  memcpy
0000000000000000  w   D  *UND*  0000000000000000              pthread_once
0000000000000000  w   DF *UND*  0000000000000000  GLIBC_2.2.5 pthread_mutex_unlock
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.2.5 malloc
0000000000000000  w   D  *UND*  0000000000000000              pthread_setspecific
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.2.5 realloc
0000000000000000  w   D  *UND*  0000000000000000              _Jv_RegisterClasses
0000000000000000  w   D  *UND*  0000000000000000              _ITM_registerTMCloneTable
0000000000000000  w   DF *UND*  0000000000000000  GLIBC_2.2.5 __cxa_finalize
0000000000000000  w   DF *UND*  0000000000000000  GLIBC_2.2.5 pthread_mutex_lock

これには、私たちが見たものと比較して見ることができるいくつかのバージョンのシンボル(2番目の列にあるシンボル)GLIBC_2.2.5がリストされています。ここでは、以前のバージョンとの互換性が重要です。バージョン2.2.5は、GNU Cライブラリのシンボリックバージョン管理のための基準です。バージョン 2.2.5 に存在するすべての機能には、そのバージョンが含まれます。 GNU Cライブラリバージョン2.13では、動作が変更され、多くのプログラムが破損しています。したがって、バージョン2.14では、オプションのバージョンタグを使用して以前のバージョンと互換性のあるバージョンが配置され、バージョンタグ付きの新しいバージョンが追加されました。したがって、古いバージョンのCライブラリでビルドされた古いバイナリは古いバージョンを使用し、バージョン2.14以降でビルドされたバイナリは新しいバージョンを使用します。GLIBC_2.14lddmemcpyGLIBC_2.2.5GLIBC_2.14memcpymemcpy

同じ内容が適用されますが、libstdc++.so.6バージョン番号が更新されるにつれて、より多くの変更が適用されます。このマニュアルにはlibstdc++詳細な情報が記載されています。

libstdc++.so.6あなたの場合は一致する必要がありますGLIBCXX_3.4.18つまりGCC 4.8.0以降で提供されているバージョンとGNU Cライブラリバージョン2.14。

RHEL 7でバイナリを簡単にビルドし、RHEL 6で実行することはできません(これがメジャーバージョンが異なる理由です)。 RHEL 6でプログラムを再構築することをお勧めします。

関連情報