2011-12-23 51 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

相關問題