1. 程式人生 > 其它 >【Core Dump】核心轉存 故障分析

【Core Dump】核心轉存 故障分析

瀏覽關於coredump的文章時,下面兩篇文章說的清晰易懂,轉發下:

https://blog.csdn.net/asdfghjkl0606/article/details/52841678

https://blog.csdn.net/stpeace/article/details/119699330

http://wjhsh.net/zhchoutai-p-6717780.html

第一篇:簡單介紹coredump基本概念和操作

引言:程式在Linux系統中執行時出錯的時間並不能預測,也許在三分鐘之內程式就崩潰了,也許執行一個月之後才發生錯誤。

如果前一節課學到的GDB除錯,顯然除錯上十天半個月是不可能的。這裡我們用core

dump來解決。

一、Core Dump:資訊轉存、核心轉存。

core dump是一個過程,即Linux會把程式執行過程中發生異常的記憶體內容轉存到core檔案。

core dump主要解決段錯誤(Segment fault)。


二、發生段錯誤的基本原因有:

1、陣列訪問越界;

2、對空指標操作;

3、棧溢位;

4、修改只讀記憶體的內容。

三、啟用/關閉 Core Dump:

開啟:ulimit -c unlimited

關閉:ulimit -c 0

(在Linux系統中預設關閉該功能)

四、Core檔案分析:

 在發生core dump之後會在該程式所在路徑下生成一個core檔案。

注意:在編譯程式時需要用-g來加入除錯資訊,否則將讓錯誤逃之夭夭。

> gdb  ./test  core.13140

#include <stdio.h>
#include <stdlib.h>
 
void main()
{
    int *ptr = NULL;
    
    *ptr = 3;
}

第二篇:告訴你一般定位這類問題的思路


core的最原始含義是磁芯,是一種儲存裝置,dump的意思是倒出,那麼core dump的含義就是:當程序發生異常時,會把當時的記憶體資訊傾倒出來,形成core檔案。

每個做linux C++開發的人,必然會遇到過core dump問題。在C++相關的面試中,core dump的除錯,幾乎是一個必考的考點,旨在檢驗應聘者的實戰除錯經驗。

我知道的一個真實案例是:面試官讓應聘者現場寫出一個core dump程式,結果應聘者很懵圈,不知道怎麼寫。這說明,應聘者沒有相關的除錯經歷,何談通過面試?

接下來,我們以一個簡單的core dump程式為例,來說說除錯core dump的六種經驗和方法,希望能對大家的開發實戰有所幫助,順便地,橫掃那些簡單的面試題。

方法一: 程式碼review

程式碼review,是一種比較原始的笨方法。對於簡單的程式碼而言,還可以進行review, 但是,一旦程式碼達到數萬行,出現core dump後,便無從看起。所以,這種方法很雞肋,幾乎沒什麼用。

方法二: 列印log夾逼

列印log來夾逼,也是一種很簡單的方法,在很多場景下,非常奏效。許多大學生和職場新手,容易出現core dump問題,那麼, 我建議直接用log夾逼。有點類似二分查詢,且看具體的姿勢:其實很多老鳥也是這麼做的。

 方法三: dmesg + addr2line

有時候,如果core dump的開關沒有開啟,無法生成core檔案,那怎麼辦呢?也是有辦法的!用dmesg和addr2line吧。關於這兩個命令的介紹,直接man一下即可。且看具體除錯:​​​​​​​

 以前確實沒用過dmesg。按照上面的操作沒出現相關的段錯誤。

方法四: strace + addr2line

接下來,我們介紹一個重要的linux命令,即strace, 直接man一下就知道,它是用檢視系統呼叫的,我們不過多贅述。來看具體的除錯過程:​​​​​​​

 後面跟的那串數字是什麼含義?地址? 實際操作的時候可以看到段錯誤。但是addr2line 後面那個a.out沒有對應的。

方法五: valgrind

