为什么关于mmap的代码在(16384 + 1)字节而不是(4096 + 1)字节处获得段错误?

时间:2014-04-14 12:20:23

标签: c linux segmentation-fault shared-memory mmap

操作系统是Ubuntu。 从我看来,页面大小为4096,它应该在第(4096 + 1)字节处得到段错误,但是当写入(16384 + 1)字节时它会出现段错误。

输出:... 16383分段错误

#include <sys/mman.h>   // memory management.
#include <sys/stat.h>   // file stat. man 2 stat
#include <fcntl.h>      // O_CREAT
#include <unistd.h>

#include <errno.h>
#include <stdio.h>

int main(int argc, char* argv[]) {
    const int page_size = getpagesize();
    printf("page_size: %d\n", page_size);

    int shm_fd = open("shm.temp", O_CREAT | O_RDWR, S_IRWXU);
    ftruncate(shm_fd, 1);

    char* begin = (char *)mmap(NULL, 1, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_NORESERVE, shm_fd, 0);
    perror("mmap");

    begin[0] = 'a';
    for(int i = 1023;/*i < .. */ ; i += 1024) {
        begin[i] = 'a';
        printf("%d %c\n", i, begin[i] );

        begin[i+1] = 'a';
        printf("%d %c\n", i+1, begin[i] );
    }

    return 0;
}

更新

int pid = getpid();
printf("pid: %d\n", pid);

printf("begin: %x\nbegin+4096: %x\nbegin+16384: %x\n", 
        (unsigned int)(begin), 
        (unsigned int)(begin + 4096),
        (unsigned int)(begin + 16384)
        );  

begin[4096] = 'a';
sleep(20);
begin[16384] = 'a';
sleep(10);

a.out &的输出:

pid: 3929
begin: b78a5000
begin+4096: b78a6000
begin+16384: b78a9000

cat /proc/pid/maps的输出。

b78a5000-b78a6000 rw-p 00000000 08:01 285615     /home/.../Try/shm.temp
b78a6000-b78a9000 rw-p 00000000 00:00 0 
bfb04000-bfb19000 rw-p 00000000 00:00 0          [stack]

感谢Basile的好点。

现在问题已更改为why there is b78a6000-b78a9000。我想弄清楚。欢迎任何更多信息。

1 个答案:

答案 0 :(得分:1)

在我使用cat /proc/pid/maps之后,我确实找到了其他一些mmap-ed段。 然后我使用strace a.out。我知道why there is b78a6000-b78a9000

它来自装载机&amp;主函数之前的运行时env。

execve("./a.out", ["./a.out"], [/* 38 vars */]) = 0
brk(0)                                  = 0x85d8000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb77f8000
... and something like it.

相关点:

g++ -static option!

现在我想我得到了这个Q的答案。感谢您的所有评论,特别是Basile的观点让我想到更多。