带有 futex 崩溃的 C 克隆地址处映射区域的权限错误

如何解决带有 futex 崩溃的 C 克隆地址处映射区域的权限错误

我正在尝试创建 64 个线程,我给每个线程 65536 个字节作为堆栈......但是从堆栈的顶部开始,我用 64 个字节来存储线程函数参数(前 4 个字节是线程 ID( 0 到 63),第二个 4 字节是线程消息长度(传递给 'write()'),从字节 8 开始,它是由 sprintf 创建的线程消息(在线程创建之前(clone())))。在每个线程进程的顶部,我使用了:

syscall(SYS_futex,& __THREADS_STATUS[thread_id],FUTEX_WAIT,NULL,0);

让线程进入休眠状态,直到我们唤醒它:

syscall(SYS_futex,& __THREADS_STATUS[i],FUTEX_WAKE,1,0);

一个线程醒来时,它使用lock方法锁定线程写进程然后写它的消息然后解锁被锁定的用户空间...

我们要唤醒15个线程来一个一个地写他们的消息(这就是为什么我用了locked!否则写的顺序不会被观察到)...

我预期的结果:

Thread #0 started
Thread #1 started
Thread #2 started
Thread #3 started
Thread #4 started
Thread #5 started
Thread #6 started
Thread #7 started
Thread #8 started
Thread #9 started
Thread #10 started
Thread #11 started
Thread #12 started
Thread #13 started
Thread #14 started

我得到了什么错误!!!!

Thread #0 started
Thread #2 started
Thread #12 started
Thread #11 started

==48072== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==48072==  Bad permissions for mapped region at address 0x400BF0
==48072==    at 0x400A8D: thread_main (in /tmp/tmp.x9XSQBiKue/cmake-build-release/threads_manager)
==48072==    by 0x4F3EDC2: clone (in /usr/lib64/libc-2.28.so)
==48072==    by 0x1200000001: ???
==48072==    by 0x2320646165726853: ???
==48072==    by 0x6574726174732031: ???
==48072==    by 0xA63: ???

这是我的源代码(完整):

#define _GNU_SOURCE
#include <sched.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <syscall.h>
#include <sys/mman.h>
#include <linux/futex.h>
#include <stdatomic.h>

#define THREADS_COUNT       64
#define THREAD_STACK_SIZE   65536
#define THREAD_FLAGS        (CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_PARENT|CLONE_THREAD|CLONE_IO)

static int  thread_main(void * data);
static void thread_lock(int * user_space);
static void thread_unlock(int * user_space);

static int __THREADS_STATUS[THREADS_COUNT];
static int __THREADS_WRITE_LOCK = 1; /* 1 = available */

int
main() {
    void * memory;

    if((memory = mmap(0,(THREADS_COUNT * THREAD_STACK_SIZE),PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0)) == MAP_Failed) {
        printf("mmap() Failed");
        return 1;
    }
    for (int i = 0; i < THREADS_COUNT; i++) {
        unsigned long long thread_stack_address = (unsigned long long) memory + THREAD_STACK_SIZE + (i * THREAD_STACK_SIZE) - 64;
        /*
         * At the end of each stack,we reserve 64 bytes to store:
         * [0-4] => thread id
         * [4-8] => thread message length to pass to 'write()'
         * [8-n] => thread message to pass to 'write()'
         */
        (*(int *)(thread_stack_address)) = i;
        (*(int *)(thread_stack_address + 4)) = sprintf((char *)(thread_stack_address + 8),"Thread #%d started\n",i);
        if(clone(thread_main,(void *) thread_stack_address,THREAD_FLAGS,(void *) thread_stack_address) == -1) {
            printf("clone() Failed");
            munmap(memory,(THREADS_COUNT * THREAD_STACK_SIZE));
            return 1;
        }
    }
    for (int i = 0; i < 15; i++) {
        syscall(SYS_futex,0);
    }
    sleep(3);
    munmap(memory,(THREADS_COUNT * THREAD_STACK_SIZE));
    return 0;
}

static int
thread_main(void * data) {
    int thread_id = (*(int *)(data));
    int thread_msg_len = (*(int *)(data + 4));
    char * thread_msg = (data + 8);

    // Wait to woken up by the main process
    syscall(SYS_futex,0);
    // Lock to write then unlock ...
    thread_lock(& __THREADS_WRITE_LOCK);
    write(0,thread_msg,thread_msg_len);
    thread_unlock(& __THREADS_WRITE_LOCK);
    return 0;
}

static void
thread_lock(int * user_space) {
    while (1) {
        static const int one = 1;
        if(atomic_compare_exchange_strong(user_space,& one,0))
            break;
        syscall(SYS_futex,user_space,0);
    }
}

static void
thread_unlock(int * user_space) {
    static const int zero = 0;
    if(atomic_compare_exchange_strong(user_space,& zero,1)) {
        syscall(SYS_futex,0);
    }
}

似乎一切正常!!!但是因为这些:

thread_lock(& __THREADS_WRITE_LOCK);
write(0,thread_msg_len);
thread_unlock(& __THREADS_WRITE_LOCK);

我有这个错误!!!有什么问题?!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?