2010-08-05 2 views
7

dlopen을 사용하여 사용자가 개발 한 라이브러리를로드하는 C++ 응용 프로그램에 문제가 있습니다. 이 응용 프로그램은 지난 몇 년 동안 다양한 리눅스 배포판과 OSX 버전에서 다양한 사람들이 사용 해왔고, 그래서 dlopen을 제대로 사용하고 있다고 가정하고 이에 따라 달라지는 코드가 있습니다 (예, 이것은 오만하다. 그래서 실패 할 때 다시보고 할 것이다.) 지금 내가 가진 문제는 사용자가 내 시스템 (OSX 10.6.4)에로드되지 않는 라이브러리를 개발했다는 ​​것입니다. 시스템이이를로드하려고하면 정지 후 충돌이 발생합니다. 충돌 스레드는 사고 보고서에 다음과 같습니다OSX에서 dlopen을 통해 라이브러리를 열 때 크래시 디버깅

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 

(필요한 경우 I는 전체 로그를 게시 할 수 있지만, 내가 내 게시물에 포함하는 경우 본문 제한 초과)에에서

을 터미널에서 실행 파일을 실행 중이면 충돌이 실행 파일을 실행하는 스크립트가 신호를 포착했다는 알림을 제외하고 출력이 생성되지 않습니다.

내 질문은 이 충돌의 원인에 대한 자세한 정보는 어떻게 얻을 수 있습니까? 누군가가 가능한 해결책을 제안 할 수 있으면 행복하지만 처음에는 시스템이 실제로 잘못된 것에 대해 더 많은 정보를 생성하는 방법을 알고 싶습니다.

처음에 dlopen에 의해 열려있는 라이브러리에서 otool을 실행하면 모든 것이 잘 보입니다 (누락 된 링크, 기호 등 없음). 필자의 주된 의문은로드되는 라이브러리가 어떤 이유로이 충돌을 일으키고 있는지에 대해 링크 된 라이브러리의 특정 조합이라는 것입니다. 이러한 링크 된 라이브러리의 다른 하위 집합을 사용하는 다른 라이브러리를로드 할 수 있습니다. 기록을 위해 라이브러리에는 X11, ZeroC의 Ice, Player/Stage 및 OpenCV (MacPorts를 사용하여 종속성을 수동으로 컴파일 한 후반 2)가 포함됩니다. OpenCV를 제외한 나머지 모든 라이브러리가 OpenCV를 문제없이로드 할 수 있기 때문에 문제가되는 OpenCV가 포함 된 것 같습니다. 이것은 나의 의심이지만, 나는 현재 더 자세히 조사 할 노하우가 부족하다.

감사합니다. Nick

업데이트 : Kaelin의 대답 덕분에 (DYLD_PRINT_ * 옵션에 대해 이전에 알지 못했던) 덕분에 완전히 명백한 상황이 발생하지 않았 음을 확인할 수있었습니다. 디버그 정보를 사용하여 문제를 하나의 특정 라이브러리로 좁힐 수있었습니다.이 라이브러리는 충돌을 일으켰습니다. OpenCV의 libhighgui를 통해이 라이브러리 (libdc1394가 내 응용 프로그램에 링크 됨)가 CoreServices와 올바르게 연결되지 않았으며 이것이 충돌을 일으키는 것으로 나타났습니다. 어떤 이유로 든 오류는 다른 것들에 의해 숨겨져 궁극의 충돌을 일으켰습니다. libdc1394 문제에 대한 정보는 here을보십시오. 불행히도 내가 여기서보고 할 수있는 깨끗한 수정을 만들 수 없었기 때문에, (OpenCV 컴파일에서 libdc1394를 꺼서) dodgy 라이브러리에 연결되지 않은 응용 프로그램 버전을 얻을 수있었습니다.

답변

3

dyld는 공유 라이브러리에서 초기화 프로그램을 실행하고 (C++의 정적 초기화 프로그램 생각하기), 그 중 하나가 CoreFoundation 프레임 워크의 __CFInitialize 함수를 실행하게합니다. [이것이 CoreFoundation을 만지는 것은 처음일까요?] 그리고 어떤 이유로 든 __CFInitialize는 만족스럽지 않습니다. 이것은 일종의 누락 된 종속성 일 수 있습니다. 또는 힙이 손상되었을 수 있습니다. 또는 CoreFoundation 프레임 워크에서 잠재적 인 버그 일 수 있습니다.

a) 모든 DYLD_PRINT_ * 환경 변수 ([man dyld 참조])와 MallocDebug에서 실행중인 모든 환경 변수로 실행하여 첫 번째 두 가지 가능성을 트리밍 할 것을 제안합니다. 이들 중 어떤 것도 빛을 발산하지 않는다면 CoreFoundation 사람들이 볼 수있는 레이더를 작성해야 할 것입니다.

+0

, 감사합니다. 나는이 두 가지를 시도하고 어떤 일이 일어날지를 볼 것입니다. 나중에 참조 할 수 있도록 내가 찾은 것을 다시 게시 할 것입니다. –

7

몇 가지 추가 문제와 몇 가지 추가 인터넷 검색 결과 궁극적으로 내 문제의 실제 원인을 발견했습니다.

CoreFoundation이 처음 초기화되지 않은 경우 (하위) 스레드에서 CoreFoundation과 연결된 라이브러리를 dlopen이라고 부를 수 없습니다. CFInitialize가 호출되고 스레드가 주 스레드인지 확인하고 그렇지 않은 경우 SIGTRAP과 충돌합니다. 최고

http://openradar.appspot.com/7209349

관련 문제