Segfault while using mmap in C for reading binary files

社会主义新天地 提交于 2019-12-22 08:02:15

问题


I am trying to use mmap in C just to see how it exactly works. Currently I am try to read a binary file byte by byte using mmap. My code is like this:

#include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>    

int main(int argc, char *argv[]) {
    int fd;
    char *data;

    for ( int i = 1; i<argc; i++)
    {

        if(strcmp(argv[i],"-i")==0)
            fd = open(argv[i+1],O_RDONLY);
    }

    data = mmap(NULL, 4000, PROT_READ, MAP_SHARED, fd, 8000);
    int i = 0;
    notation = data [i];
    // ......

}

My problem occurs when I try notation = data[0] and I get a segfault . I am sure that the first byte in the binary file is a character as well. My for loop checks if there is an -i flag while compiling , if there is the next argument should be the file name.


回答1:


It appears that mmap fails because the offset is not a multiple of page size. You can test this with perror and see that the problem is an invalid argument. If you write:

data = mmap(NULL, 4000, PROT_READ, MAP_SHARED, fd, 8000);
perror("Error");

At least on my OS X the following error is printed:

Error: Invalid argument

Changing offset from 8000 to 4096 or 8192 works. 6144 doesn't, so it has to be a multiple of 4096 on this platform. Incidentally,

printf("%d\n",getpagesize());

prints 4096. You should round your offset down to nearest multiple of this for mmap and add the remainder to i when accessing the area. Of course, get the page size for your particular platform from that function. It's probably defined in unistd.h, which you already declared.

Here's how to handle the offset correctly and deal with possible errors. It prints the byte at position 8000:

int offset = 8000;
int pageoffset = offset % getpagesize();

data = mmap(NULL, 4000 + pageoffset, PROT_READ, MAP_SHARED, fd, offset - pageoffset);
if ( data == MAP_FAILED ) {
    perror ( "mmap" );
    exit ( EXIT_FAILURE );
}
i = 0;
printf("%c\n",data [i + pageoffset]);


来源:https://stackoverflow.com/questions/10164364/segfault-while-using-mmap-in-c-for-reading-binary-files

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!