【问题标题】:SIGSEGV when calling mmap twice两次调用 mmap 时的 SIGSEGV
【发布时间】:2014-12-02 19:08:08
【问题描述】:

我正在尝试在 Ubuntu 上运行以下程序,但它因分段错误而崩溃。

我想要做的是两次调用 mmap:

p1 = mmap(null, size: 16 * 4k, offset: 0);
p2 = mmap(p1+(16*4K), 136 * 4k , offset: 16 * 4k);

基本上,尝试创建两个连续的内存区域来镜像文件中的两个连续区域。 如果第二个 mmap 失败也没关系,但我想了解它为什么会导致分段错误。

#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <unistd.h>

int main()
{
    int fd, ret;
    void* p1;
    void* p2;
    unlink ("test.file");// don't care if it doesn't exists

    fd = open("test.file", O_RDWR | O_CREAT | O_SYNC, ALLPERMS);

    if(fd == -1)
        return errno;

    ret = ftruncate(fd, 4096*16);
    if(ret != 0)
        return errno;

    p1 = mmap(NULL, 4096*16, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if(p1 == (void*)-1)
        return errno;

    ret = ftruncate(fd, 4096*150);
    if(ret != 0)
        return errno;

    // dies here!
    p2 = mmap(p1 + (4096*16), 4096*(150-16), PROT_READ | PROT_WRITE, MAP_SHARED |MAP_FIXED, fd, 4096*16);
    if(p2 == (void*)-1)
        return errno;


    return 0;
}

【问题讨论】:

    标签: c linux gcc mmap segmentation-fault


    【解决方案1】:

    它可能会在映射之前和之后分配保护页以防止映射溢出,它们应该在读写时发生段错误。另一种选择是您点击堆栈下的保护页面。检查第一个mmap 之后的pmap 输出以确定。

    尝试改用mremap

    【讨论】:

    • 您好 Maxim,非常感谢您,您能给我一些资源以获取更多信息吗?
    • @AyendeRahien 我能够重现它,但不再使用原始源代码。可能是地址空间随机化。
    猜你喜欢
    • 1970-01-01
    • 2014-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多