3

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]
64

mapping 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

Jords
  • 1,855
  • 3
  • 18
  • 28

2 Answers2

5

The problem is that you open the file with O_TRUNC which truncates it, and since mmap can only map the existing contents of a file it will give you a sigbus. Use truncate() (and friends) to truncate the file to the correct size before mapping it.

From mmap's man page:

   SIGBUS Attempted access to a portion of the buffer that does not correspond to the file (for example, beyond the end of the file, including the case where another process has truncated the file).
hroptatyr
  • 4,702
  • 1
  • 35
  • 38
  • I actually noticed that and removed the O_TRUNC... same problem. I'll update the code listing. Thanks for the answer though! :) – Jords Oct 14 '11 at 07:21
  • 1
    @Jords This is the correct answer. Try `ftruncate(file, 4096 * 4);` right after `open`. – cnicutar Oct 14 '11 at 07:22
  • That seems to get it to read the first part of the file ok- thanks! I'm going to test with ftruncate to the length the file is supposed to be and see if that also helps :) – Jords Oct 14 '11 at 07:28
  • 1
    It works now, in the listing above you mmap() `page_size` and munmap() `page_size * num_pages`, that's probably what causes you confusion. (as of 2011-10-14T07:30:00 UTC) – hroptatyr Oct 14 '11 at 07:30
  • Yeah, that was right before but I was just changing everything I could to get it to work! It seems to work with the ftruncate call in there, but just prints zeros - suggesting that the file is not being read, so it just pads it out the whole way? – Jords Oct 14 '11 at 07:32
  • 1
    Still, I think you should change the listing above to some previous or updated version, whoever stumbles on that snippet in the future will think we're discussing something else, the munmapped size must not be greater than the mmapped size. – hroptatyr Oct 14 '11 at 07:37
  • Yeah, I have updated that now. Sorry, trying to keep it clean but tricky to keep up :) – Jords Oct 14 '11 at 07:40
  • Now if only I could figure out what the issue with this file was :) – Jords Oct 14 '11 at 07:44
2

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 by sysconf(_SC_PAGESIZE)*sizeof(int) so you quickly get outside the mapped region.

Also, the page_size * 4 in mmap looks questionable: surely num_pages ought to come into the equation?

NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • Yes but according to `gdb` the error occurs before the loop even begins, at `printf("%d", mapped_file[0]);`. – cnicutar Oct 14 '11 at 07:15
  • So I should add on pagesize/4 then? Any idea what's causing the sigbus, I'm really confused by it. – Jords Oct 14 '11 at 07:16
  • @Jords: `current_pos += page_size` is probably not what you expect since it doesn't advance the pointer by `page_size` bytes, but by `sizeof(int) * page_size`. – Blagovest Buyukliev Oct 14 '11 at 07:17