2011-12-23 18 views
1

这段代码为什么会出现分段错误?mmap:map_anonymous它为什么给SIGSEGV?

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/mman.h> 
#include <string.h> 

int main() 
{ 
    void *ptr; 

    ptr=mmap(NULL, 10, PROT_READ|PROT_WRITE, MAP_ANONYMOUS, -1, 0); 
    strcpy(ptr, "Hello"); 

} 

或者更好,我想有:char *ptr=malloc(10);然后通过这个参数的mmap。两者都给出了SIGSEGV。

回答

10

检查系统调用的返回值!

flags参数mmap必须具备以下两个选项只有一个:

MAP_SHARED 
    Share this mapping. Updates to the mapping are visible to other processes 
    that map this file, and are carried through to the underlying file. The file 
    may not actually be updated until msync(2) or munmap() is called. 

MAP_PRIVATE 
    Create a private copy-on-write mapping. Updates to the mapping are not 
    visible to other processes mapping the same file, and are not carried through 
    to the underlying file. It is unspecified whether changes made to the file 
    after the mmap() call are visible in the mapped region. 

你不提供,所以mmap是最有可能失败与errno集(返回(void*)-1)到EINVAL

+1

+1,依靠分段故障作为诊断手段可能并不总能产生理想的结果。 – 2011-12-23 13:47:13

+0

非常感谢,它解决了。现在我使用malloc的返回值作为mmap的第一个参数,并且这也起作用。你认为映射内存而不是只有malloc可能会造成一些开销吗? – kingsmasher1 2011-12-23 13:52:50

+0

@ kingsmasher1:是的,潜在的很多。最小映射'mmap'实现为1页(在很多系统上4k,但可以更大),所以它不适合小分配(除非您自己管理映射内的小块)。介绍开销(OS和CPU),不要认为你会找到一种快速而廉价的方式来实现你的目标,这很难做到,几乎不可能做到“完美” - 甚至valgrind也不行捕获所有无效的内存引用,并且它实际上调整了整个CPU_。 – Mat 2011-12-23 13:57:22

0

由于您的mmapEINVALerrno中,您可能获得MAP_FAILED(即,(void*)-1)。该man page of mmap(2)说,它失败

EINVAL We don't like addr, length, or offset (e.g., they are too large, 
      or not aligned on a page boundary). 

你的第二个参数mmap(称为手册页length)不能10.应该页长(至少4K)的倍数。

+0

没有要求'长度'是页面大小的倍数。 (Linux系统调用的手册页在kernel.org上比在die.net上要好得多 - 它们是最新的,实际上格式正确。) – Mat 2011-12-24 08:48:29

相关问题