正确分配堆栈以克隆线程

Correctly allocate stack for clone a thread

所以我想创建一个没有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 = &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 的行为相同。那么我应该如何使用克隆呢?

OS:Ubuntu 18.04 LTS,g++ 7.3.0

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

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