【问题标题】:Correctly allocate stack for clone a thread正确分配堆栈以克隆线程
【发布时间】:2018-12-29 21:27:18
【问题描述】:

所以我想创建一个没有CLONE_FILES flag 的线程。我尝试直接调用克隆,但有一些奇怪的问题。我认为这与不正确的内存分配有关。

#ifndef _GNU_SOURCE
    #define _GNU_SOURCE
#endif
#include <iostream>
#include <sys/mman.h>
#include <pthread.h>
#include <unistd.h>

const int clone_flags = (CLONE_VM | CLONE_FS | CLONE_SYSVSEM
            | CLONE_SIGHAND | CLONE_THREAD
            | CLONE_SETTLS | CLONE_PARENT_SETTID
            | CLONE_CHILD_CLEARTID
            | 0);

static int cloneThread(void* arg)
{
    long arg2 = (long)arg + (long)arg;
    long* arg2_ptr = &arg2;
    return 0;
}

int main(int argc, char** argv)
{
    const int STACK_SIZE = 0x800000;
    void* stackaddr = malloc(STACK_SIZE);
    void* stacktop  = (char*)stackaddr + STACK_SIZE; // assuming stack going downwards

    clone(cloneThread, stacktop, clone_flags, (void*)1);
    sleep(1); // wait for cloneThread running before exit
}

正如您在此处看到的,我使用 malloc 进行堆栈分配。 lldb 显示程序在cloneThread 开头崩溃。但是如果我删除long* arg2_ptr = &amp;arg2;,程序就会成功退出。

我还阅读了pthread_create.callocatestack.c的源代码。使用strace,我将malloc 替换为以下内容

void* stackaddr = mmap(NULL, STACK_SIZE, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0);
mprotect(stackaddr, STACK_SIZE, PROT_READ|PROT_WRITE);

但它的行为与使用 malloc 相同。那么应该如何使用clone呢?

操作系统:Ubuntu 18.04 LTS,g++ 7.3.0

【问题讨论】:

  • 顺便说一下,我使用 lldb 是因为 gdb 之前崩溃了。解决这个问题后,我打算在cloneThread中调用pthread_create,然后我将有一个与调用者分开的带有FD表的普通pthread。

标签: linux memory-management linux-kernel pthreads glibc


【解决方案1】:

当您提供CLONE_SETTLSCLONE_PARENT_SETTIDCLONE_CHILD_CLEARTID 标志时,您必须分别为clone() 提供newtlsptidctid 参数。

如果您只想要一个带有单独 FD 表的普通线程,只需使用 pthread_create() 并调用 unshare(CLONE_FILES) 作为新线程中的第一个操作。

【讨论】:

  • 请注意,从多线程程序调用 unshare(CLONE_FILES) 可能会产生真正奇怪的效果,因为许多库(包括 glibc 的部分)假定文件描述符是进程全局的,可以从不同的线程中使用。
  • 非常感谢!在我删除了 CLONE_SETTLS、CLONE_PARENT_SETTID 和 CLONE_CHILD_CLEARTID 之后,它现在似乎运行良好。如果以后遇到奇怪的问题,我会尝试 unshare(CLONE_FILES)。
猜你喜欢
  • 2014-07-05
  • 2011-10-09
  • 2011-11-15
  • 2016-05-09
  • 1970-01-01
  • 1970-01-01
  • 2016-08-05
  • 1970-01-01
  • 2016-12-20
相关资源
最近更新 更多