1. 程式人生 > >【Linux】使用gdb快速定位core dump

【Linux】使用gdb快速定位core dump

前言

如果你沒有見過core dumped,說明你不是一個合格的Coder(但並不代表知道就是合格的Coder),在Linux作業系統下,通過gcc、g++編譯出的程式碼就有可能出現這樣的問題(windows下一般都是棧溢位),下面就具體的core dumped的一系列操作作以說明。

什麼是core dumped?

core dumped即段錯誤,當然它也有更官方的說法,稱之為核心轉儲。當某一個程序在異常退出時,核心有可能把該程式當前記憶體對映到core檔案裡,即以檔案的方式儲存於硬碟上,方便後續的gdb除錯。

下面看一個簡短的程式(非法賦值):

#include <stdio.h>
int main() { char* str = "hello world"; str[1] = 'H'; return 0; }

執行結果: 在這裡插入圖片描述 從執行結果可以很清晰的看見core dumped,即段錯誤,也稱核心轉儲。出現core dumped主要有以下幾個原因:

① 記憶體訪問越界:由於使用錯誤的下標,導致陣列越界。 ② 多執行緒程式使用了執行緒不安全的函式。 ③ 多執行緒讀寫的資料未加鎖保護。 ④ 非法指標:比如指標的++操作,使用空指標以及隨意轉換指標型別等。 ⑤ 堆疊溢位。Linux預設的棧大小為10M(與Linux核心版本有關),比如定義一個數組(空間在棧上)大於此預設空間就會溢位。

當我們出現core dump時,如何獲取具體的錯誤資訊?我們先使用ulimit -a命令來檢視系統資源限制。 在這裡插入圖片描述 預設為0,即不會生成core檔案,需要修改core file size的值在編譯連結時生成core file。 既然core file儲存了錯誤資訊,目的是後續的gdb除錯,那麼為什麼作業系統(在Linux下)預設關閉?

如果作業系統對core file預設開啟,一旦程式上線之後,程式就脫離了程式設計師的管理範疇,此時程式設計師可能不知情,程式一直重啟掛掉重啟掛掉,那麼你的硬碟上就會dump出很多檔案,將你的硬碟空間慢慢吞噬,甚至將你的作業系統掛掉。

我們可以使用ulimit -c來改變core檔案的大小(臨時改變,重啟後恢復預設): 在這裡插入圖片描述

現在我們執行剛才的程式看是否生成了core檔案。 在這裡插入圖片描述 從上述結果可以看出,此時重新編譯連結會生成一個core.5321的檔案,5321為引起錯誤的程序id。進入gdb模式並定位dump資訊需要兩步:

① gdb [可執行程式] [dump檔案] 進入gdb模式。 [root@bogon Core_file]# gdb Core core.5321 ② 使用where或core-file [core.(程序號)]定位dump的錯誤資訊。

從結果可以看出,程式第12行出錯,快速定位了dump的位置。以上就是gdb模式下dump錯誤資訊的定位,下一節我將對gdb的使用技巧作以闡述。