Felsökning av en krasch när ett bibliotek öppnas via dlopen på OSX

Felsökning av en krasch när ett bibliotek öppnas via dlopen på OSX


Jag har ett problem med en C++-applikation jag har utvecklat som använder dlopen för att ladda användarutvecklade bibliotek. Applikationen har använts av en mängd människor på en mängd olika Linux-distros och versioner av OSX under de senaste åren och så jag antar att min användning av dlopen är OK och så är koden som beror på det (ja, detta är hybris, så jag återkommer när det misslyckas). Problemet jag har nu är att en användare har utvecklat ett bibliotek som inte laddas på mitt system (OSX 10.6.4). När systemet försöker ladda det uppstår en frysning och sedan en krasch. Tråden som kraschar ser ut så här i kraschrapporten:


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

(Jag kan lägga upp hela loggen om det behövs, men det överskrider gränsen för brödtext om jag inkluderar det i mitt inlägg)


I terminalen där jag kör den körbara filen producerar kraschen ingen utdata förutom meddelandet om att skriptet som kör den körbara har fångat en signal.


Min fråga är hur får jag mer information om vad som kan orsaka denna krasch? Jag är också glad om någon kan föreslå möjliga lösningar, men till att börja med skulle jag åtminstone vilja veta hur man genererar mer information när systemet kraschar om vad som faktiskt är fel.


Om jag kör otool på biblioteket som initialt öppnas av dlopen ser allt bra ut (inga saknade länkar, symboler etc). Min huvudsakliga misstanke är att det är den speciella kombinationen av bibliotek som biblioteket som laddas är länkat mot som på något sätt orsakar denna krasch. Dessa andra bibliotek kan laddas som använder olika delmängder av dessa länkade-mot-bibliotek. För ordens skull inkluderar biblioteken X11, ZeroCs Ice, Player/Stage och OpenCV (med de 2 sistnämnda kompilerade manuellt med beroenden installerade med MacPorts). Det verkar vara införandet av OpenCV som orsakar problemet, eftersom andra bibliotek som länkar till alla dessa förutom OpenCV kan laddas utan problem. Detta är mina misstankar, men jag saknar för närvarande kunskapen för att undersöka vidare.


Tack! Nick


UPPDATERING: Tack vare Kaelins svar (alternativen DYLD_PRINT_* som jag inte var medveten om tidigare) kunde jag åtminstone bekräfta att inget helt uppenbart hände. Med hjälp av felsökningsinformationen kunde jag begränsa problemet till ett särskilt bibliotek som orsakade kraschen. Det visade sig att det här biblioteket (libdc1394 länkat till min app via libhighgui i OpenCV) inte var korrekt länkat mot CoreServices och detta orsakade kraschen. Av någon anledning doldes felet sedan av andra saker, vilket orsakade den ultimata kraschen. För information om libdc1394-problemet, titta här. Tyvärr kunde jag inte göra en ren fix som jag kan rapportera här, så jag lyckades precis få igång en version av appen som inte länkade till det tvivelaktiga biblioteket (genom att stänga av libdc1394 i OpenCV-kompileringen).


Svar:


dyld kör initierarna i det delade biblioteket (tänk statiska initierare i C++), och en av dem gör att CoreFoundations ramverks __CFinitialize-funktion körs. [Är det möjligt att detta är det första som rör CoreFoundation?] Och av någon anledning är __CFinitialize inte nöjd. Detta kan vara någon form av saknat beroende. Eller så kan det vara att högen är skadad. Eller det kan vara en latent bugg av något slag i CoreFoundation-ramverket.


Jag skulle föreslå att du beskär de två första möjligheterna genom att a) köra med alla DYLD_PRINT_*-miljövariablerna [se man dyld ] och b) körs under MallocDebug. Om ingen av dessa kastar något ljus, har du förmodligen kvar att skriva en radar som CoreFoundation-folket kan titta på.


Några kodsvar


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