第九次调用克隆产生段错误

发布于 2024-12-29 12:38:00 字数 598 浏览 1 评论 0原文

我在使用克隆函数时遇到问题,因为它在第 9 次调用它后给了我一个分段错误。程序工作正常,直到我开始使用 9 个以上的线程。

这是我对克隆的调用:

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

我使用的是克隆,而不是任何更高级别的线程库,例如 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

I am having a problem with the clone function in that it give me a segmentation fault after the 9th call to it. Program works fine until I get up to using 9+ threads.

here is my call to clone:

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

I am using clone and not any higher level threads library like pthreads.

If it helps, this is the error I get when using 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

青衫负雪 2025-01-05 12:38:00

这是我对克隆的调用

“不要这样做”。在你纠正指针算术之后(如 Jay Conrod 的回答),你的代码将由于竞争条件而可怕地死亡,因为你没有按照 glibc 期望的方式设置 TLS(线程本地存储)。

实际上,如果您使用直接clone 调用,则您永远无法在新版本中调用任何 glibc 函数(甚至不能在另一个共享库 (1) 中调用您自己的函数)。 “线程”,否则您将面临间歇性(并且极其难以调试)故障的风险。只需使用 pthread_create() 即可。

这是 glibc bug 显示您将遇到的问题类型(注意这不是 glibc 问题)。

(1) 因为动态符号解析需要访问 glibc。

here is my call to clone

Don't do that. After you correct pointer arithmetic (as answered by Jay Conrod), your code will die horrible death due to a race condition, because you are not setting up TLS (thread-local storage) the way glibc expects it to be set up.

Effectively, if you use direct clone calls, you can't ever call any of glibc functions (not even your own functions in another shared library (1)) in the new "thread", or you risk intermittent (and exceedingly hard to debug) failures. Just use pthread_create() instead.

Here is the glibc bug showing the kinds of problems you'll run into (note that this is not a glibc problem).

(1) Because dynamic symbol resolution requires a trip into glibc.

橘亓 2025-01-05 12:38:00

TJD 上面的评论让我立即看到了问题:您获取堆栈末尾的指针算术不正确。如果您将堆栈分配为:

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

然后计算堆栈顶部为:

child_stack + SIGSTKSZ

传递给克隆的实际地址将是

child_stack + sizeof(void*)*SIGSTKSZ

也许您的意思是 child_stack 具有类型 char*sizeof(char) 根据定义为 1,这样就能得到正确的结果。

TJD's comment above made me see the problem right away: your pointer arithmetic to get the end of the stack is incorrect. If you allocate the stack as:

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

And then you calculate the top of the stack as:

child_stack + SIGSTKSZ

The actual address passed to clone will be

child_stack + sizeof(void*)*SIGSTKSZ

Maybe you meant for child_stack to have type char*? sizeof(char) is 1 by definition, so that would give you the right result.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文