1. 程式人生 > >程式執行崩潰(segfault)的排查方法

程式執行崩潰(segfault)的排查方法

我的筆記:

寫的C++程式老是執行兩三天就掛了,關鍵是掛的時候連“segment fault”都不顯示。動用了gdb、valgrind還是沒辦法,最後還是根據系統的日誌定位到了問題。

首先,最好是在編譯時加上debug選項(-g)。

程式掛掉後,在終端通過指令

dmesg
#或者
dmesg | grep 你的程式名

在系統日誌中查詢到相關的資訊。

隨便寫個例子:

a.out[2374]: segfault at 7f0ed0bfbf70 ip 00007f0edd646fe7 sp 00007f0ed3603978 error 4 a.out[7f0edd514000+1b6000]

at(位置),ip(instruction pointer 指令指標),sp(stack pointer 堆指標),後面跟的都是地址。

對這三個地址分別執行

addr2line -e a.out xxxxxxxx
這裡的“xxxxxxxx”就是上面的“7f0ed……”,前面的0可以省略,三個地址都試一下。如果成功了,終端會打印出來這個地址對應的程式碼行(前面提到編譯時要加-g)。

這裡的“error 4”是什麼意思?把它更換成二進位制表示,就是:100。說明是使用者態記憶體訪問越界了

bit2:值為1表示是使用者態程式記憶體訪問越界,值為0表示是核心態程式記憶體訪問越界
bit1:
值為1表示是寫操作導致記憶體訪問越界,值為0表示是讀操作導致記憶體訪問越界
bit0:
值為1表示沒有足夠的許可權訪問非法地址的內容,值為0表示訪問的非法地址根本沒有對應的頁面,也就是無效地址

然後就去找問題啦。如果是自己程式碼的問題,上面執行“addr2line”的時候就直接把出錯的程式碼行號都給出來了;如果是動態庫的問題,可以借鑑上面連結部落格裡的經驗。