【问题标题】:mmap SIGBUS error and initializing the filemmap SIGBUS 错误和初始化文件
【发布时间】:2017-06-14 20:11:27
【问题描述】:

我试图通过映射一个 1 MiB 文件来模拟基本 CPU,对应于 RAM 大小。我想读/写这个文件。目前,我收到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]);

【问题讨论】:

  • ram_bytes的值是多少?
  • 你没有检查mmap是否成功!
  • @DavidSchwartz 没关系,映射成功时会生成sigbus。
  • @AnttiHaapala 当然,但这将是一个完全不同的原因,例如,如果他在一个共享内存支持已被禁用的平台上。
  • 另外,int16_t ramD; 是一个非常奇怪的文件描述符变量类型。为什么不直接使用 int?

标签: c mmap


【解决方案1】:

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

SIGBUS

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

当您创建一个新文件时,它最初是,即大小为 0 字节。您需要使用ftruncate 调整它的大小,使其至少足够大以包含写入的地址(可能四舍五入到页面大小)。如果你想拥有一个大小为ram_bytes 的 ram 磁盘,那么:

ftruncate(ramD, ram_bytes);

See this answer for a longer explanation about the same mechanism, using POSIX shared memory objects.


PS。 open 返回一个 int;你应该使用int,而不是int16_t,来存储文件描述符。

【讨论】:

    猜你喜欢
    • 2016-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多