關於so檔案cp覆蓋導致呼叫者core的研究

2022-07-10 04:57:09 字數 1028 閱讀 9514

先說cp好mv/rm的區別:

cp from to,則被覆蓋檔案 to的inode依舊不變(屬性也不變),內容變為from的;

mv from to,則to的inode變為from的,相應的,to的屬性也成了from的;rm類似;

問題,假如程式 main.out依賴的so檔案libtest.so被cp掉,會發生什麼?

strace cp test2 test  2>&1 | grep open.*test

open("test2", o_rdonly|o_largefile)     = 3

open("test", o_wronly|o_trunc|o_largefile) = 4

cp的實現邏輯不是「rm + open(o_creat)」,而上面的實現方式才是最可靠的(保證了時序安全和目標檔案的屬性)。這解釋了為什麼cp的目標檔案會繼承被覆蓋檔案的屬性而非原始檔。

linux由於demand paging機制的關係,必須確保正在執行中的程式映象(注意,並非檔案本身)不被意外修改,因此核心在啟動程式後會繫結 記憶體頁 到這個so的inode,而一旦此inode檔案被open函式o_trunc掉,則kernel會把so檔案對應在虛存的頁清空,這樣當執行到so裡面的**時,因為物理記憶體中不再有實際的資料(僅存在於虛存空間內),會產生一次缺頁中斷。kernel從so檔案中copy乙份到記憶體中去,a)但是這時的全域性符號表並沒有經過解析,當呼叫到時就產生segment fault , b)如果需要的檔案偏移大於新的so的位址範圍,就會產生bus error。

備註:如果用相同的so去cp覆蓋

a) 如果so 裡面依賴了外部符號(如標準庫),coredump

b) 如果so裡面沒有依賴外部符號,運氣不錯,不會coredump

不必說,先rm再cp的話,新檔案的inode其實已經改變了,原inode並沒有被真正刪除,直到核心釋放對它的引用(引用舊so的程序退出,而新程序當然呈現的就是新so的效果了,新程序和core無關啦)。同理,mv只是改變了檔名,其inode不變,新檔案使用了新的inode。

參考: 

[1][2]

linux下So覆蓋導致coredump問題的分析

感謝這位大神,我剛好遇到這個問題 嘗試解答以下問題 1.為什麼cp的方式更新執行中程序的so,程式會coredump 2.採用什麼方式更新已經載入了的so,就可以避免coredump 我們的公共元件絕大部分都支援so形式的自定義外掛程式,比如s qzhttp,ttc。在不停程序更新so的時候往往會產...

linux下So覆蓋導致coredump問題的分析

嘗試解答以下問題 1.為什麼cp的方式更新執行中程序的so,程式會coredump 2.採用什麼方式更新已經載入了的so,就可以避免coredump 我們的公共元件絕大部分都支援so形式的自定義外掛程式,比如s qzhttp,ttc。在不停程序更新so的時候往往會產生coredump,並且肯定cor...

求指教 。。。關於呼叫so檔案

問題描述 今天同事給我發來乙個檔案,說讓我通過android呼叫裡面的函式檔案是 裡面的內容是 call so.cpp檔案的內容 pragma pack 1 非常重要的申明,記憶體對齊的方法,影響sizeof 的結果 include include include include operation...