9

Linux でのライブラリのバージョン管理と、それをすべて機能させる方法についてもっと学ぼうとしています。コンテキストは次のとおりです。

- 同じインターフェイス セットを公開する動的ライブラリの 2 つのバージョンがあります。たとえばlibsome1.so、 とlibsome2.soです。

-- アプリケーションが に対してリンクされていlibsome1.soます。

-- このアプリケーションはlibdl.so、別のモジュールを動的にロードするために使用しますlibmagic.so

-- 現在libmagic.soは に対してリンクされていlibsome2.soます。明らかに、リンカー スクリプトを使用して のシンボルを非表示にしないlibmagic.soと、実行時に のインターフェイスへのすべての呼び出しlibsome2.soが に解決されlibsome1.soます。libVersion()これは、マクロの値に対してによって返される値をチェックすることで確認できますLIB_VERSION

-- それで、次に、で定義されエクスポートさlibmagic.soれる 3 つのシンボルを除くすべてのシンボルを非表示にするリンカー スクリプトを使用してコンパイルおよびリンクを試みます。libmagic.soこれは機能します...または、少なくとも値が一致libVersion()LIB_VERSIONます(そして、バージョン1ではなくバージョン2が報告されます)。

-- ただし、一部のデータ構造がディスクにシリアライズされると、いくつかの破損に気付きました。libsome1.soアプリケーションのディレクトリで、 を指す場所にソフト リンクを削除して作成するとlibsome2.so、すべてが期待どおりに機能し、同じ破損は発生しません。

これは、実行時リンカーによるシンボルの解決における競合が原因である可能性があると思わざるを得ません。libsome2.soすべてのシンボルが関連付けられるようにリンクしようとするなど、多くのことを試しました(コマンドがまだシンボルを asと notとしてリストsymbol@@VER_2しているため、まだ混乱しています)...何も機能していないようです!!! ヘルプ!!!!!!nm -CD libsome2.sosymbolsymbol@@VER_2

編集: 先に述べておくべきでしたが、問題のアプリは Firefox であり、libsome1.solibsqlite3.so梱されています。それらを再コンパイルするオプションはまったくありません。また、バージョン スクリプトを使用してシンボルを非表示にすることが、現在のところ唯一の解決策のようです。では、シンボルが隠されていると実際に何が起こるのでしょうか? それらは SO に対して「ローカル」になりますか? rtld はそれらの存在を認識していませんか? エクスポートされた関数が非表示のシンボルを参照するとどうなりますか?

4

1 に答える 1

3

libsome1.soと の両方をコンパイルしてlibsome2.so、それぞれ独自のバージョンを持つシンボルのバージョン管理を追加してみてください ( への--version-scriptオプションを使用しますld)。次に、アプリケーションをリンクlibmagic.soし、新しいライブラリを使用します。そして、完全に分離する必要がありますlibsome1.solibsome2.so

シンボルへのバージョン管理されていない参照がある場合、問題が発生する可能性があります。このような参照は、バージョン管理された定義によって満たすことができます (バイナリ互換性を損なうことなく、シンボルのバージョン管理をライブラリに追加できるようにするため)。同じ名前のシンボルが複数ある場合、どのシンボルが使用されるかを予測するのが難しい場合があります。

ツールに関しては、nm -Dシンボルのバージョン管理に関する情報は表示されません。objdump -Tまたはreadelf -s代わりに試してください。

于 2011-01-14T16:50:50.860 に答える