16

Linux上に(別の共有ライブラリを介して)依存関係の1つとしてロードするlibfoo.so.1(つまり)実行可能ファイルがあります。SONAMEまた、別のシステムライブラリにリンクし、システムライブラリはシステムバージョンにリンクしますlibfoo.so.2。その結果、との両方 実行中に読み込まれ、バージョン1のライブラリから関数を呼び出すはずだったコードは、バージョン2の新しいシステムライブラリから(バイナリ非互換の)関数を呼び出すことになります。これは、一部のシンボルが同じままであるためです。その結果、通常、スタックスマッシングとそれに続くセグメンテーションフォールトが発生します。libfoo.so.1libfoo.so.2

現在、古いバージョンに対してリンクしているライブラリはクローズドソースのサードパーティライブラリであり、どのバージョンlibfooに対してコンパイルするかを制御することはできません。と仮定すると、残っている他の唯一のオプションは、現在リンクしているシステムライブラリの束を再構築しlibfoo.so.2てリンクすることlibfoo.so.1です。

古いものにリンクするローカルコピーでシステムライブラリを置き換えることを回避する方法はありますlibfooか?両方のライブラリをロードして、正しいバージョンのシンボルを呼び出すコードを作成できますか?だから私はいくつかの特別なシンボルレベルのバージョン管理が必要ですか?

4

2 に答える 2

8

バージョン スクリプトのいくつかのトリックを実行できる場合があります。

http://sunsite.ualberta.ca/Documentation/Gnu/binutils-2.9.1/html_node/ld_26.html

これには、一部のシンボルを明示的にエクスポートし、他のすべてをローカルとしてマスクする libfoo.so.1 を取り込む lib の周りにラッパーを作成する必要がある場合があります。例えば:

MYSYMS { グローバル: foo1; foo2; ローカル: *; };

次のようにラッパーをリンクするときにこれを使用します。

gcc -shared -Wl,--version-script,mysyms.map -o mylib wrapper.o -lfoo -L/path/to/foo.so.1

これにより、libfoo.so.1 のシンボルがラッパーに対してローカルになり、メインの exe では使用できなくなります。

于 2008-10-24T16:15:45.093 に答える
0

回避策しか思いつきません。これは、使用している「システム ライブラリ」のバージョンを静的にリンクすることです。静的ビルドの場合、サードパーティ ライブラリと同じ古いバージョンに対してリンクすることができます。新しいバージョンに依存していないことを考えると...

通常の方法でサードパーティのライブラリにリンクしないことで、これらの問題を回避することも可能かもしれません。代わりに、プログラムは実行時にそれをロードできます。おそらく、それは残りの部分に影を落とす可能性があります。しかし、私はそれについてあまり知りません。

于 2008-10-23T01:22:48.527 に答える