【问题标题】:Program with mmap(MAP_FIXED) crashes on Linux 2.6.18 && glibc 2.5带有 mmap(MAP_FIXED) 的程序在 Linux 2.6.18 && glibc 2.5 上崩溃
【发布时间】:2012-10-05 14:14:56
【问题描述】:

以下节目:

#include <stdio.h>
#include <assert.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

void generate_test_file(int count)
{
    FILE *f;
    int i;

    f = fopen("testfile", "w+");
    for (i=0;i<count;i++) {
            fwrite(&i, 1, sizeof(i), f);
    }
    fclose(f);

}

void test_mmap_directly()
{
    int fd;
    void *area_short, *area_long;

    generate_test_file(1024);
    fd = open("testfile", O_RDONLY);
    assert(fd>=0);

    area_short = mmap(0, 4096, PROT_READ, MAP_PRIVATE, fd, 0);
    assert(area_short != MAP_FAILED);

    generate_test_file(1024*1024);
    area_long = mmap(area_short, 4096*1024, PROT_READ, MAP_PRIVATE | MAP_FIXED, fd, 0);
    assert(area_long != MAP_FAILED);
    assert(area_short == area_long);
}

int main(int argc, char ** argv)
{
    test_mmap_directly();
/* Crashes on shutdown for libc 2.5 and kernel 2.6.18 (CentOS 5) */
}

在我的 CentOS 5 机器上因 Segfault 关闭而崩溃。这是一个已知的错误, 一般不应该使用 MAP_FIXED 还是有什么问题 程序。它在其他平台上也会崩溃吗?

感谢您的帮助,

  • 约翰内斯

【问题讨论】:

  • 在第一个mmap() 之后关闭fd 并在第二个generate_test_file() 之后再次打开它会有所不同吗? “testfile”生活在什么样的文件系统上?我想知道文件的截断/覆盖是否导致保持打开的文件描述符不一致,这会导致第二个mmap() 出现问题。此外,由于MAP_FIXED 导致重叠映射区域被丢弃,可能第二个映射会杀死映射的共享库或数据段或其他东西。
  • 这似乎正在发生:第二次 mmap 调用杀死了一个共享库。关闭和重新打开文件没有任何区别。
  • 4096*1024 您通过 MAP_FIXED 将 4M 映射到先前保留的 4K。由于您没有控制地址空间,因此它可以覆盖任何内容。

标签: linux segmentation-fault mmap


【解决方案1】:

您是否忘记在指针上使用munmap,在文件描述符上使用close。 如果你还没有,那么问题很可能是MAP_FIXED

我在我的 debian(内核 2.6.32)上进行了测试,它在使用 MAP_FIXED 标志时导致 SEGFAULT,并且在没有标志的情况下工作(除了第二个 mmap 之后的断言失败,我认为这并不意外)。

根据man mmap 对MAP_FIXED 的支持是实现定义的,不鼓励支持。我自己从未使用过它,所以除了省略它之外,我想不出任何解决方案。

【讨论】:

  • 感谢您的回答。可能不应该使用 MAP_FIXED,但我在 mmap_allocator 的特殊情况下需要它(在 github 上可用:github.com/johannesthoma/mmap_allocator)。我已经找到了解决方法。这个问题在最近的内核(比如 3.6)中是否仍然存在?
猜你喜欢
  • 2016-12-21
  • 2021-02-17
  • 1970-01-01
  • 1970-01-01
  • 2013-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多