第9次调用克隆会产生seg错误

时间:2012-01-27 18:47:50

标签: c linux segmentation-fault clone

我遇到克隆功能的问题,因为它在第9次调用后给我一个分段错误。程序运行正常,直到我开始使用9+个线程。

这是我对克隆的呼吁:

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

我正在使用clone而不是像pthreads那样的任何更高级别的线程库。

如果有帮助,这是我在使用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

2 个答案:

答案 0 :(得分:3)

  

这是我对克隆的呼吁

不要那个。在你纠正指针运算后(由Jay Conrod回答),你的代码会因竞争条件而死亡,因为你没有像glibc预期的那样设置TLS(线程本地存储)。

实际上,如果你使用直接clone调用,你就不能永远调用新的任何glibc函数(甚至不是你自己在另一个共享库中的函数(1)) “线程”,或者你冒着间歇性(并且极难调试)失败的风险。只需使用pthread_create()代替。

这是glibc bug,显示了您将遇到的各种问题(请注意,这是不是 glibc问题)。

(1)因为动态符号分辨率要求进入glibc。

答案 1 :(得分:2)

TJD上面的评论让我立刻看到了问题:你的指针算术得到了堆栈的结尾是不正确的。如果将堆栈分配为:

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

然后你计算堆栈的顶部为:

child_stack + SIGSTKSZ

传递给克隆的实际地址为

child_stack + sizeof(void*)*SIGSTKSZ

也许您的意思是child_stackchar*类型?根据定义,sizeof(char)为1,因此可以为您提供正确的结果。