一、說明
在前一家公司經常測出一些緩沖區溢出導致進程掛掉的問題,開發經常要求在調試模式進行測試,生成core文件給他們定位問題。
當時的調試模式啟動只是修改某些配置文件重新啟動即可,所以在很長一段時間內並不知道到底要如何生成core文件及core文件如何使用。
二、配置允許生成core文件
臨時配置使用ulimit命令進行操作即可:
# 查看當前用戶core文件配置情況 # 0表示允許core文件大小為0,亦即不允許生成 ulimit -c # 限制core文件大小 # 禁止生成core文件 ulmit -c 0 # 限制core文件大小100塊 ulimit -c 100 # 不限制core文件大小 ulimit -c unlimited
要永久生效則修改配置文件/etc/security/limits.conf,使用類似如下形式進行配置:
* soft core unlimited
三、直接的core文件生成
3.1 通過kill觸發生成
# 查看當前core文件大小限制
ulimit -c # 設置成不限制大小 ulimit -c unlimited # 再次查看core文件大小限制 ulimit -c # 新啟動一個bash進程 bash # 查看當前bash的pid echo $$ # 將該進程kill掉,觸發core文件生成 kill -s SIGSEGV $$ # 確認core文件確實已經生成 ll

使用gdb查看core文件即可定位到出錯行,如下圖。

3.2 使用gdb直接生成
# 查看當前bash的pid echo $$ # 通過pid進行gdb調試。為了通用性這里直接使用$$ gdb -p $$ # 生成core文件。在gdb內部輸入 generate-core-file # 退出gdb。在gdb內部輸入 quit # 確認退出gdb。在gdb內部輸入 y # 確認當前目錄下有core文件生成 ls -l | grep $$
3.3 使用gcore生成
# 直接生成當前bash進程的core文件 gcore $$ # 確認core文件已在當前目錄下生成 ls -l | grep $$

四、自己代碼中core文件的使用
第三大節中介紹的幾種方法是可以生成core文件,但是像bash這些程序在編譯時並沒有匯入源代碼,所以要定位代碼也只能定位到匯編語句定位不到源代碼語句。
而對於開發而言,使用core文件的主要目的是為了分析定位程序運行出錯的代碼位置(然后在此基礎上分析出錯的原因)。我們這里就以一個簡單的C程序進行演示。
將以下代碼保存成test.c:
#include <stdio.h> int main() { printf("calc start...\n"); int value = 1/0; printf("calc finished.\n"); return value; }
生成core文件並調試:
# 設置core文件大小限制 ulimit -c unlimited # 編譯文件。-g將源代碼附加到生成的二進制文件中,這樣后邊gdb定位出錯位置時才能顯示源代碼行 gcc test.c -o test -g # 查看當前文件 ls -l # 執行程序觸發生成core文件 ./test # 查看確認core文件生成 ls -l # 使用gdb進行調試。第一個參數是生成core文件的可執行程序,第二個參數是生成的core文件 gdb test core.xxx

可以看到可以直接定位到導致出錯的代碼處:

參考:
https://linux-audit.com/understand-and-configure-core-dumps-work-on-linux/
