c - 为什么关于 mmap 的代码在 (16384+1) 字节而不是 (4096 + 1) 字节处出现段错误



OS is 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: %dn", 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 %cn", i, begin[i] );
        begin[i+1] = 'a';
        printf("%d %cn", i+1, begin[i] );
    }
    return 0;
}

更新:

int pid = getpid();
printf("pid: %dn", pid);
printf("begin: %xnbegin+4096: %xnbegin+16384: %xn", 
        (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]

感谢巴西勒的好点。

现在问题改为 why there is b78a6000-b78a9000 .我正在试图弄清楚。欢迎提供更多信息。

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

它来自 loader 和运行时 env 在 main 函数之前。

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!

现在我想我得到了这个问题的答案,谢谢你的所有评论,尤其是巴西尔的观点,让我思考更多。

最新更新