一.簡單介紹什麼是core檔案以及他的作用
在linux編寫的C/C++可執行程式往往會出現如下圖的錯誤,一個core dumped。由于剛開始對linux的認識不足,就忽略了這樣一個重要的調試資訊。

随着學習的深入,其實core檔案在linux下是一種ELF格式的檔案,有關于什麼是ELF格式大家可以自行查閱相關的内容。
實際上core檔案就是可執行檔案執行時的映像,也可以叫做記憶體的快照。儲存下來可執行程式在執行過程的點點滴滴。除了記憶體資訊之外,還有些關鍵的程式運作狀态也會同時dump下來,例如寄存器資訊(包括程式指針、棧指針等)、記憶體管理資訊、其他處理器和作業系統狀态和資訊。core檔案對于程式員診斷和調試程式是非常有幫助的,因為對于有些程式錯誤是很難重制的,例如指針異常,而core檔案可以再現程式出錯時的情景。結合gdb的調試指令可以對core檔案進行調試。
二.如何儲存core檔案。
在linux下,預設的情況是core dumped并不産生core檔案,因為此項功能預設是被關閉。使用
ulimit -c
指令可以檢視是否啟動core檔案。執行上述指令後會有如下的三種可能分别代表着不同的意義:
1.0 不能産生core檔案
2.unlimited 産生的core檔案沒有位元組限制
3.一個确定數字 當超過這個位元組數時不能産生core檔案,小于等于時可以産生core檔案
複制
綜上,隻需要使用ulimit -c unlimited就可打開core檔案了,注意需要在root使用者下執行此指令,否則權限不足執行失敗。而且這樣的設定是一次性的,下次重新開機後就需要重新設定。一勞永逸的辦法就是在配置檔案寫入上述的設定。此步設定好之後,當你的可執行程式再次出現core dumped的情況時,就會在目前目錄下出現一個core檔案。如下:
三.設定core檔案的生成路徑以及core檔案的名稱格式。
(1)設定程序的pid作為core檔案擴充名,這樣的好處是當core文有很多時,可以區分是哪一個可執行程式産生的core檔案,友善查找。
1:添加pid作為擴充名,生成的core檔案名稱為core.pid
0:不添加pid作為擴充名,生成的core檔案名稱為core
//修改方法
1.修改 /proc/sys/kernel/core_uses_pid 檔案内容為: 1
2.在終端執行如下兩條指令的任意一條
echo "1" > /proc/sys/kernel/core_uses_pid
sysctl -w kernel.core_uses_pid=1 kernel.core_uses_pid = 1
複制
(2)修改core檔案的檔案格式以及儲存路徑
執行如下兩條指令中的一條即可
1.echo "/corefile/core-%e-%p-%t" > /proc/sys/kernel/core_pattern
辨別生成的core檔案名格式是 core-%e-%p-%t,儲存路徑為/corefile
sysctl -w kernel.core_pattern=/corefile/core-%e-%p-%t kernel.core_pattern = /corefile/core-%e-%p-%t
複制
以下是參數清單:
%p - insert pid into filename 添加pid(程序id)
%u - insert current uid into filename 添加目前uid(使用者id)
%g - insert current gid into filename 添加目前gid(使用者組id)
%s - insert signal that caused the coredump into the filename 添加導緻産生core的信号
%t - insert UNIX time that the coredump occurred into filename 添加core檔案生成時的unix時間
%h - insert hostname where the coredump happened into filename 添加主機名
%e - insert coredumping executable name into filename 添加導緻産生core的指令名
複制
三.使用core檔案進行簡單debug。
測試程式一:
#include <iostream>
using namespace std;
int main(){
int *p;
*p = 20;//使用野指針
}
複制
對于上述這樣的一個小程式很容易定位到錯誤的源頭,但是對于一個成百上千行的代碼來說定位一個錯誤就不容易了尤其是在運作之後發生的bug,但是使用core檔案卻很容易定位。
調試上述檔案生成的core檔案:
通過core檔案可以清楚的定位到錯誤的根源,可見core檔案的強大之處。
測試程式二:
test1.cpp
#include <iosreram>
using namespace std;
int main(){
cout<<(10 / 0)<<endl;
return 0;
}
複制
使用test1生成的core檔案定位錯誤: