简体   繁体   English

MMAP分割错误

[英]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() 并且还必须使用stat()来获取文件信息,而不是getpagesize()

You can't fclose() a file descriptor you got from open() . 您不能fclose()open()获得的文件描述符。 You must use close(fp) instead. 您必须改为使用close(fp) What you do is passing a small int that gets treated as a pointer. 您要做的是传递一个被当作指针的小int 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. 通常, fp是指向文件的指针(标准IO库使用的FILE* ),而fd是内核的IO系统调用使用的文件描述符(一个小整数)。

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. 您的编译器应该告诉您,您传递了一个预期指向文件的指针的int ,或者您在范围内没有原型的情况下使用了fclose()。 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. 如果data指针未指向以NUL(0)终止的字符串,则可能会发生另一个段错误。 Does your log.txt contain NUL-terminated strings? 您的log.txt是否包含NUL终止的字符串?

You should also check if mmap() fails returning MAP_FAILED . 您还应该检查mmap()无法返回MAP_FAILED

mmap's man page gives you information on the parameters: mmap的手册页为您提供有关参数的信息:

void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset); void * mmap(void * addr,size_t长度,int prot,int标志,int fd,off_t偏移量);

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? 另外:可能0不是有效的标志值? 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. flags参数确定对映射的更新是否对映射同一区域的其他进程可见,以及是否将更新进行到基础文件。 This behavior is determined by including exactly one of the following values in flags: MAP_SHARED or MAP_PRIVATE 通过在标志中完全包含以下值之一来确定此行为:MAP_SHARED或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. 事先检查log.txt的大小。

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();' 在我使用“ getpagesize();”之前 thanks beej !!! 谢谢蜜蜂!

The second argument to mmap should not be page size, it should be the size of your file. mmap的第二个参数不应为页面大小,而应为文件的大小。 Here is a nice example. 是一个很好的例子。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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