操作系统是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
。我想弄清楚。欢迎任何更多信息。
答案 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的观点让我想到更多。