正确分配堆栈以克隆线程
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.c
、allocatestack.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_SETTLS
、CLONE_PARENT_SETTID
和 CLONE_CHILD_CLEARTID
标志时,您必须提供 newtls
、ptid
和 ctid
参数clone()
分别
如果您只需要一个带有单独 FD 的普通线程 table,只需使用 pthread_create()
并调用 unshare(CLONE_FILES)
作为新线程中的第一个操作。
所以我想创建一个没有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.c
、allocatestack.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_SETTLS
、CLONE_PARENT_SETTID
和 CLONE_CHILD_CLEARTID
标志时,您必须提供 newtls
、ptid
和 ctid
参数clone()
分别
如果您只需要一个带有单独 FD 的普通线程 table,只需使用 pthread_create()
并调用 unshare(CLONE_FILES)
作为新线程中的第一个操作。