2011-06-02 65 views
4

當存儲器被訪問(讀或寫)時,是否存在一種方法來分配某些內存並進行某種回調(指向函數或信號的指針)?內存訪問回調?

例如,如果我說分配1mb的內存,我想有一個方法來調用一個函數,當任何1mb被訪問。

我正在使用的平臺是x86 Linux,並使用C/C++編寫。

+0

可能重複的[可能陷入寫入地址(x86-linux)](http://stackoverflow.com/questions/608584/possible-to-trap-write-to-address-x86-linux) – caf 2011-06-02 07:52:18

回答

5

是的,有。

使用mprotect(2)系統調用(請參閱:http://linux.die.net/man/2/mprotect)在頁面上設置只讀或無訪問內存保護,並設置在訪問內存時調用的SIGEGVsignal處理函數。

請注意,您需要在您的信號處理程序中使用mprotect,以便在您調用信號處理程序後實際允許內存訪問,並且您可以在不知情的情況下打開窗口訪問內存從不同的線程。這可能會也可能不是問題,具體取決於您的具體使用情況。

+0

是,但是這並不能阻止訪問?我認爲問題是如何知道訪問權限,而不是如何防止訪問。 – littleadv 2011-06-02 07:07:28

+0

會發生什麼情況是您的程序獲取了SIGSEGV信號。您可以捕獲信號並使用mprotect更改內存保護以啓用該操作,並且當您從信號處理程序返回時,操作將自動成功,因爲程序指針仍指向相同的位置。 這裏隱藏着一個競賽條件,這可能是也可能不是問題。 我編輯了答案來展開。謝謝 – gby 2011-06-02 07:11:05

+0

@gby - 但是一旦你改變了權限 - 你不再能夠跟蹤它,因爲後續具有相同權限的訪問不會觸發信號。所以這是一次性的事情,不是嗎? – littleadv 2011-06-02 07:12:09

3

您可以使用您自己的「安全指針」類的類的版本,它將包裝分配的指針,並且通過方式實現解除引用操作符。儘管如此,它需要使用它來分配資源。

東西在這幾行:

// based on pretty standard auto_ptr 
template <class T> class auto_ptr 
{ 
    T* ptr; 
public: 
    explicit auto_ptr(T* p = 0) : ptr(p) {} 
    ~auto_ptr()     {delete ptr;} 
    T& operator*()    {return *ptr;} // <<--- add your stuff here 
    T* operator->()    {return ptr;} // <<--- and here 
    // . 
}; 
1

我不認爲有這樣的API這樣做,直到你創建一個圍繞分配的內存的包裝對象,然後對存儲器的訪問是通過這個工作包裝對象。然後這個包裝器對象將能夠看到對底層內存的所有訪問。

0

那麼....你可以設置一個緩衝區。你甚至可以用分配來設置一個數組。然後設置一個if語句,如果有任何篡改該數組段,例如,如果該數組默認在索引處具有值0,並且現在不是,則調用任何您想要執行的操作。

如果您希望發生很多事情,然後程序中斷並響應被篡改的分配,請設置一個布爾值,並在該值發生更改時,布爾值變爲true,併發佈一個函數以檢查布爾值。