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

2022-08-24 11:51:09 字數 1253 閱讀 6214

嘗試解答以下問題:

1.為什麼cp的方式更新執行中程序的so,程式會coredump

2.採用什麼方式更新已經載入了的so,就可以避免coredump

我們的公共元件絕大部分都支援so形式的自定義外掛程式,比如s++,qzhttp,ttc。在不停程序更新so的時候往往會產生coredump,並且肯定core得莫名其妙,core得讓人心碎。

先看一下用cp的方式更新so的時候發生了什麼事情

strace cp new.so old.so#strace是人間利器

發現老的so被trunc了,這個過程發生的具體的事情是:

1.應用程式通過dlopen開啟so的時候,kernel通過mmap把so載入到程序位址空間,對應於vma裡的幾個page.

2.在這個過程中loader會把so裡面引用的外部符號例如malloc printf等解析成真正的虛存位址。

3.當so被cp覆蓋時,確切地說是被trunc時,kernel會把so檔案在虛擬內的頁purge 掉。

4.當執行到so裡面的**時,因為物理記憶體中不再有實際的資料(僅存在於虛存空間內),會產生一次缺頁中斷。

5.kernel從so檔案中copy乙份到記憶體中去,a)但是這時的全域性符號表並沒有經過解析,當呼叫到時就產生segment fault , 

b)如果需要的檔案偏移大於新的so的位址範圍,就會產生bus

error.

所以,如果用相同的so去覆蓋

a)如果so

裡面依賴了外部符號,coredump

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

所有問題的產生都是因為so被trunc了一把,所以如果不用turnc的方式就避免這個問題。ok,該我們的install 上場了。

strace install new.so old.so

install

的方式跟cp不同,先unlink再creat,當unlink的時候,已經map的虛擬空間vma中的inode結點沒有變,只有inode結點的引用計數為0是,kernel才把它乾掉。

也就是新的so和舊的so用的不是同乙個inode結點,所以不會相互影響。這時只有得啟程式才會使用到新的so。所以採用這種方式的話就可以避免先stop程序,更新so,再重啟程序這樣比較耗時的操作。

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

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

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

先說cp好mv rm的區別 cp from to,則被覆蓋檔案 to的inode依舊不變 屬性也不變 內容變為from的 mv from to,則to的inode變為from的,相應的,to的屬性也成了from的 rm類似 問題,假如程式 main.out依賴的so檔案libtest.so被cp掉,...

Linux下Lua擴充套件so

include include include include include include include include include include include lua.h include lualib.h include lauxlib.h 庫 open 函式的前置宣告 int lu...