2011-02-15 48 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 - 這取決於您的應用程序。全局/共享對象的初始化可能會有問題 - 請參閱靜態初始化失敗。這同樣適用於銷燬。兩種情況下的順序都是實現定義的。