2013-07-09 112 views
8

In Linux, the mmap(2) man page解釋了一個匿名映射匿名mmap零填充?

。 。 。沒有任何文件支持;其內容被初始化爲零。

The FreeBSD mmap(2) man page沒有做出零填充了類似的保證,儘管它承諾在非匿名的映射文件結束後的字節是零填充。

哪個Unix的口味承諾返回來自匿名mmaps零初始化的內存?哪些在實踐中返回零初始化內存,但在他們的手冊頁上沒有這樣的承諾?

這是我的印象是零填充部分是出於安全考慮。我想知道是否有任何mmap實現會跳過零填充頁面,該頁面被mmap,munmapped,然後再由單個進程再次映射,或者任何實現用僞隨機位或一些非零常量填充新映射的頁面。

P.S. Apparently, even brk and sbrk used to guarantee zero-filled pages.我在Linux上的實驗似乎表明,即使整個頁面都是零填充在後SBRK呼叫分配他們缺頁,部分頁都沒有:

#include <unistd.h> 
#include <stdio.h> 

int main() { 
    const intptr_t many = 100; 
    char * start = sbrk(0); 
    sbrk(many); 
    for (intptr_t i = 0; i < many; ++i) { 
    start[i] = 0xff; 
    } 
    printf("%d\n",(int)start[many/2]); 
    sbrk(many/-2); 
    sbrk(many/2); 
    printf("%d\n",(int)start[many/2]); 
    sbrk(-1 * many); 
    sbrk(many/2); 
    printf("%d\n",(int)start[0]); 
} 

回答

7

很難說哪些不只是諾言詳盡地枚舉所有手冊頁或其他發佈文檔,但處理MAP_ANON的底層代碼(通常是?總是?)也用於在bss空間中映射可執行文件,並且bss空間需要填充爲零。所以這很可能。至於「給你回舊的價值」(或一些非零值,但最有可能的是,你的舊價值),如果你取消映射並重新映射,那麼肯定似乎有可能,如果某些系統是「懶惰的」 「關於釋放。我只使用了一些支持mmap的系統(BSD和Linux衍生產品),至少在處理mmap的內核代碼中,這兩種系統都不是懶惰的。

原因sbrk可能會或可能不會零一補「再成長」頁面可能依賴於歷史,或缺乏。目前的FreeBSD代碼與我之前記得的mmap天相匹配:有兩個半祕密變量,minbrkcurbrk,並且brksbrk只會調用SYS_break(真正的系統調用),如果它們正在移動curbrk達到至少爲minbrk的值。 (實際上,這看起來略微沙啞:brk擁有的,至少行爲,但sbrk只是增加了它的參數來curbrk並調用SYS_break似乎是無害的,因爲內核檢查,在/sys/vm/vm_unix.csys_obreak(),所以太消極sbrk()將失敗,並EINVAL。 )

我不得不看看Linux C庫(也可能是內核代碼),但它可能會簡單地忽略嘗試「降低中斷」並僅在libc中記錄「邏輯中斷」值。如果你有mmap()並沒有向後兼容性的要求,你完全可以在libc中實現brk()sbrk(),使用匿名映射,這將是微不足道兩者實施的「增長 - 僅」,因爲它是。