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