如何沒有core檔案時,使用syslog中的列印資訊定位程式core的原因
阿新 • • 發佈:2022-03-26
異常列印:
有時候在生產環境中因為種種原因,程序coredump以後沒有生成core檔案。但是一般會在syslog中都會有如下的列印,這將是我們分析異常的關鍵。
Mar 26 10:17:37 ywh-virtual-machine kernel: [ 1818.141888] a.out[34255]: segfault at 40 ip 0000560811a8c250 sp 00007ffe890cdb20 error 4 in a.out[560811a8c000+1000] Mar 26 10:17:37 ywh-virtual-machine kernel: [ 1818.141950] Code: f3 0f 1e fa 55 48 89 e5 be ff ff 00 00 bf 01 00 00 00 e8 9c ff ff ff 5d c3 90 f3 0f 1e fa 55 48 89 e5 48 89 7d f8 48 8b 45 f8 <8b> 40 40 5d c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 41 57
錯誤分析:
segfault at 40 ip 0000560811a8c250 sp 00007ffe890cdb20 error 4 in a.out[560811a8c000+1000]
1. error 4 :
error number是由三個字位組成的,從高到底分別為bit2 bit1和bit0,所以它的取值範圍是0~7. bit2: 值為1表示是使用者態程式記憶體訪問越界,值為0表示是核心態程式記憶體訪問越界 bit1: 值為1表示是寫操作導致記憶體訪問越界,值為0表示是讀操作導致記憶體訪問越界 bit0: 值為1表示沒有足夠的許可權訪問非法地址的內容,值為0表示訪問的非法地址根本沒有對應的頁面,也就是無效地址 所以錯誤error 4,轉換成二進位制就是:110 ,即bit2=1, bit1=0, bit0=0, 按照上面的解釋,我們可以得出程式異常是由於使用者態非法讀操作造成的。 2. at 40(gdb) p ((test_core*)0)->c Cannot access memory at address 0x40
這裡通過 get_c() 獲取物件成員c的值,成員c的在物件中的偏移量就是 0x40。
3. ip 000055c2905b1250
這個就是CPU當前執行的指令地址,也就是這句指令導致core的,可以通過使用addr2line工具解析。
addr2line -e a.out 0000555555555250
我可以知道程式在哪一行崩潰的。如果程序沒有帶gdb除錯資訊,我們可以取一個相同版本程式碼編譯一個帶gdb的程序,獲取行號資訊。
4. sp 00007ffe890cdb20
程式棧指標,可以定位出當前程式在哪個函式中執行時core的。
5. in a.out[560811a8c000+1000]
6.a.out[
34255
]
程序的名字,以及程序的pid。
示例程式:
程式建立了一個空物件指標,然後通過這個指標呼叫物件方法,訪問物件成員。
#include<iostream> using namespace std; class test_core { test_core(void); ~test_core(); public: void set_c(int c){ this->c = c; }; int get_c(void){ return this->c; } private: int a; int b[15]; int c; };
int main() { test_core *p = NULL; p->get_c(); return 0; }