You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux arm64下使用clone3系统调用实现线程触发段故障的问题

在Linux arm64平台使用clone3实现线程的问题与解决

问题描述

在Linux arm64平台上,尝试通过clone和clone3系统调用实现线程功能,但无法成功启动线程(克隆进程后执行execve是可行的)。预期效果是像pthread_create()一样启动线程并调用指定的start_routine()。

初始实现代码

C代码

unsigned long flags = (CLONE_VM | 
            CLONE_FS | 
            CLONE_FILES | 
            CLONE_SYSVSEM |
            CLONE_SIGHAND | 
            CLONE_SETTLS |
            CLONE_THREAD | 
            CLONE_PARENT_SETTID |
            CLONE_CHILD_CLEARTID);

size_t stack_size = 8*1024*1024;

void *stack = mmap(NULL, 
        stack_size, 
        PROT_READ | PROT_WRITE, 
        MAP_ANONYMOUS | MAP_PRIVATE | MAP_GROWSDOWN, 
        -1, 
        0);

struct clone_args args = { 0 };
args.flags = flags;
args.tls = stack;
args.stack = stack + 0x1000;
args.stack_size = stack_size;

int ret = _syscall_clone3(&args, sizeof(struct clone_args));
if (ret < 0)
{
    return -1;
}

if (ret != 0) {
    // This is printed on console
    printf("continue from thread %d\n", gettid());
}
else {
    // This never gets executed
    printf("In thread %d\n", gettid());
        start_routine(arg);
    exit(0);
}

汇编实现(_syscall_clone3)

__syscall_clone3:
    mov x8, #435
    svc #0
    ret

调试与解决过程

调试后发现栈为空,这是触发段故障的原因,推测编译器未正确填充栈,和C语言的工作机制有关。

研究libc实现后,发现部分实现会用汇编为start_routine做包装函数。修改汇编函数,新增传递参数并调用start_routine的逻辑:

// __syscall_clone3(args, sizeof(args), start_routine, start_routine_arg)
__syscall_clone3:
    mov x8, #435
    svc #0
    ...
    mov x0, x3
    blr x2
    ret

修改后代码可正常工作,实现了预期的线程启动功能。


内容的提问来源于stack exchange,提问作者m3n

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 14:52:23