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

写入内存映射文件时触发Bus Error问题求助

Bus Error 问题分析与修复

问题根源

你的代码中db_file_open函数使用fopen(path, "w+")打开文件,这个模式会强制截断已存在的文件至0长度。之前在disk_io_create_disk_file中通过ftruncate设置的文件大小会被清空,导致db_file_init_hdr中mmap的区域实际上超出了文件的实际大小,写入操作触发Bus Error。

另外还有两处潜在问题:

  • mmap失败时返回的是MAP_FAILED(值为(void*)-1),而非NULL,原代码的assert(pptr)无法正确检测mmap失败。
  • 代码中未给出disk_file_unmap的实现,需要补充调用munmap的逻辑。

修复方案

  1. 修改db_file_open的文件打开模式为"r+",打开已存在文件时不截断:
fd_t
db_file_open (const char* path) {
    FILE *file = fopen (path, "r+");
    if (!file) assert(0);
    fd_t fd = fileno (file);
    return fd;
}
  1. 完善disk_io_file_mmap的错误检测:
void *
disk_io_file_mmap (fd_t fd, uint64_t start_offset, uint64_t end_offset) {
    size_t map_size = end_offset - start_offset;
    void *pptr = mmap (NULL, map_size, 
                       PROT_READ | PROT_WRITE, MAP_SHARED, 
                       fd, start_offset);
    // mmap失败返回MAP_FAILED,需正确检测
    assert(pptr != MAP_FAILED);
    return pptr;
}
  1. 补充disk_file_unmap的实现:
void disk_file_unmap(void *addr, size_t size) {
    assert(munmap(addr, size) != -1);
}

关键说明

  • "w+"模式会清空已有文件内容并重置长度,这是导致映射区域无效的核心原因;"r+"模式用于读写已存在的文件,不会修改文件长度。
  • mmap的映射区域必须对应文件的实际有效范围,当文件长度被截断后,原映射的区域超出文件实际大小,写入时会触发Bus Error或Segmentation Fault。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 03:01:28