7

我开发的 C++ 应用程序使用 dlopen 加载用户开发的库时遇到问题。在过去的几年里,该应用程序已被各种 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_* 选项),我至少能够确认没有完全明显的事情发生。使用调试信息,我能够将问题缩小到导致崩溃的一个特定库。事实证明,这个库(libdc1394 通过 OpenCV 中的 libhighgui 链接到我的应用程序)没有正确链接到 CoreServices,这导致了崩溃。由于某种原因,错误随后被其他事物隐藏,导致最终崩溃。有关 libdc1394 问题的信息,请查看此处。不幸的是,我无法在此处报告一个干净的修复程序,因此只能设法获得一个未链接到狡猾库的应用程序版本(通过在 OpenCV 编译中关闭 libdc1394)。

4

2 回答 2

7

经过一些进一步的问题和进一步的谷歌搜索后,我最终找到了问题的真正原因。

如果 CoreFoundation 一开始没有被初始化,则不能在(子)线程中调用 dlopen 与 CoreFoundation 链接的库。CFInitialize 被调用,显然检查线程是否是主线程,如果不是,则使用 SIGTRAP 崩溃。

http://openradar.appspot.com/7209349

于 2010-09-09T09:50:28.207 回答
3

dyld 正在共享库中运行初始化程序(想想 C++ 中的静态初始化程序),其中之一是导致 CoreFoundation 框架的 __CFInitialize 函数运行。[这可能是接触 CoreFoundation 的第一件事吗?] 无论出于何种原因,__CFInitialize 都不高兴。这可能是某种缺失的依赖。或者它可能是堆已损坏。或者它可能是 CoreFoundation 框架中的某种潜在错误。

我建议通过 a) 运行所有 DYLD_PRINT_* 环境变量集 [参见man dyld] 和 b) 在 MallocDebug 下运行来调整前两种可能性。如果这些都没有阐明,那么您可能需要编写一个雷达供 CoreFoundation 人员查看。

于 2010-08-10T16:46:31.420 回答