2011-08-24 78 views
7

我想知道...當我啓動一個使用共享庫A的程序X,並且在程序運行時,我修改了磁盤上的共享庫,並運行另一個依賴於相同共享的程序Y圖書館。該程序是否會使用共享庫的已有內存版本,或者是否會加載具有後續修改的共享庫的不同實例?共享庫何時被認爲是共享的「相同」?

如何確定是否共享加載的庫或從磁盤重新加載它?

回答

4

動態加載程序只是做普通的舊open(2)mmap(2)電話,以及存儲器映射顛簸的inode引用計數相同的方法,開放FD一樣。因此,如果您爲庫執行通常的原子文件替換技巧,請在文件的新副本中寫下更改,然後將其替換爲舊的名稱,在該點之後開始的任何內容都將拾取新的inode,並且新內容,但正在運行的程序將繼續使用舊的inode和舊內容。

如果您修改了該庫,那麼在write調用之後啓動的任何程序自然都會提取您的更改。更有趣的問題是已經映射的進程發生了什麼。答案可能是「系統不會讓你這樣做」或「未指定,取決於頁面緩存實現的細節」。在Linux執行過程中(這是我不得不手動)輕鬆地進行的:glibc動態加載程序對其所有共享庫地圖使用MAP_DENYWRITE,但沒有記錄,但聽起來像,它的意思是「在映射存在時使該文件不可修改」 。然而,我在內核源代碼中找不到任何東西可以使MAP_DENYWRITE;它可能是一個歷史遺蹟或其他類似的東西。它也使用MAP_PRIVATEhttp://pubs.opengroup.org/onlinepubs/7908799/xsh/mmap.html表示「未確定MAP_PRIVATE映射建立後對底層對象所做的修改是否通過MAP_PRIVATE映射可見」。因此,您可能會也可能無法修改正在運行的進程下的共享庫映像,具體取決於頁面緩存實施的細節。

0

動態加載器使用mmap(2)來加載共享庫,所以所有的魔法真的在mmap(2)

在Linux中的特定情況下,文件映射調用特定的FS-mmap()操作,這通常是有線mm/filemap.c:generic_file_mmap(),這臺vm_ops.fault的文件映射到mm/filemap.c:filemap_fault(),所以魔術被延遲到頁面故障時間。 filemap_fault()嘗試使用find_lock_page()找到頁面緩存中的頁面。

mmap() → fs_file_ops.mmap() → generic_file_mmap() → file_vm_ops.fault = filemap_fault() 
page fault → filemap_fault() → find_lock_page() 
+0

這實際上並沒有回答問題 – zwol