2012-01-27 34 views
1

我有一個克隆功能的問題,因爲它在第9次調用它後給我一個分段錯誤。程序工作正常,直到我開始使用9 +線程。第9次通話克隆產生seg故障

這裏是我的電話,克隆:

void **child_stack = (void **) malloc(SIGSTKSZ); 
clone (func, 
     (child_stack + SIGSTKSZ), 
     CLONE_VM | CLONE_FILES | CLONE_PARENT_SETTID, 
     (void *) argsForFunc, 
     &pid); 

我使用克隆,而不是任何更高級別的線程庫像並行線程。

如果有幫助,這是使用GDB時,我得到的錯誤:以上

Program received signal SIGSEGV, Segmentation fault. 
clone() at ../sysdeps/unix/sysv/linux/x86_64/clone.S:66 
66    movq %rcx,8(%rsi) 
Current language: auto; currently asm 
+1

爲什麼void ** child_stack,而不僅僅是void * child_stack? – TJD 2012-01-27 19:16:29

+0

爲什麼使用clone來代替pthread或其他線程庫? – 2012-01-28 12:52:33

回答

2

TJD的評論讓我看到了這個問題的時候了:你的指針運算,以獲取堆棧的結尾不正確。如果您分配堆棧:

void **child_stack = (void **) malloc(SIGSTKSZ); 

然後你計算堆棧的頂部爲:

child_stack + SIGSTKSZ 

通過克隆的實際地址將是

child_stack + sizeof(void*)*SIGSTKSZ 

也許你的意思爲child_stack有類型char*sizeof(char)是1的定義,所以這會給你正確的結果。

3

這裏是我的電話,克隆

不要做。在你糾正指針算術(由Jay Conrod回答)之後,由於你沒有像glibc設置的那樣設置TLS(線程本地存儲),你的代碼將會因爲競爭條件而死亡。

實際上,如果你使用直接clone電話,你不能永遠電話任何的glibc的功能(即使你在另一共享庫自己的函數(1))在新的「線程」,否則就會出現間歇性(並且非常難以調試)失敗。只需使用pthread_create()

這裏是glibc bug顯示您遇到的問題的種類(請注意,這是而不是 glibc問題)。

(1)因爲動態符號分辨率需要進入glibc。