2011-02-15 61 views
1

我的多线程应用程序(C++,SunOS)与共享库动态链接。程序中有几个线程,其中一些来自库。一种这样的线程的调用出口()并且它导致在共享库从另一个线程生成核心转储:死于多线程进程的核心转储

(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 [email protected] 
(dbx) lwps 
    [email protected] LWP suspended in __SLIP.FINAL__A() 
    [email protected] LWP suspended in find_composition_start() 
o>[email protected] signal SIGSEGV in 0x0() 

堆栈帧6-4是从利巴,从libB帧3-2。帧1必须从C++标准库(/usr/lib/libCstd.so.1?)调用。如您所见,此通话失败。

在第4帧,代码调用类型为GenPtrSortVec的全局对象的isEmpty()方法。该对象位于定义方法sm_tmr_process()的同一模块的堆栈中。稍后在第2帧,代码称为STL矢量对象的empty()方法。该向量是GenPtrSortVec类的字段。

我有一个关于这个问题,下面的问题:

  1. 为什么第一架具有地址0x0?

  2. 在取消程序中的所有线程之前,libCstd是否可能已从死亡进程中卸载?请注意,libCstd作为动态依赖项自动加载到进程中。

而关于从进程退出两个问题:

  1. 是否有可能自动加载共享库已经自动之前取消所有线程和破坏全局/静态对象卸载?

  2. 全局或静态对象可能在取消所有线程之前被销毁?

+0

** libA。cpp **: `GenPtrSortVec < SM_Timer > timeoutList; void sm_tmr_process(){ \t timeoutList.isEmpty(); }` ** libB.h **: [链接](http://pastebin.com/PdvmfiTs) – darkshine 2011-02-15 22:39:45

回答

1

对1的回答:您可能调用了一个NULL函数指针。可能不是直接的,而是间接的。你能用零覆盖一个对象的vtable,然后调用它的虚拟方法吗?

+0

只是次要澄清:V表本身通常应驻留在只读存储器(虽然我假定这是特定于实现的)。可能被覆盖的是指向vtable的指针。 – sstn 2011-02-15 19:30:58

2

1.1 - 可能是空指针呼叫(见Jörgen的)

1.2 - 无

2.1 - 无

2.2 - 可能

1.2/2.1:共享库被加载时程序被加载到内存中。然后动态链接程序将扫描所有外部引用并修复它们。这是动态链接的过程。这不会被撤消,即没有以这种方式加载的库将被操作系统卸载。一旦程序终止,整个过程映像就会被丢弃。

2.2 - 这取决于您的应用程序。全局/共享对象的初始化可能会有问题 - 请参阅静态初始化失败。这同样适用于销毁。两种情况下的顺序都是实现定义的。