0

我試圖用ltalloc構建我的應用程序。我用MinGW32 4.9.1和MinGW64-32 4.9.2試了一下。 它編譯和鏈接很好,但是當我運行它時發生分段錯誤。調試精確定位的問題下面的代碼:爲什麼我在使用MinGW添加ltalloc時遇到了分段錯誤

#include <pthread.h> 
#pragma weak pthread_once 
#pragma weak pthread_key_create 
#pragma weak pthread_setspecific 
static pthread_key_t pthread_key; 
static pthread_once_t init_once = PTHREAD_ONCE_INIT; 
static void init_pthread_key() { pthread_key_create(&pthread_key, release_thread_cache); } 
static thread_local int thread_initialized = 0; 
static void init_pthread_destructor()//must be called only when some block placed into a thread cache's free list 
{ 
    if (unlikely(!thread_initialized)) 
    { 
     thread_initialized = 1; 
     if (pthread_once) 
     { 
      pthread_once(&init_once, init_pthread_key); // <--- THIS CAUSES THE SEGSEGV 
      pthread_setspecific(pthread_key, (void*)1);//set nonzero value to force calling of release_thread_cache() on thread terminate 
     } 
    } 
} 

據我知道,這兩個版本都支持線程本地存儲本身。的ltalloc的維基還寫道:

警告:在一些建立的MinGW的存在與emutls和線程析構函數(所有線程局部變量之前銷燬)的執行順序的問題,和因任何原因終止線程將導致應用程序崩潰。

不幸的是,這個警告並沒有告訴我任何東西。谷歌搜索它也沒有讓我變得更聰明。

+0

爲什麼使用線程特定變量('thread_initialized')初始化全局'init_pthread_key'? – alk 2015-04-01 16:25:28

回答

1

出於藍,試試這個:

static void init_pthread_key(void) 
{ 
    if (pthread_key_create) 
    { 
    pthread_key_create(&pthread_key, release_thread_cache); 
    } 
} 

還加入了全部的差錯檢驗到pthread_*可能在調試過程中,不僅幫助。

+0

該定義使pthread_once不會崩潰。但是現在sigsegv出現在pthread_setspecific中。這是什麼意思?我如何啓用pthread的全部錯誤檢查? – 2015-04-01 19:43:27

+1

@JackSabbath:然後是同樣的問題。所以只需在調用'pthread_setspecific'之前測試與'NULL'不同的''''。用「*完整的錯誤檢查*」我引用了測試用於指示錯誤的'pthread_ *'函數'返回值的可能性。 – alk 2015-04-01 19:45:26

+0

是的,這個函數也沒有找到,因此你的建議避免了SIGSEGV。但是,我認爲這並不能解決問題。這些函數調用背後的想法是有一個回調函數,它將清理thread_local數據(它們不能有析構函數,因爲thread_local數據對於GCC來說是不重要的,如果我不調用這些函數,不清理這些函數是什麼原因存在,所以這些函數是0編譯器和鏈接器不會抱怨,所以我不明白這個函數怎麼可能找不到。 – 2015-04-03 13:31:44

相關問題