2010-08-05 14 views
7

Tengo un problema con una aplicación de C++ que he desarrollado que utiliza dlopen para cargar bibliotecas desarrolladas por el usuario. La aplicación ha sido utilizada por una variedad de personas en una variedad de distribuciones de linux y versiones de OSX durante los últimos años, así que estoy asumiendo que mi uso de dlopen está bien y también lo está el código que depende de él (sí, esto es arrogancia, entonces informaré cuando fracase). El problema que tengo ahora es que un usuario ha desarrollado una biblioteca que no se carga en mi sistema (OSX 10.6.4). Cuando el sistema intenta cargarlo, se congela y luego se cuelga. El hilo que se estrella es la siguiente con el informe de bloqueo:Depuración de un bloqueo cuando se abre una biblioteca mediante dlopen en OSX

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 

(me pueden enviar el registro completo si es necesario, pero se excede el límite de texto del cuerpo, si lo incluyo en mi post)

En el En la terminal donde estoy ejecutando el ejecutable, el bloqueo no produce salida a excepción de la notificación de que el script que ejecuta el ejecutable ha atrapado una señal.

Mi pregunta es ¿cómo obtengo más información sobre lo que podría estar causando este bloqueo? También estoy feliz si alguien puede sugerir posibles soluciones, pero para empezar, al menos me gustaría saber cómo generar más información cuando el sistema falla sobre lo que realmente está mal.

Si ejecuto otool en la biblioteca que está siendo abierta inicialmente por dlopen, todo se ve bien (no faltan enlaces, símbolos, etc.). Mi principal sospecha es que es la combinación particular de bibliotecas que la biblioteca que se está cargando está vinculada contra la que está causando este bloqueo de alguna manera. Estas otras bibliotecas pueden cargarse que utilizan diferentes subconjuntos de estas bibliotecas vinculadas contra. Para el registro, las bibliotecas incluyen X11, ZeroC's Ice, Player/Stage y OpenCV (las últimas 2 compiladas manualmente con dependencias instaladas usando MacPorts). Parece que es la inclusión de OpenCV la que causa el problema, ya que otras bibliotecas que enlazan con todas estas, excepto OpenCV, pueden cargarse sin problemas. Estas son mis sospechas, pero actualmente carezco de los conocimientos para investigar más a fondo.

Gracias! Nick

ACTUALIZACIÓN: Gracias a la respuesta de Kaelin (las DYLD_PRINT_ * opciones que antes no conocía) pude al menos confirmar que no estaba sucediendo nada completamente obvio. Utilizando la información de depuración, pude reducir el problema a una biblioteca en particular que estaba causando el bloqueo. Resultó que esta biblioteca (libdc1394 vinculada a mi aplicación a través de libhighgui en OpenCV) no estaba correctamente enlazada con CoreServices y esto estaba causando el colapso. Por alguna razón, el error fue ocultado por otras cosas, causando el colapso final. Para obtener información sobre el problema libdc1394, mira here. Lamentablemente, no pude solucionar el problema de manera que puedo informarlo aquí, así que me las arreglé para ejecutar una versión de la aplicación que no estaba vinculada a la biblioteca dudosa (desactivando libdc1394 en la compilación de OpenCV).

Respuesta

3

dyld está ejecutando los inicializadores en la biblioteca compartida (piensa inicializadores estáticos en C++), y uno de ellos está causando función __CFInitialize de CoreFoundation marco que se ejecute. [¿Es posible que esto sea lo primero que toque CoreFoundation?] Y por alguna razón, __CFInitialize no está contento. Esto podría ser algún tipo de dependencia faltante. O podría ser que el montón está dañado. O podría ser un error latente de algún tipo en el marco de CoreFoundation.

Sugiero recortar las dos primeras posibilidades a) ejecutando con todas las variables de entorno DYLD_PRINT_ * establecidas [ver man dyld] yb) ejecutándose bajo MallocDebug. Si ninguno de los dos arroja algo de luz, probablemente se quede escribiendo un radar para que lo mire la gente de CoreFoundation.

+0

impresionante, gracias. Voy a probar estos dos y ver qué pasa. También publicaré lo que encuentre para futuras referencias. –

7

Después de algunos otros problemas y de buscar más en Google finalmente encontré la verdadera causa de mi problema.

No se puede llamar a dlopen una biblioteca vinculada con CoreFoundation en un (sub) subproceso si CoreFoundation no se inicializó en primer lugar. Se llama a CFInitialize, aparentemente comprueba si el hilo es el hilo principal y si no lo es, se bloquea con un SIGTRAP.

http://openradar.appspot.com/7209349

Cuestiones relacionadas