程式執行的時候替換程式檔案會影響程序嗎?

2022-09-19 11:15:08 字數 1486 閱讀 7993

我要公升級乙個程式,在程式執行的時候用新的程式檔案替換舊的程式檔案,然後殺死程序,重新啟動程式。在程式執行的時候替換程式檔案,會導致程序出現異常嗎?

呼叫系統呼叫execve()裝載elf檔案的時候,函式load_elf_binary()為主程式的**段和資料段建立私有的檔案對映,為動態鏈結器的**段和資料段建立私有的檔案對映。動態鏈結器載入主程式依賴的共享庫的時候,呼叫函式mmap()為共享庫的**段和資料段建立私有的檔案對映。

核心為每個檔案建立乙個頁快取。程序讀**段或者資料段中的某一頁的時候,直接把檔案的頁快取中的物理頁對映到程序的虛擬位址空間,當程序修改這一頁的時候,就會生成頁錯誤異常,頁錯誤異常處理程式為檔案的頁快取中的物理頁生成乙個副本,然後把虛擬頁對映到這個副本,和檔案脫離關係。程序沒有修改的虛擬頁,直接對映到檔案的頁快取中的物理頁,如果修改檔案的這一頁,那麼程序可以看到,會影響程序。

第1種替換方法:開啟舊的程式檔案,使用函式ftruncate()把檔案截斷到長度為0,然後把新的程式檔案複製過來。

直接修改程式檔案對程序有影響,假設程序正在函式func1()裡面呼叫函式func2()的時候替換程式檔案,函式func2()的位置變化,那麼會跳轉到乙個未知的地方,導致程序出現異常。

第2種替換方法:使用函式unlink()刪除舊的程式檔案,重新建立檔案,然後把新的程式檔案複製過來。

假設程式檔案是「/sbin/test.elf」,屬於ext4檔案系統。glibc庫的函式unlink()呼叫系統呼叫unlink(),系統呼叫unlink()的處理過程如下。

(1)修改儲存裝置上的ext4檔案系統:從父目錄「sbin」的資料中刪除檔案「test.elf」對應的目錄項;把檔案「test.elf」的索引節點中的硬鏈結計數減1,如果檔案「test.elf」只有乙個硬鏈結,也就是只有乙個名稱,那麼硬鏈結計數變為0,把索引節點插入到孤兒鍊錶。

(2)檔案「test.elf」在記憶體中的dentry結構體,把它從雜湊表刪除,把它的引用計數減1,因為引用計數大於0,所以沒有釋放dentry結構體,沒有真正刪除檔案。

刪除乙個檔案的時候,如果某個程序已經開啟這個檔案,那麼刪除的結果是:從父目錄刪除這個檔案對應的目錄項,把檔案的索引節點中的硬鏈結計數減到0,但是沒有刪除檔案自身。如果程序一直開啟這個檔案,直到裝置斷電,就會造成儲存裝置上檔案的索引節點和資料塊洩漏。為了解決這個問題,ext4檔案系統使用孤兒鍊錶,超級塊的字段s_last_orphan儲存孤兒鍊錶的第乙個索引節點的編號,ext4_inode結構體的字段i_dtime(刪除時間)被重用為儲存下乙個孤兒索引節點的編號。裝置重啟以後,掛載ext4檔案系統的時候,如果孤兒鍊錶不是空的,那麼釋放孤兒鍊錶中的每個索引節點。

當殺死程序的時候,關閉檔案「test.elf」,把記憶體中的dentry結構體的引用計數減1,引用計數變為0,於是釋放dentry結構體,釋放dentry結構體的過程中把inode結構體的引用計數減1,引用計數變為0,處理如下。

(2)釋放記憶體中的inode結構體。

在ext4檔案系統中,舊的程式檔案和新的程式檔案使用不同的索引節點編號,是2個不同的檔案。這種替換方法對程序沒有影響。

程式檔案的優化

1.開啟php加速模組 apache 中使用 mod php 的請求 響應執行流程 1 apache 接收請求 2 apache 傳遞請求給 mod php 3 mod php 定位磁碟檔案,並載入到記憶體中 4 mod php 編譯源 成為 opcode 樹 5 mod php 執行 opcode...

如何獲取當前程式檔案的路徑

程序物件在.net中表現為system.diagnostics.process類,通過呼叫process.getcurrentprocess mainmodule.filename可獲得當前執行的exe的檔名。但是這個方法得到的僅僅是檔名,如果程式執行期間沒有切換工作目錄,那麼可以呼叫system....

IOS應用程式檔案目錄的操作

各位親 有時間可以去看看我的 金駿家居 店 買時說明在我的部落格看到有優惠哦 還有意外禮品贈送 真正的程式設計師 店 iphone沙箱模型的有四個資料夾,分別是什麼,永久資料儲存一般放在什麼位置,得到模擬器的路徑的簡單方式是什麼.一.檔案目錄說明 1 documents 目錄 您應該將所有 的應用程...