Linux 下 core dump 的 gdb 除錯
一、前言
linux下開發時,有時候程式突然崩潰了,沒有任何日誌。
從core檔案中分析原因,通過gdb看出程式掛在哪裡,分析前後的變數,找出問題的原因。
core檔案都帶有程序名稱、程序ID、和時間,這又是怎麼做到的呢?接下來記錄core檔案的生成和配置。
二、基本概念
當程式執行的過程中異常終止或崩潰,作業系統會將程式當時的記憶體狀態記錄下來,儲存在一個檔案中,這種行為就叫做Core Dump(中文有的翻譯成“核心轉儲”)。我們可以認為 core dump 是“記憶體快照”,但實際上,除了記憶體資訊之外,還有些關鍵的程式執行狀態也會同時 dump 下來,例如暫存器資訊(包括程式指標、棧指標等)、記憶體管理資訊、其他處理器和作業系統狀態和資訊。
core dump 對於程式設計人員診斷和除錯程式是非常有幫助的,因為對於有些程式錯誤是很難重現的,例如指標異常,而 core dump 檔案可以再現程式出錯時的情景。
三、配置系統,開啟core dump
1、檢視系統中core檔案生成的開關是否開啟
1)使用ulimit -c命令可檢視core檔案的生成開關,若結果為0,則便是關閉了此功能,不會生成core檔案。
2、設定core檔案生成
可使用命令ulimit開啟,或在程式中通過setrlimit系統呼叫開啟。
(1)使用命令 ulimit -c filesize (只對當前shell程序有效)
若 ulimit -c unlimited ,則標識此core檔案的大小不受限制
若指定 ulimit -c 1024,如果生成的資訊超過1024,將會被裁剪,最終生成一個不完整的core檔案,在調 試此core檔案時,gdb會提示錯誤。
(2)但是若想整個系統中生效則方法如下:
<1> 編輯 /root/.bash_profile 檔案,在其中加入 ulitmit -S -c unlimited (一勞永逸)
<2> source /root/.bash_profile
# ulimit -c
0
$ ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
file size (blocks, -f) unlimited
3、core檔案的設定
1) /proc/sys/kernel/core_uses_pid 可以控制core檔案的問價名是否新增PID作為擴充套件,檔案的內容為1,
標識新增PID作為擴充套件,生成的core檔案格式為core.XXXX;為0則表示生成的core檔案統一命名為core;
可通過一下命令修改此檔案:
echo "1" > /proc/sys/kernel/core_uses_pid
2)core檔案的儲存位置和檔名格式
echo "/corefile/core-%e-%p-%t" > core_pattern,
可以將core檔案統一生成到/corefile目錄下,產生的檔名為core-命令名-pid-時間戳,以下是引數列表: %p - insert pid into filename 新增pid %u - insert current uid into filename 添加當前uid %g - insert current gid into filename 添加當前gid %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 新增命令名
三、用gdb檢視core檔案
發生core dump之後, 用gdb進行檢視core檔案的內容, 以定位檔案中引發core dump的行.
gdb [exec file] [core file]
如: gdb ./selfminitor core.23314
使用gdb 除錯方法,首先要在gcc編譯時加入-g選項。
除錯core檔案,在Linux命令列下:gdb pname corefile。
例如,程式名為selfminitor,core檔案為core.3421,則為:gdb selfminitor core.3421。
這樣進入了gdb core除錯模式。
追蹤產生segmenttation fault的位置及程式碼函式呼叫情況:
gdb>bt
這樣,一般就可以看到出錯的程式碼是哪一句了,還可以打印出相應變數的數值,進行進一步分析。
gdb>print 變數名