Linux幽靈般的coredump之如何定位出錯位置
視覺slam,最近修改了原工程里的數(shù)據(jù)更新部分,由主線程改到子線程中,改完后自認(rèn)為邏輯沒有問題,每次訪問共享數(shù)據(jù)也上了數(shù)據(jù)互斥鎖。
但是卻出現(xiàn)了一個偶發(fā)性bug,有時候運(yùn)行幾次都不會出現(xiàn),有時候軌跡跑到一半就會出現(xiàn)coredump,每次引起coredump的原因也不盡相同如,ibus?error, Segmentation?fault?(core?dumped), corrupted double-linked?list Aborted?(core?dumped) 伴隨的就是程序的立刻中斷,而不帶一絲的錯誤位置信息。
只能網(wǎng)上搜索,給出的方法是查看coredump文件。具體步驟如下
1.查看當(dāng)前系統(tǒng)是否已開啟core文件記錄
????為0測代表沒有開啟,需要輸入 ulimit -c unlimited,表示core文件大小無限制。
2.我們需要設(shè)置core文件生成的位置
3.加上可調(diào)式參數(shù)gcc main.c -o main -g,對于cmake文件需要設(shè)置Debug模式或者release但是O0優(yōu)化(默認(rèn)的優(yōu)化)
4.再次執(zhí)行文件,直到出現(xiàn)coredump,此時進(jìn)入core文件生成的目錄,下面應(yīng)該就有了core文件生成。執(zhí)行gdb ./main core_main.xxx.xxxxxxxx,查看core文件,此時應(yīng)該能看到具體出錯位置了,如果沒有的話輸入bt或者where即可。
當(dāng)然我的問題沒這么簡單,當(dāng)我輸入bt后,依舊沒有出錯的具體位置或者函數(shù),只有下面一些信息:
Backtrace?stopped:?previous?frame?identical?to?this?frame?(corrupt?stack?) 或者 double?free之類的
位置信息也只有 0xb.......... in ?? () 的地址信息,而看不見具體的出錯位置或者函數(shù)。
后來知道了需要將編譯優(yōu)化參數(shù)去掉 O0、O1、O2、O3、Os中,只能用原始的O0,不進(jìn)行優(yōu)化。但是當(dāng)我設(shè)置O0后,原來的slam幀數(shù)就從100fps+變成了0.1-1fps左右。這樣的速度太慢,很難觸發(fā)coredump,跑了十幾分鐘,沒有耐性了,并且可能改為O0不優(yōu)化后,根本觸發(fā)不了錯誤了。我的錯誤大概率是由線程間的不安全訪問導(dǎo)致的。但我訪問公共資源時都加了互斥鎖,相比原來的代碼,我也找不出邏輯錯誤。
總之,這樣使用O3優(yōu)化,雖然能觸發(fā)了coredump,但是看不了具體錯誤位置。O0能從core文件看到具體錯誤位置,但又觸發(fā)不了coredump。直接自相矛盾了。
最后只能妥協(xié),采用wait/notify機(jī)制,線程等待和喚醒,喚醒后再更新數(shù)據(jù),這樣雖然更新數(shù)據(jù)還是在子線程運(yùn)行,試了多次后,沒有觸發(fā)過coredump。缺點(diǎn)就是只有插入了新關(guān)鍵幀,才會更新數(shù)據(jù),pan-golin的可視化交互才可以被相應(yīng),只有此時才能拖動鼠標(biāo)進(jìn)行交互,所以會卡卡的。而slam結(jié)束后,由于沒有新關(guān)鍵幀了,一直處于wait狀態(tài),所以pangolin也無法相應(yīng)鼠標(biāo)交互。相比coredump,這點(diǎn)交互犧牲確實(shí)無傷大雅了。
所以,我還是沒能找到之前coredump的原因(無法理解的偶發(fā)性錯誤),但還是把查看core文件的方法寫下來吧,免得以后又忘了,再查資料又要花很多時間。