次の簡単なプログラムがあります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
現在インストールされているライブラリのマイナーバージョンが低すぎるというエラーが発生しますか? - プログラムがバージョンを識別し、マイナーバージョンが十分であることを確認するために、ライブラリの特殊関数を呼び出す必要がありますか?
- プログラムの実行を開始する前に、ライブラリローダはすべてのシンボルを確認する必要がありますか?
- バージョン番号を誤って理解したか、マイナーバージョンを確認する設定を見逃したのでしょうか?
答え1
バージョン番号を誤解したわけではありません。これは実際にはシンボル検索が頻繁に必要な領域です。
これが誰の責任であるかについては、現代のシステムでは、ライブラリではなくアプリケーションを構築する人に属すると言いたいと思います。アプリケーションをld -z now
(少なくともGNU binutilsで)接続すると、動的リンカーは起動時にすべてのシンボルをチェックします。シンボルが欠落していると早期に失敗します。したがって、手動手動チェックを追加する必要はありません。LD_BIND_NOW=1
環境にエクスポートしてプログラムをリンクした後、この動作を有効にすることができます(null以外のすべての値は可能ですが、これはLinuxに限定されません)。
これらの問題は通常、パッケージ管理システムによって処理されます。パッケージ管理システムは、シンボリックバージョン要件を説明する広範なメタデータを維持し、適切なバージョン依存関係を生成します。ライブラリの作成者も状況を改善するのに役立ちますが、これにはかなりの労力が必要な場合があります。 GNU libcの特殊バージョンシンボル(GLIBC_...
エラーメッセージによく表示されるシンボル)とバージョン付きシンボルの包括的な処理を参照してください。