1. 程式人生 > 其它 >如何沒有core檔案時,使用syslog中的列印資訊定位程式core的原因

如何沒有core檔案時,使用syslog中的列印資訊定位程式core的原因

異常列印:

  有時候在生產環境中因為種種原因,程序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
     這個是指發生錯誤的記憶體位置,如果是0表示就是訪問了空指標了,也有可能也不是0。如果是通過空指標訪問物件成員,這個值可能是成員的偏移量。      通過使用GDB檢視物件成員的偏移地址     
(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; }