【问题标题】:SIGBUS on mmap with MAP_FIXED | MAP_FILE | MAP_SHARED带有 MAP_FIXED 的 mmap 上的 SIGBUS | MAP_FILE | MAP_SHARED
【发布时间】:2016-12-21 22:58:37
【问题描述】:

:) 我正在尝试将一些遗留代码(大型程序)移植到 CentOS 7,但遇到了障碍。代码的核心是一个相当尴尬的结构,它使用 mmap 来分配硬编码地址并将文件映射到它。该文件就像一个数据库(并且由一个数据库构建)并且包含指向映射内存不同部分的硬编码指针。非常丑陋,但它就是这样。整个程序都是围绕这种结构构建的,没有人会资助重写。

问题出现在 mmap 行上。这以前有效,但不再在 CentOS 7 上:

mmapAddr = mmap ((void *) SMAddr, SMA_WINDOW_SIZE, PROT_READ | (readOnly ? 0 : PROT_WRITE),MAP_FILE | MAP_FIXED | MAP_SHARED, SMFileDesc, 0);

... 其中SMAddr0x8000000SMA_WINDOW_SIZE127926272readOnly 是假的。所以基本上它试图将一个文件映射到地址0x8000000,大小为122MB。

版本之间可能发生了什么变化,我不知道。但我确实注意到它映射的文件只有 1.5MB。我不确定为什么它需要映射比文件大小更多的东西,但我知道它是必需的,而且我知道出于某种原因选择大小“122MB”时存在很多细微差别。

实际文件大小和分配大小之间的不匹配在过去是否正常,但现在不行了?我知道SIGBUS 意味着试图访问无效的内存区域。鉴于 mmap 不采用任何类型的分配指针,这必须是它在内部做的事情。

我尝试捕获并阻止SIGBUS(认为它可能会被忽略?),但程序仍然在同一位置以SIGBUS 崩溃。也许我做错了。

想法?

【问题讨论】:

    标签: c mmap sigbus


    【解决方案1】:

    从这里1:

    mmap() 函数可用于映射内存区域 大于对象的当前大小。内存访问 映射但超出底层对象的当前端可能 导致 SIGBUS 信号被发送到进程。的原因 这是对象的大小可以被其他人操纵 过程,并且可以随时更改。实施应该告诉 内存引用在对象之外的应用程序 这可以被检测到;否则,写入的数据可能会丢失和读取 数据可能无法反映对象中的实际数据。

    请注意,超出对象末尾的引用不会扩展 作为新终点的客体不能由大多数虚 内存硬件。相反,大小可以直接由 ftruncate().

    所以最有可能的错误是您的程序试图访问位于文件外部的映射内存区域。但是, mmap 调用应该会成功。你得到哪个返回值?

    【讨论】:

    • 我得到的值是崩溃——或者更准确地说,SIGBUS。 :( 我同意, mmap 调用应该成功。但它没有。
    • 我应该补充一点,我已经通过刷新调试包围了该语句。仅到达 pre-mmap 行。 GDB 在 mmap 语句中退出:
    • 程序收到信号SIGBUS,总线错误。 0xb7739424 in __kernel_vsyscall () (gdb) #0 0xb7739424 in __kernel_vsyscall () #1 0xb7613638 in mmap () at ../sysdeps/unix/sysv/linux/i386/mmap.S:56 #2 0x080a563f in fdps_shmat (SMFileDesc=8 , SMAddr=0xb0000000, SMFlag=2048) at fdps_shm.c:284 #3 0x08063339 in ET_open (p_fname=0xbf896939 "/home/fdps/fdps/dat/local/cassrw.dat", p_flag=2) at et_open.c: 260 #4 0x0806c294 在 DB_open (p_fiid=0xbf896939 "/home/fdps/fdps/dat/local/cassrw.dat", p_flag=2, p_seg=0xb0000000 "FDPS\005") 在 db_open.c:104 ...
    • 0x8000000 + 127926272 = 0xb7a00000,与“__kernel_vsyscall()中的0xb7739424”比较。您已经覆盖了部分地址空间。
    • 我可以尝试减小分配的大小,但我知道在选择那个大小上做了很多工作(同样,我不知道为什么。但是由
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-03
    • 1970-01-01
    • 1970-01-01
    • 2020-11-14
    • 2016-01-07
    • 2023-03-30
    • 2014-05-12
    相关资源
    最近更新 更多