mmap SIGBUS 错误并初始化文件

问题描述 投票:0回答:2

我正在尝试通过映射与 RAM 大小相对应的 1 MiB 文件来模拟基本 CPU。我想读/写这个文件。目前,我遇到了

ram[2] = 1
的 SIGBUS 错误,我收集到的错误是由于尝试在文件范围之外进行 mmap 造成的。我读过,也许我需要用零作为占位符填充文件,但我有点困惑为什么我必须这样做,因为我认为 mmap 会自动为我预留一个将分配的内存块当我第一次触摸它时(正如我在下面的测试中尝试做的那样)。我缺少什么?

int16_t ramD;
if ( (ramD = open("ramMap.txt", O_RDWR | O_CREAT, 0666)) == -1)
{
    errx(EX_OSERR, "RAM could not be initialized");
}

uint8_t* ram = mmap(0, ram_bytes, PROT_READ | PROT_WRITE, MAP_SHARED, ramD, 0);

ram[2] = 1;
printf("%i", ram[2]);
c mmap
2个回答
11
投票

SIGBUS
表示您正在文件外部写入。来自 Linux 手册页
mmap(2)
:

SIGBUS

尝试访问缓冲区中与文件不对应的部分(例如,超出文件末尾, 包括另一个进程截断了的情况 文件)。

创建新文件时,它最初是“空”,即大小为 0 字节。您需要使用 ftruncate 调整其大小,使其至少足够大以包含写入的地址(可能四舍五入为页面大小)。由于您想要一个大小为

ram_bytes
的 ram 磁盘,那么:

ftruncate(ramD, ram_bytes);

有关使用 POSIX 共享内存对象的相同机制的详细说明,请参阅此答案。

PS。

open
返回

int

;您应该使用 
int
,而不是 
int16_t
,来存储文件描述符。

考虑使用 posix_fallocate ,它可以确保分配磁盘空间,这与 ftruncate 不同。

0
投票
© www.soinside.com 2019 - 2024. All rights reserved.