【发布时间】:2011-02-15 17:38:02
【问题描述】:
我的多线程应用程序(C++、SunOS)与共享库动态链接。程序中有几个线程,其中一些来自库。其中一个线程调用 exit() 并导致从共享库中的另一个线程生成核心转储:
(dbx) where
[1] 0x0(0xbeee0b30, 0x0, 0x0, 0x1c00, 0x1, 0xbeee0b50), at 0x0
[2] STLCollectionWrapper<std::vector<SM_Timer*,std::allocator<SM_Timer*> > >::empty(0xbeee0b30, 0x0, 0x0, 0x1c00, 0xbca12200, 0x0), at 0xbee04690
[3] GenPtrSortVec<SM_Timer,std::less<SM_Timer>,std::allocator<SM_Timer> >::isEmpty(0xbeee0b30, 0x0, 0x0, 0x0, 0x4fb0e0, 0xbd436b90), at 0xbee04424
[4] sm_tmr_process(0x341000, 0x8e400, 0xbeeba00f, 0x1c00, 0x1, 0xbeee0800), at 0xbee03968
[5] sm_nm_process_timeouts(0xbc67bf94, 0xbc67bf98, 0xbd4c3800, 0x0, 0xbca12200, 0xbee830f0), at 0xbee813dc
[6] TimerThreadObject::poll(0x0, 0xbc67c000, 0x0, 0x0, 0xbedf1530, 0x1), at 0xbedf15f4
(dbx) thread
current thread ($thread) is t@null
(dbx) lwps
l@1 LWP suspended in __SLIP.FINAL__A()
l@3 LWP suspended in find_composition_start()
o>l@6 signal SIGSEGV in 0x0()
堆栈帧 6-4 来自 libA,帧 3-2 来自 libB。第 1 帧必须是从 C++ 标准库 (/usr/lib/libCstd.so.1?) 调用的。如您所见,此调用失败。
在第 4 帧,代码调用了 GenPtrSortVec 类型的全局对象的 isEmpty() 方法。该对象位于定义方法 sm_tmr_process() 的同一模块的堆栈中。后来在第 2 帧,代码调用了 STL 向量对象的 empty() 方法。这个向量是 GenPtrSortVec 类的一个字段。
我有以下关于这个问题的问题:
为什么第一帧的地址是 0x0?
在取消程序中的所有线程之前,libCstd 是否可能已从垂死的进程中卸载?请注意,libCstd 会作为动态依赖项自动加载到进程中。
还有两个关于退出流程的问题:
是否有可能在取消所有线程并销毁全局/静态对象之前自动卸载了自动加载的共享库?
是否有可能在取消所有线程之前已销毁全局或静态对象?
【问题讨论】:
-
libA.cpp:
GenPtrSortVec< SM_Timer > timeoutList; void sm_tmr_process(){ timeoutList.isEmpty(); }libB.h:link
标签: c++ multithreading shared-libraries solaris coredump