mmap 不存在物理地址错误
我正在尝试 mmap 文件,它似乎成功了,但是当我访问它时,我收到 SIGBUS 错误。 代码:
int main(int argc, char* argv[]) {
int pid = getpid();
char cmd [1024];
int file;
if (argc != 2) {
printf("Wrong arguments\n");
return 1;
}
printf("%s", argv[1]);
int numpages = atoi(argv[1]);
sprintf(cmd, "cat /proc/%d/maps", pid);
system(cmd);
long page_size = sysconf(_SC_PAGESIZE);
file = open(argv[1], O_RDWR, (mode_t)0600);
ftruncate(file, page_size * numpages);
if(file == -1) {
perror("file open failed!\n");
return 1;
}
printf("\n\n mapping file - numpages: %d \n\n", numpages);
printf("mapping %ld KB\n", page_size * numpages/1024);
int* mapped_file = mmap(0, page_size * numpages, PROT_READ | PROT_WRITE, MAP_PRIVATE, file, 0 );
if (mapped_file == MAP_FAILED) {
perror("Map failed");
return 1;
}
printf("mapped file at %p\n\n", mapped_file);
int* current_pos = mapped_file;
system(cmd);
int j;
for (j=0; j<numpages; j++) {
printf("%d ", *current_pos);
current_pos += page_size/4;
}
if (munmap (mapped_file, page_size * numpages) == -1) {
perror ("munmap");
return 1;
}
if (close(file) == -1) {
perror("close");
return 1;
}
return 0;
}
输出:
(gdb) run 64
Starting program: /home/jords/engcode/workspace/SE370Assignment3/A3Program3 64
00400000-00401000 r-xp 00000000 08:03 3288976 /home/jords/engcode/workspace/SE370Assignment3/A3Program3
00600000-00601000 r--p 00000000 08:03 3288976 /home/jords/engcode/workspace/SE370Assignment3/A3Program3
00601000-00602000 rw-p 00001000 08:03 3288976 /home/jords/engcode/workspace/SE370Assignment3/A3Program3
7ffff7a48000-7ffff7bd2000 r-xp 00000000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so
7ffff7bd2000-7ffff7dd1000 ---p 0018a000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so
7ffff7dd1000-7ffff7dd5000 r--p 00189000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so
7ffff7dd5000-7ffff7dd6000 rw-p 0018d000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so
7ffff7dd6000-7ffff7ddc000 rw-p 00000000 00:00 0
7ffff7ddc000-7ffff7dfd000 r-xp 00000000 00:10 8090 /lib/x86_64-linux-gnu/ld-2.13.so
7ffff7fd0000-7ffff7fd3000 rw-p 00000000 00:00 0
7ffff7ff8000-7ffff7ffb000 rw-p 00000000 00:00 0
7ffff7ffb000-7ffff7ffc000 r-xp 00000000 00:00 0 [vdso]
7ffff7ffc000-7ffff7ffd000 r--p 00020000 00:10 8090 /lib/x86_64-linux-gnu/ld-2.13.so
7ffff7ffd000-7ffff7fff000 rw-p 00021000 00:10 8090 /lib/x86_64-linux-gnu/ld-2.13.so
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0 [stack]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
64
映射文件 - numpages: 64
映射 256 KB
映射文件位于 0x7ffff7ff4000
00400000-00401000 r-xp 00000000 08:03 3288976 /home/jords/engcode/workspace/SE370Assignment3/A3Program3
00600000-00601000 r--p 00000000 08:03 3288976 /home/jords/engcode/workspace/SE370Assignment3/A3Program3
00601000-00602000 rw-p 00001000 08:03 3288976 /home/jords/engcode/workspace/SE370Assignment3/A3Program3
7ffff7a48000-7ffff7bd2000 r-xp 00000000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so
7ffff7bd2000-7ffff7dd1000 ---p 0018a000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so
7ffff7dd1000-7ffff7dd5000 r--p 00189000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so
7ffff7dd5000-7ffff7dd6000 rw-p 0018d000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so
7ffff7dd6000-7ffff7ddc000 读写 00000000 00:00 0
7ffff7ddc000-7ffff7dfd000 r-xp 00000000 00:10 8090 /lib/x86_64-linux-gnu/ld-2.13.so
7ffff7fd0000-7ffff7fd3000 读写 00000000 00:00 0
7ffff7ff4000-7ffff7ff8000 rw-p 00000000 08:03 3288973 /home/jords/engcode/workspace/SE370Assignment3/64
7ffff7ff8000-7ffff7ffb000 读写 00000000 00:00 0
7ffff7ffb000-7ffff7ffc000 r-xp 00000000 00:00 0 [vdso]
7ffff7ffc000-7ffff7ffd000 r--p 00020000 00:10 8090 /lib/x86_64-linux-gnu/ld-2.13.so
7ffff7ffd000-7ffff7fff000 rw-p 00021000 00:10 8090 /lib/x86_64-linux-gnu/ld-2.13.so
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0 [堆栈]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
程序收到信号 SIGBUS,总线错误。
0x0000000000400abb 在主(argc = 2,argv = 0x7fffffffe058)在A3Program3.c:49
49 printf("%d", 映射文件[0]);
(gdb)
It's confusing me, since you can clearly see in the maps output that the file has been mapped and the address is correct - but it gives an error whenever I try to access it.编辑:Valgrind:
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
==16295==
==16295== Process terminating with default action of signal 7 (SIGBUS)
==16295== Non-existent physical address at address 0x4024000
==16295== at 0x400AB7: main (A3Program3.c:49)
==16295==
更新:所以我现在已经通过 ftruncate 调用阻止了它崩溃(谢谢:)),但它打印全零: <代码>
I think this is because the file is not being read correctly, so all I'm reading is padded zeros. But I'm not sure why that would bejords@jords-desktop ~/engcode/workspace/SE370Assignment3 (master) $ ./A3Program3 64 00400000-00401000 r-xp 00000000 08:03 3288976 /home/jords/engcode/workspace/SE370Assignment3/A3Program3 00600000-00601000 r--p 00000000 08:03 3288976 /home/jords/engcode/workspace/SE370Assignment3/A3Program3 00601000-00602000 rw-p 00001000 08:03 3288976 /home/jords/engcode/workspace/SE370Assignment3/A3Program3 7f96ec7a1000-7f96ec92b000 r-xp 00000000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so 7f96ec92b000-7f96ecb2a000 ---p 0018a000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so 7f96ecb2a000-7f96ecb2e000 r--p 00189000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so 7f96ecb2e000-7f96ecb2f000 rw-p 0018d000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so 7f96ecb2f000-7f96ecb35000 rw-p 00000000 00:00 0 7f96ecb35000-7f96ecb56000 r-xp 00000000 00:10 8090 /lib/x86_64-linux-gnu/ld-2.13.so 7f96ecd2a000-7f96ecd2d000 rw-p 00000000 00:00 0 7f96ecd52000-7f96ecd55000 rw-p 00000000 00:00 0 7f96ecd55000-7f96ecd56000 r--p 00020000 00:10 8090 /lib/x86_64-linux-gnu/ld-2.13.so 7f96ecd56000-7f96ecd58000 rw-p 00021000 00:10 8090 /lib/x86_64-linux-gnu/ld-2.13.so 7fff9be10000-7fff9be31000 rw-p 00000000 00:00 0 [stack] 7fff9bf0b000-7fff9bf0c000 r-xp 00000000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] 64
映射文件 - numpages: 64
映射 256 KB 映射文件位于 0x7f96eccea000
00400000-00401000 r-xp 00000000 08:03 3288976 /home/jords/engcode/workspace/SE370Assignment3/A3Program3 00600000-00601000 r--p 00000000 08:03 3288976 /home/jords/engcode/workspace/SE370Assignment3/A3Program3 00601000-00602000 rw-p 00001000 08:03 3288976 /home/jords/engcode/workspace/SE370Assignment3/A3Program3 7f96ec7a1000-7f96ec92b000 r-xp 00000000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so 7f96ec92b000-7f96ecb2a000 ---p 0018a000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so 7f96ecb2a000-7f96ecb2e000 r--p 00189000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so 7f96ecb2e000-7f96ecb2f000 读写-p 0018d000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so 7f96ecb2f000-7f96ecb35000 读写 00000000 00:00 0 7f96ecb35000-7f96ecb56000 r-xp 00000000 00:10 8090 /lib/x86_64-linux-gnu/ld-2.13.so 7f96eccea000-7f96ecd2a000 rw-p 00000000 08:03 3288973 /home/jords/engcode/workspace/SE370Assignment3/64 7f96ecd2a000-7f96ecd2d000 读写 00000000 00:00 0 7f96ecd52000-7f96ecd55000 读写 00000000 00:00 0 7f96ecd55000-7f96ecd56000 r--p 00020000 00:10 8090 /lib/x86_64-linux-gnu/ld-2.13.so 7f96ecd56000-7f96ecd58000 rw-p 00021000 00:10 8090 /lib/x86_64-linux-gnu/ld-2.13.so 7fff9be10000-7fff9be31000 rw-p 00000000 00:00 0 [堆栈] 7fff9bf0b000-7fff9bf0c000 r-xp 00000000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
更新,解决了,它实际上正确地读取了文件,我只是在如何读取它方面犯了错误。谢谢大家
I'm trying to mmap a file, and it seems to succeed but when I access it, I get an SIGBUS error.
Code:
int main(int argc, char* argv[]) {
int pid = getpid();
char cmd [1024];
int file;
if (argc != 2) {
printf("Wrong arguments\n");
return 1;
}
printf("%s", argv[1]);
int numpages = atoi(argv[1]);
sprintf(cmd, "cat /proc/%d/maps", pid);
system(cmd);
long page_size = sysconf(_SC_PAGESIZE);
file = open(argv[1], O_RDWR, (mode_t)0600);
ftruncate(file, page_size * numpages);
if(file == -1) {
perror("file open failed!\n");
return 1;
}
printf("\n\n mapping file - numpages: %d \n\n", numpages);
printf("mapping %ld KB\n", page_size * numpages/1024);
int* mapped_file = mmap(0, page_size * numpages, PROT_READ | PROT_WRITE, MAP_PRIVATE, file, 0 );
if (mapped_file == MAP_FAILED) {
perror("Map failed");
return 1;
}
printf("mapped file at %p\n\n", mapped_file);
int* current_pos = mapped_file;
system(cmd);
int j;
for (j=0; j<numpages; j++) {
printf("%d ", *current_pos);
current_pos += page_size/4;
}
if (munmap (mapped_file, page_size * numpages) == -1) {
perror ("munmap");
return 1;
}
if (close(file) == -1) {
perror("close");
return 1;
}
return 0;
}
Output:
(gdb) run 64
Starting program: /home/jords/engcode/workspace/SE370Assignment3/A3Program3 64
00400000-00401000 r-xp 00000000 08:03 3288976 /home/jords/engcode/workspace/SE370Assignment3/A3Program3
00600000-00601000 r--p 00000000 08:03 3288976 /home/jords/engcode/workspace/SE370Assignment3/A3Program3
00601000-00602000 rw-p 00001000 08:03 3288976 /home/jords/engcode/workspace/SE370Assignment3/A3Program3
7ffff7a48000-7ffff7bd2000 r-xp 00000000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so
7ffff7bd2000-7ffff7dd1000 ---p 0018a000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so
7ffff7dd1000-7ffff7dd5000 r--p 00189000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so
7ffff7dd5000-7ffff7dd6000 rw-p 0018d000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so
7ffff7dd6000-7ffff7ddc000 rw-p 00000000 00:00 0
7ffff7ddc000-7ffff7dfd000 r-xp 00000000 00:10 8090 /lib/x86_64-linux-gnu/ld-2.13.so
7ffff7fd0000-7ffff7fd3000 rw-p 00000000 00:00 0
7ffff7ff8000-7ffff7ffb000 rw-p 00000000 00:00 0
7ffff7ffb000-7ffff7ffc000 r-xp 00000000 00:00 0 [vdso]
7ffff7ffc000-7ffff7ffd000 r--p 00020000 00:10 8090 /lib/x86_64-linux-gnu/ld-2.13.so
7ffff7ffd000-7ffff7fff000 rw-p 00021000 00:10 8090 /lib/x86_64-linux-gnu/ld-2.13.so
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0 [stack]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
64
mapping file - numpages: 64
mapping 256 KB
mapped file at 0x7ffff7ff4000
00400000-00401000 r-xp 00000000 08:03 3288976 /home/jords/engcode/workspace/SE370Assignment3/A3Program3
00600000-00601000 r--p 00000000 08:03 3288976 /home/jords/engcode/workspace/SE370Assignment3/A3Program3
00601000-00602000 rw-p 00001000 08:03 3288976 /home/jords/engcode/workspace/SE370Assignment3/A3Program3
7ffff7a48000-7ffff7bd2000 r-xp 00000000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so
7ffff7bd2000-7ffff7dd1000 ---p 0018a000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so
7ffff7dd1000-7ffff7dd5000 r--p 00189000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so
7ffff7dd5000-7ffff7dd6000 rw-p 0018d000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so
7ffff7dd6000-7ffff7ddc000 rw-p 00000000 00:00 0
7ffff7ddc000-7ffff7dfd000 r-xp 00000000 00:10 8090 /lib/x86_64-linux-gnu/ld-2.13.so
7ffff7fd0000-7ffff7fd3000 rw-p 00000000 00:00 0
7ffff7ff4000-7ffff7ff8000 rw-p 00000000 08:03 3288973 /home/jords/engcode/workspace/SE370Assignment3/64
7ffff7ff8000-7ffff7ffb000 rw-p 00000000 00:00 0
7ffff7ffb000-7ffff7ffc000 r-xp 00000000 00:00 0 [vdso]
7ffff7ffc000-7ffff7ffd000 r--p 00020000 00:10 8090 /lib/x86_64-linux-gnu/ld-2.13.so
7ffff7ffd000-7ffff7fff000 rw-p 00021000 00:10 8090 /lib/x86_64-linux-gnu/ld-2.13.so
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0 [stack]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Program received signal SIGBUS, Bus error.
0x0000000000400abb in main (argc=2, argv=0x7fffffffe058) at A3Program3.c:49
49 printf("%d", mapped_file[0]);
(gdb)
It's confusing me, since you can clearly see in the maps output that the file has been mapped and the address is correct - but it gives an error whenever I try to access it.
EDIT: Valgrind:
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
==16295==
==16295== Process terminating with default action of signal 7 (SIGBUS)
==16295== Non-existent physical address at address 0x4024000
==16295== at 0x400AB7: main (A3Program3.c:49)
==16295==
Update: So I have stopped it crashing now (thanks :)) with the ftruncate call, but it's printing all zeros:
jords@jords-desktop ~/engcode/workspace/SE370Assignment3 (master) $ ./A3Program3 64 00400000-00401000 r-xp 00000000 08:03 3288976 /home/jords/engcode/workspace/SE370Assignment3/A3Program3 00600000-00601000 r--p 00000000 08:03 3288976 /home/jords/engcode/workspace/SE370Assignment3/A3Program3 00601000-00602000 rw-p 00001000 08:03 3288976 /home/jords/engcode/workspace/SE370Assignment3/A3Program3 7f96ec7a1000-7f96ec92b000 r-xp 00000000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so 7f96ec92b000-7f96ecb2a000 ---p 0018a000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so 7f96ecb2a000-7f96ecb2e000 r--p 00189000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so 7f96ecb2e000-7f96ecb2f000 rw-p 0018d000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so 7f96ecb2f000-7f96ecb35000 rw-p 00000000 00:00 0 7f96ecb35000-7f96ecb56000 r-xp 00000000 00:10 8090 /lib/x86_64-linux-gnu/ld-2.13.so 7f96ecd2a000-7f96ecd2d000 rw-p 00000000 00:00 0 7f96ecd52000-7f96ecd55000 rw-p 00000000 00:00 0 7f96ecd55000-7f96ecd56000 r--p 00020000 00:10 8090 /lib/x86_64-linux-gnu/ld-2.13.so 7f96ecd56000-7f96ecd58000 rw-p 00021000 00:10 8090 /lib/x86_64-linux-gnu/ld-2.13.so 7fff9be10000-7fff9be31000 rw-p 00000000 00:00 0 [stack] 7fff9bf0b000-7fff9bf0c000 r-xp 00000000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] 64mapping file - numpages: 64
mapping 256 KB mapped file at 0x7f96eccea000
00400000-00401000 r-xp 00000000 08:03 3288976 /home/jords/engcode/workspace/SE370Assignment3/A3Program3 00600000-00601000 r--p 00000000 08:03 3288976 /home/jords/engcode/workspace/SE370Assignment3/A3Program3 00601000-00602000 rw-p 00001000 08:03 3288976 /home/jords/engcode/workspace/SE370Assignment3/A3Program3 7f96ec7a1000-7f96ec92b000 r-xp 00000000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so 7f96ec92b000-7f96ecb2a000 ---p 0018a000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so 7f96ecb2a000-7f96ecb2e000 r--p 00189000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so 7f96ecb2e000-7f96ecb2f000 rw-p 0018d000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so 7f96ecb2f000-7f96ecb35000 rw-p 00000000 00:00 0 7f96ecb35000-7f96ecb56000 r-xp 00000000 00:10 8090 /lib/x86_64-linux-gnu/ld-2.13.so 7f96eccea000-7f96ecd2a000 rw-p 00000000 08:03 3288973 /home/jords/engcode/workspace/SE370Assignment3/64 7f96ecd2a000-7f96ecd2d000 rw-p 00000000 00:00 0 7f96ecd52000-7f96ecd55000 rw-p 00000000 00:00 0 7f96ecd55000-7f96ecd56000 r--p 00020000 00:10 8090 /lib/x86_64-linux-gnu/ld-2.13.so 7f96ecd56000-7f96ecd58000 rw-p 00021000 00:10 8090 /lib/x86_64-linux-gnu/ld-2.13.so 7fff9be10000-7fff9be31000 rw-p 00000000 00:00 0 [stack] 7fff9bf0b000-7fff9bf0c000 r-xp 00000000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
I think this is because the file is not being read correctly, so all I'm reading is padded zeros. But I'm not sure why that would be
Update, worked it out, it was actually reading the file correctly I was just making a mistake in terms of how to read it. Thanks everyone
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
问题在于,您使用 O_TRUNC 打开文件会截断文件,并且由于 mmap 只能映射文件的现有内容,因此它会给您一个 sigbus。在映射文件之前,使用
truncate()
(和朋友)将文件截断为正确的大小。来自 mmap 的手册页:
The problem is that you open the file with
O_TRUNC
which truncates it, and sincemmap
can only map the existing contents of a file it will give you a sigbus. Usetruncate()
(and friends) to truncate the file to the correct size before mapping it.From mmap's man page:
存在错误,但它无法解释
mapped_file[0]
中的崩溃。sysconf(_SC_PAGESIZE)
为您提供页面大小以字节为单位。在
current_pos += page_size
的每次迭代中,您都会将指针增加sysconf(_SC_PAGESIZE)*sizeof(int)
,以便快速到达映射区域之外。另外,
mmap
中的page_size * 4
看起来有问题:num_pages
肯定应该进入等式吗?There's a bug, but it won't explain the crash in
mapped_file[0]
.sysconf(_SC_PAGESIZE)
gives you the page size in bytes.At each iteration of
current_pos += page_size
you're incrementing your pointer bysysconf(_SC_PAGESIZE)*sizeof(int)
so you quickly get outside the mapped region.Also, the
page_size * 4
inmmap
looks questionable: surelynum_pages
ought to come into the equation?