2016-05-29 71 views
2

是否有可能無限延長對內存位置的讀取(並且允許另一個線程允許在任意超時後完成讀取)?可以無限期地訪問文件映射內存

例如,阻止套接字,我們可以得到一個進程使用read系統調用時停止:

fd = socket(AF_UNIX, SOCK_DGRAM, 0); 
read(fd, buffer, 256); 

通常我們不能mmap插座,但我基本上是一樣的東西發生直接訪問內存時:

int x = *(int *)map; 

我知道的技術,使內存訪問需要更長的時間,比如訪問之前使用madvise頁出內存,但我找得到這個持續的方法無限期。

我已經考慮在文件上使用mmap,然後「鎖定」該文件,但找不到適當的接口。系統調用似乎不能以這種方式工作。

具體來說,我對FreeBSD x86-64體系結構感興趣,但對其他類Unix系統(如Linux)以及其他體系結構的答案也將不勝感激。

+0

如果你想「阻止」內存訪問,你可以嘗試mmap()在NFS掛載文件,並在這個內存上執行一些真正的隨機訪問。 – wildplasser

+0

如果該文件位於自定義['FUSE' mount](https://en.wikipedia.org/wiki/Filesystem_in_Userspace)上,您可以獲得任意的行爲。 –

回答

3

您可以使用mprotect(..., PROT_NONE)將包含map的頁面標記爲不可訪問。當您嘗試訪問它時,會發生頁面錯誤,並且會引發SIGSEGV

您可以安裝SIGSEGV的處理程序,聲明時帶有額外的siginfo_t參數。查看該結構的si_addr成員以檢查錯誤地址是否匹配map;這使您可以區分來自其他代碼中的實際錯誤(例如NULL解除引用)的其他錯誤對此地址的訪問。如果是這樣,那麼信號處理程序可以等待直到被另一個線程告知繼續。準備就緒後,請撥mprotectPROT_READ(或PROT_WRITE視情況而定)並從信號處理程序返回;錯誤指令重新啓動並繼續執行。

這是一個相當醜陋的黑客攻擊,我建議你好好看看爲什麼你認爲你需要這樣做。你的問題似乎可能是XY problem

+0

我已經實現了你的建議,它適用於userland訪問(EG:'*(int *)buffer = 0;'),但它不會凍結來自內核的寫入,這是我的最終目標(EG:'getcontext ((ucontext_t *)buffer);')。 – CHRIS

+0

@CHRIS:內核模式是一種完全不同的動物。如果那是你的目標,我希望你這樣說。事實上,你應該問一個新的問題。 –

+0

我會接受你的答案,因爲它適用於我最初描述的問題。謝謝。 – CHRIS