7

dlopen を使用してユーザーが開発したライブラリをロードする、私が開発した C++ アプリケーションに問題があります。このアプリケーションは、過去数年間、さまざまな Linux ディストリビューションや OSX のバージョンでさまざまな人々によって使用されてきたので、私の dlopen の使用は問題なく、それに依存するコードも問題ないと思います (ええ、これは傲慢なので、失敗したら報告します)。私が今抱えている問題は、ユーザーが開発したライブラリが私のシステム (OSX 10.6.4) にロードされないことです。システムがそれを読み込もうとすると、フリーズしてからクラッシュします。クラッシュ レポートでは、クラッシュするスレッドは次のようになります。

Thread 5 Crashed:
0   com.apple.CoreFoundation        0x00007fff80fa6110 __CFInitialize + 1808
1   dyld                            0x00007fff5fc0d5ce ImageLoaderMachO::doImageInit(ImageLoader::LinkContext const&) + 138
2   dyld                            0x00007fff5fc0d607 ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) + 27
3   dyld                            0x00007fff5fc0bcec ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int) + 236
4   dyld                            0x00007fff5fc0bc9d ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int) + 157
5   dyld                            0x00007fff5fc0bc9d ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int) + 157
6   dyld                            0x00007fff5fc0bc9d ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int) + 157
7   dyld                            0x00007fff5fc0bc9d ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int) + 157
8   dyld                            0x00007fff5fc0bc9d ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int) + 157
9   dyld                            0x00007fff5fc0bda6 ImageLoader::runInitializers(ImageLoader::LinkContext const&) + 58
10  dyld                            0x00007fff5fc08fbb dlopen + 573
11  libSystem.B.dylib               0x00007fff816492c0 dlopen + 61
12  cast-server-c++                 0x0000000100007819 cast::loadLibrary(std::string const&) + 96 (ComponentCreator.cpp:43)
13  cast-server-c++                 0x00000001000079c7 cast::createComponentCreator(std::string const&) + 24 (ComponentCreator.cpp:87)
14  cast-server-c++                 0x00000001000089c5 cast::CASTComponentFactory::createBase(std::string const&, std::string const&, Ice::Current const&) + 197 (CASTComponentFactory.cpp:27)
15  cast-server-c++                 0x00000001000090e9 cast::CASTComponentFactory::newManagedComponent(std::string const&, std::string const&, bool, Ice::Current const&) + 73 (CASTComponentFactory.cpp:62)
16  libCDL.dylib                    0x00000001009ceb6c cast::interfaces::ComponentFactory::___newManagedComponent(IceInternal::Incoming&, Ice::Current const&) + 218 (CDL.cpp:14904)
17  libCDL.dylib                    0x00000001009cf1d0 cast::interfaces::ComponentFactory::__dispatch(IceInternal::Incoming&, Ice::Current const&) + 572 (CDL.cpp:15057)
18  libIce.3.3.1.dylib              0x00000001000c9078 IceInternal::Incoming::invoke(IceInternal::Handle<IceInternal::ServantManager> const&) + 2004 (Incoming.cpp:484)
19  libIce.3.3.1.dylib              0x0000000100091a5d Ice::ConnectionI::invokeAll(IceInternal::BasicStream&, int, int, unsigned char, IceInternal::Handle<IceInternal::ServantManager> const&, IceInternal::Handle<Ice::ObjectAdapter> const&) + 367 (ConnectionI.cpp:2436)
20  libIce.3.3.1.dylib              0x000000010009bb40 Ice::ConnectionI::message(IceInternal::BasicStream&, IceInternal::Handle<IceInternal::ThreadPool> const&) + 416 (ConnectionI.cpp:1105)
21  libIce.3.3.1.dylib              0x00000001001a9bbc IceInternal::ThreadPool::run() + 3470 (ThreadPool.cpp:523)
22  libIce.3.3.1.dylib              0x00000001001aa4ec IceInternal::ThreadPool::EventHandlerThread::run() + 152 (ThreadPool.cpp:782)
23  libIceUtil.3.3.1.dylib          0x00000001006eb1e9 startHook + 128 (Thread.cpp:375)
24  libSystem.B.dylib               0x00007fff8167c456 _pthread_start + 331
25  libSystem.B.dylib               0x00007fff8167c309 thread_start + 13

