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

Linux共享内存开发时向struct赋值触发Segmentation fault求助

问题分析与修复方案

核心错误

代码中最致命的问题是mmap返回值的赋值对象错误,直接覆盖了函数入参shm指针本身:

// 错误写法
shm = mmap(0,SHMSZ,PROT_WRITE,MAP_SHARED,shm->fd,0);

mmap返回的是共享内存区域的映射起始地址,应该赋值给shm结构体的data成员,而不是覆盖shm指针本身:

// 正确写法
shm->data = mmap(NULL, sizeof(shared_data_t), PROT_READ | PROT_WRITE, MAP_SHARED, shm->fd, 0);

之前的写法会把原本指向调用方栈上shared_memory_t结构体的指针,修改为共享内存的映射地址,后续所有对shm成员的访问都会访问非法地址,这就是段错误的根本原因。感知到段错误发生在shm->fd = shm_fd行,大概率是编译优化导致调试行号偏移,实际错误触发在后续访问shm->data的位置。

其他需要修复的问题

  • 统一共享内存大小:ftruncate用的是sizeof(struct shared_data),但mmap原逻辑用的是SHMSZ宏,两者如果不一致会导致访问越界,建议统一使用sizeof(shared_data_t)避免错误,不需要额外定义SHMSZ宏。
  • 增加mmap返回值校验:mmap失败会返回MAP_FAILED,原逻辑没有做错误判断,建议补充校验逻辑。
  • 补充mmap权限:原逻辑仅设置了PROT_WRITE,后续如果读取共享内存内容会触发权限错误,建议加上PROT_READ。
  • 信号量初始化校验:sem_init失败会返回-1,建议补充错误判断避免异常。
  • 增加错误分支的资源清理:创建失败时要及时关闭已打开的文件描述符、解除已建立的映射,避免资源泄漏。

修复后核心代码片段

bool create_shared_object( shared_memory_t* shm, const char* share_name ) {
    int shm_fd;
    // 先删除已存在的共享内存对象
    shm_unlink(share_name);

    shm->name = share_name;
    shm_fd = shm_open(share_name, O_CREAT | O_RDWR, 0666);
    if(shm_fd == -1){  
        shm->data = NULL;
        return false;
    }
    shm->fd = shm_fd;

    if(ftruncate(shm->fd, sizeof(shared_data_t)) == -1){
        shm->data = NULL;
        close(shm->fd);
        return false;
    }

    shm->data = mmap(NULL, sizeof(shared_data_t), PROT_READ | PROT_WRITE, MAP_SHARED, shm->fd, 0);
    if (shm->data == MAP_FAILED) {
        shm->data = NULL;
        close(shm->fd);
        return false;
    }

    if (sem_init(&shm->data->controller_semaphore, 1, 0) != 0 || 
        sem_init(&shm->data->worker_semaphore, 1, 0) != 0) {
        munmap(shm->data, sizeof(shared_data_t));
        close(shm->fd);
        shm->data = NULL;
        return false;
    }

    return true;
}

程序退出前需要做清理操作,避免共享内存对象残留在系统中:

// 清理示例
sem_destroy(&shm.data->controller_semaphore);
sem_destroy(&shm.data->worker_semaphore);
munmap(shm.data, sizeof(shared_data_t));
close(shm.fd);
shm_unlink(shm.name);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 11:18:03