简体   繁体   中英

MMAP segmentation fault

int  fp, page;
char *data;

if(argc > 1){
    printf("Read the docs");
    exit(1);
}

fp = open("log.txt", O_RDONLY); //Opening file to read 
page = getpagesize();
data = mmap(0, page, PROT_READ, 0,fp, 0);

initscr(); // Creating the ncurse screen
clear();
move(0, 0); 
printw("%s", data);
endwin(); //Ends window
fclose(fp); //Closing file 
return 0;

Here is my code I keep getting a segmentation fault for some reason. All my header files have been included so that's not the problem (clearly, because its something to do with memory). Thanks in advance.

Edit: Got it - it wasn't being formatted as a string. and also had to use stat() to get the file info rather than getpagesize()

You can't fclose() a file descriptor you got from open() . You must use close(fp) instead. What you do is passing a small int that gets treated as a pointer. This causes a segmentation fault.

Note that your choice of identifier naming is unfortunate. Usually fp would be a pointer-to-FILE ( FILE* , as used by the standard IO library), while fd would be a file descriptor (a small integer), used by the kernel's IO system calls.

Your compiler should have told you that you pass an int where a pointer-to-FILE was expected, or that you use fclose() without a prototype in scope. Did you enable the maximum warning level of your compiler?

Another segfault is possible if the data pointer does not point to a NUL (0) terminated string. Does your log.txt contain NUL-terminated strings?

You should also check if mmap() fails returning MAP_FAILED .

mmap's man page gives you information on the parameters:

void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);

As you can see, your second argument may be wrong (except you really want to exactly map a part of the file fitting into a single page).

Also: Probably 0 is not a valid flag value? Let's have a look again at the man page:

The flags argument determines whether updates to the mapping are visible to other processes mapping the same region, and whether updates are carried through to the underlying file. This behavior is determined by including exactly one of the following values in flags: MAP_SHARED or MAP_PRIVATE

So you could try something like

data = mmap(0, size, PROT_READ, MAP_SHARED, fp, 0);
  • Always use the provided flags, as the underlying value may differ from machine to machine.

  • Also, the mapped area should not be larger than the underlying file. Check the size of log.txt beforehand.

Okay so here is the code that got it working

#include <sys/stat.h>
int status;
struct stat s;
status = stat(file, &s);

if(status < 0){
    perror("Stat:");
    exit(1);

data = mmap(NULL, s.st_size, PROT_READ, MAP_PRIVATE, fd, 0);

Before i was using 'getpagesize();' thanks beej !!!

The second argument to mmap should not be page size, it should be the size of your file. Here is a nice example.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM