2014-12-02 71 views
0

我試圖在Ubuntu上運行下面的程序,但它崩潰與分段錯誤。當調用mmap兩次SIGSEGV

我想要做的就是調用MMAP兩次:

p1 = mmap(null, size: 16 * 4k, offset: 0); 
p2 = mmap(p1+(16*4K), 136 * 4k , offset: 16 * 4k); 

基本上,試圖創建一個鏡像文件連續兩個區域的兩個連續的內存區域。 第二個mmap可能會失敗,但我想知道它爲什麼會導致分段錯誤。

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

int main() 
{ 
    int fd, ret; 
    void* p1; 
    void* p2; 
    unlink ("test.file");// don't care if it doesn't exists 

    fd = open("test.file", O_RDWR | O_CREAT | O_SYNC, ALLPERMS); 

    if(fd == -1) 
     return errno; 

    ret = ftruncate(fd, 4096*16); 
    if(ret != 0) 
     return errno; 

    p1 = mmap(NULL, 4096*16, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 
    if(p1 == (void*)-1) 
     return errno; 

    ret = ftruncate(fd, 4096*150); 
    if(ret != 0) 
     return errno; 

    // dies here! 
    p2 = mmap(p1 + (4096*16), 4096*(150-16), PROT_READ | PROT_WRITE, MAP_SHARED |MAP_FIXED, fd, 4096*16); 
    if(p2 == (void*)-1) 
     return errno; 


    return 0; 
} 

回答

3

它可能會在您的映射之前和之後分配防護頁以防止溢出您的映射,它們應該在讀取和寫入時發生段錯誤。另一個選擇是,你擊中堆棧下的守衛頁面。確認pmap後輸出第一個mmap

嘗試使用mremap代替。

+0

嗨馬克西姆,非常感謝你,你能指點我一些資源,以獲得更多的信息嗎? – 2014-12-02 19:14:49

+0

@AyendeRahien我能夠重現它,但沒有更多的原始源代碼。可能是地址空間隨機化。 – 2014-12-02 19:51:57