2011-09-21 15 views
1

保護頁面以進行讀取和/或寫入訪問是可能的,因爲頁表項中的位可以在內核級別打開和關閉。有沒有一種方法可以保護某些區域的內存不受寫訪問的限制,比如說在C結構中有某些需要寫保護的變量,並且對它們的任何寫訪問都會觸發段錯誤和核心轉儲。它像mprotect()的縮小功能,就像在頁面級別工作一樣,在用戶空間的字節級有類似的東西。字節級寫訪問保護?

謝謝,Kapil Upadhayay。

回答

5

不,沒有這樣的設施。如果您需要每個數據對象的保護,則必須爲每個對象分配至少一個頁面(使用mmap)。如果您還希望有一些防止訪問超出對象末尾的限制(對於數組),那麼您可能會分配至少一個多於您所需的頁面,請將對象對齊,以便它在頁邊界處結束,並使用mprotect來保護您分配的一個或多個額外頁面。

當然這種方法會導致程序非常慢並浪費大量資源。除了作爲一種調試技術之外,它可能是不可行的,並且valgrind可以更有效地滿足這種需求,而無需修改程序...

+0

如果你想編寫可移植的代碼,這是真的,但gdb幾乎在任何地方都實現了內存觀察點,所以毫無疑問,它使用的一些技巧將有助於特定的實現。如果這是字級或更大而不是字節級別,則可以大致描述Roland所描述的內容:捕獲條件,檢查地址是否實際上是您之後的地址。 –

+0

我認爲它保護整個頁面,處理錯誤,並且只在寫入匹配觀察點時才停止執行。雖然我可能會誤解;我認爲一些硬件有少量特定的地址可以作爲觀察點安裝,但絕對不是你可以大規模進行的。 –

+0

如果它不這樣做,那麼它可能會更好,更精確的是性能優化:-)我認爲重要的一點是,你不*有*分配一個頁面或更多的每個對象,你可以實現在硬件級別的保護措施完成之後您自己的保護措施。 –

4

儘管非常慢,但一種方法是保護對象所在的整個頁面。每當對該頁面的寫入訪問發生時,您的無效頁面訪問自定義處理程序被調用並通過快速解除頁面保護,寫入數據然後再次保護頁面來解決這種情況。

這適用於單線程程序,我不確定該怎麼做多線程程序。

這個想法可能並不新鮮,所以你可能能夠找到一些信息甚至是現成的實現。

+0

對於多線程程序 - 如果你的保護處理程序是一個單獨的進程(例如使用'ptrace'),你可以停止整個進程(通過'SIGSTOP'或者一些'ptrace'特定的方法),然後你不必擔心比賽。如果它處於同一個進程中,那麼可以使用一個特殊的信號來捕捉信號處理程序中的所有線程,並將它們保持在那裏,直到處理程序完成。無論哪種方式,它都會有可怕的表現。 –