之前,在除錯記憶體洩漏時,介紹過valgrind,其實valgrind能查其他更多記憶體問題,非常強大。下面,我們來看看valgrind查core dump問題,如下:

 valgrind 是 Linux 業內流行且十分強勁的記憶體洩漏查驗專用工具。在其官方網站詳細介紹中,執行記憶體查驗(memcheck)僅僅其在其中一個作用。因為僅用過其記憶體洩漏的查驗,也不擴充套件共享 valgrind 別的作用了。

沒有使用過。暫不描述。

方法六: gdb

gdb除錯,是本文的重頭戲,也幾乎是筆試面試的必考內容。話不多說,直接來看姿勢。使用gdb a.out core(不會重新拉取a.out程序)或者gdb a.out(會重新拉起a.out程序)都可以,如下:​​​​​​​

 第三篇:linux程式除錯命令addr2line之入門簡單介紹

addr2line有什麼作用呢? 可別小瞧它, 它能夠定位到程式碼出錯的位置。

以下, 我們來看看這個簡單的程式碼:

 #include <stdio.h>

int main()
{
        int *p = NULL;
        *p = 0;

        printf("bad");
        return 0;
}

       這個程式非常小, 我們能夠一眼就看出程式在執行期出錯。 可是, 假設是大程式, 在執行期出錯。 我們該怎樣定位呢?  那就必須依賴於工具。 而不是你我的肉眼。

我們以上述小程式為例, 進行例如以下操作:

[taoge@localhost learn_c]$ gcc -o taogeSeg -g taogeSeg.c 
[taoge@localhost learn_c]$ ./taogeSeg 
Segmentation fault (core dumped)
[taoge@localhost learn_c]$ dmesg | grep taogeSeg
taogeSeg[4941]: segfault at 0 ip 080483c9 sp bfb92410 error 6 in taogeSeg[8048000+1000]
[taoge@localhost learn_c]$ addr2line -e taogeSeg 080483c9
/home/taoge/Desktop/learn_c/taogeSeg.c:6
[taoge@localhost learn_c]$ cat -n taogeSeg.c
     1	#include <stdio.h>
     2	
     3	int main()
     4	{
     5		int *p = NULL;
     6		*p = 0;
     7	
     8		printf("bad
");
     9		return 0;
    10	}
[taoge@localhost learn_c]$ 
但是我在實際操作過程中,發現dmesg沒有任何相關的linux core資訊出來。不清楚是不是linux版本問題。
 我來解釋一下:
       1. gcc -o taogeSeg -g taogeSeg.c :生成帶有除錯資訊的可執行檔案taogeSeg        2. dmesg | grep taogeSeg :獲得執行taogeSeg後的出錯資訊, 你能夠將結果理解為日誌, 當中的080483c9是一個地址, 正是這個地址出錯了        3. addr2line -e taogeSeg 080483c9 :將出錯地址轉換成原始碼相應的行, 結果為6, 也就是說原始碼第6行有問題。 一看, 果然是,萬惡的*p=0;被揪出來了。
       當然。 針對這個樣例, 會gdb除錯的朋友肯定也能調試出來,並且也確實能找到程式碼出錯的地址和原始碼行, 從這個意義上來講。 gdb內部也攜帶了類addr2line的功能。這是不是說gdb就能夠替代addr2line呢? 不是的。

假設某bug低概率發生。 如今僅僅有一份crash log, 那就要用addr2line了, 由於你用gdb時。 該bug不一定發生啊。


            實際上, 在非常多linux大型軟體開發中, 常常出現段錯誤, 造成程序掛掉, 系統崩潰等問題, 此時, 用addr2line是比較好的方法。

在後面的博文中, 我們會繼續瞭解與addr2line有關的除錯方法, 畢竟, 程式碼除錯太重要了。事實上呢, 假設不熟悉addr2line的使用, 或者乾脆沒有聽說過這個命令, 那最好不要說自己搞linux開發。 免得被人歧視啊。 



       OK, 本文僅僅是一個引子, 能在實戰中熟練使用addr2line才見真功夫。

如能熟練掌握addr2line的使用。 以後聽到什麼段錯誤, 系統崩潰。 就沒那麼毛骨悚然了。