Linux の C++ 共有ライブラリに奇妙な問題があります。
このプロセスはライブラリを 2 回ロードおよびアンロードします (これは設計によるものであり、変更できません)。
- 最初の dlopen() で、ライブラリ内のすべての静的メンバーが正しい順序で初期化されます。
- 次に、最初の dlclose() が呼び出されると、破壊も期待どおりに、構築とは逆の順序で行われます。
- 2 回目の dlopen() では、すべて問題ありません。最初と同じように、構築の順序は正しいです。
- しかし、2 番目の dlclose() で、破棄の順序が突然破られます。デストラクタは、初期化されたときと同じ順序で呼び出され、静的オブジェクトがすでに破棄されたオブジェクトにアクセスしようとすると、SEGFAULT が発生することがよくあります。
- その後 dlopen()/dlclose() を試みると、3 番目と 4 番目のステップが正確に繰り返されます。
最小限の例で問題を再現しようとしましたが、成功しませんでした.小さな偽の共有ライブラリでは、すべてが期待どおりに機能します. 私の大きなライブラリには、2 番目の dlclose() で大混乱を引き起こすものがあり、それは非常に大きいです。
gcc (3.2/3.4/4.1.2 を試した) や Linux ディストリビューション (RHEL 4/5、SuSE 10) への依存関係は見つかりませんでした。Web で同様のケースを検索すると、0 件の結果が得られました。類似したケースはありません。
実験中、atexit() ハンドラーの順序が影響を受けるかどうかを確認するために、atexit() へのいくつかの呼び出しを静的オブジェクト コンストラクターに埋め込もうとしましたが、影響があることがわかりました。手順 1/2/3 は正常に機能します (dlopen/dlclose/dlopen)。2 番目の dlclose では、atexit に登録されたハンドラーの順序が正しくありません。
答えが得られるとはあまり期待していませんが、問題を追求する方法についての提案をいただければ幸いです。
前もって感謝します、
アンドリュー・シェティニン
PS Update - GLIBC で atexit() のコードをデバッグしたところ、ヒットしているバグがあることがわかりました。実際には非常に単純なバグです。GLIBC 2.4 で修正されましたが、GLIBC 2.3.4 で作業できなかったのは不運でした。