(必要に応じて完全なログを投稿できますが、投稿に含めると本文テキストの制限を超えます)

実行可能ファイルを実行しているターミナルでは、実行可能ファイルを実行しているスクリプトがシグナルをトラップしたという通知を除いて、クラッシュは出力を生成しません。

私の質問は、このクラッシュの原因についてより多くの情報を得るにはどうすればよいですか? 誰かが考えられる解決策を提案してくれるのもうれしいですが、まず、システムがクラッシュしたときに実際に何が問題なのかについて、より多くの情報を生成する方法を知りたいと思います。

最初に dlopen によって開かれているライブラリで otool を実行すると、すべてが正常に見えます (リンクの欠落、シンボルなどはありません)。私の主な疑いは、ロードされているライブラリがリンクされているライブラリの特定の組み合わせが、何らかの形でこのクラッシュを引き起こしているということです。これらのリンクされたライブラリの異なるサブセットを使用するこれらの他のライブラリをロードできます。記録のために、ライブラリには X11、ZeroC の Ice、Player/Stage、および OpenCV が含まれます (後者の 2 つは MacPorts を使用してインストールされた依存関係で手動でコンパイルされます)。OpenCVを除くこれらすべてにリンクする他のライブラリは問題なくロードできるため、OpenCVが含まれていることが問題の原因のようです。これらは私の疑いですが、現在、さらに調査するためのノウハウが不足しています.

ありがとう!ニック

更新: Kaelin の回答 (以前は認識していなかった DYLD_PRINT_* オプション) のおかげで、少なくとも完全に明白なことが何も起こっていないことを確認できました。デバッグ情報を使用して、クラッシュの原因となっている特定のライブラリに問題を絞り込むことができました。このライブラリ (OpenCV で libhighgui を介してアプリにリンクされた libdc1394) が CoreServices に対して正しくリンクされておらず、これがクラッシュの原因であることが判明しました。何らかの理由で、エラーが他のものによって隠され、最終的なクラッシュが発生しました。libdc1394 の問題については、こちらを参照してください。残念ながら、ここで報告できる完全な修正を行うことができなかったため、危険なライブラリにリンクしていないバージョンのアプリを実行することができました (OpenCV コンパイルで libdc1394 をオフにすることにより)。

4

2 に答える 2

7

さらにいくつかの問題とさらにいくつかのグーグルの後、私は最終的に私の問題の本当の原因を見つけました。

CoreFoundation が最初に初期化されていない場合、(サブ) スレッドで CoreFoundation にリンクされたライブラリを dlopen を呼び出すことはできません。CFInitialize が呼び出され、スレッドがメイン スレッドであるかどうかを明らかにチェックし、そうでない場合は SIGTRAP でクラッシュします。

http://openradar.appspot.com/7209349

于 2010-09-09T09:50:28.207 に答える
3

dyld は共有ライブラリ (C++ の静的初期化子と考えてください) で初期化子を実行しており、そのうちの 1 つが CoreFoundation フレームワークの __CFInitialize 関数を実行させています。[これが最初に CoreFoundation に触れる可能性はありますか?] そして、何らかの理由で、__CFInitialize は満足していません。これは、ある種の欠落している依存関係である可能性があります。または、ヒープが破損している可能性があります。または、CoreFoundation フレームワークの潜在的なバグである可能性があります。

最初の 2 つの可能性は、a) DYLD_PRINT_* 環境変数をすべて設定して実行すること [参照man dyld] と、b) MallocDebug の下で実行することによって削減することをお勧めします。どちらも光を当てていない場合は、おそらく、CoreFoundation の人々が見るレーダーを作成する必要があります。

于 2010-08-10T16:46:31.420 に答える