Linux 生成 core dump的方法及設置


core dump 定義
A core dump is the recorded state of the working memory of a computer program at a specific time, generally when the 
program has terminated abnormally (crashed). In practice, other key pieces of program state are usually dumped at 
the same time, including the processor registers, which may include the program counter and stack pointer, memory 
management information, and other processor and operating system flags and information. The name comes from the 
once-standard memory technology core memory. Core dumps are often used to diagnose or debug errors in computer programs.

On many operating systems, a fatal error in a program automatically triggers a core dump, and by extension the phrase 
"to dump core" has come to mean, in many cases, any fatal error, regardless of whether a record of the program memory 
is created.

core dump的生成方式

Linux環境下進程發生異常而掛掉,通常很難查找原因,但是一般Linux內核給我們提供的核心文件,記錄了進程在崩潰時候的信息。但是生成core文件需要設置開關,具體步驟如下:

1、查看生成core文件的開關是否開啟,輸入命令

ulimit -a

第一行core文件大小為0,沒有開啟。

2、使用 ulimit -c [kbytes] 可以設置系統允許生成的core文件大小。

ulimit -c 0              #不產生core文件
ulimit -c 100            #設置core文件最大為100k
ulimit -c unlimited      #不限制core文件大小    

執行命令 ulimit -c unlimited,然后ulimit -a查看core

 這樣進程崩潰就可以生成core文件了,這種方法只能在shell中生效,需要此設置一直生效需要做如下設置

vim /etc/profile                                   #然后進入編輯模式,在profile文件中加入
ulimit -c unlimited

 保存退出,重啟服務器,改文件就長久生效,或者

source /etc/profile

不重啟服務器,使用source使文件馬上生效。

3.指定生成文件的路徑和名字

默認情況下,core dump生成的文件名為core,而且就在程序當前目錄下。新的core會覆蓋已存在的core, 通過修改/proc/sys/kernel/core_uses_pid文件,可以控制core文件保存位置和文件格式。

vim /etc/sysctl.conf                                      #進入編輯模式,加入下面兩行

kernel.core_pattern=/tmp/corefile/core_%t_%e_%p
kernel.core_uses_pid=0

在var下創建core目錄,用

sysctl –p /etc/sysctl.conf

是修改馬上生效。

core_pattern的命名參數如下:

%c 轉儲文件的大小上限
%e 所dump的文件名
%g 所dump的進程的實際組ID
%h 主機名
%p 所dump的進程PID
%s 導致本次coredump的信號
%t 轉儲時刻(由1970年1月1日起計的秒數)
%u 所dump進程的實際用戶ID

4、terminal中執行命令: kill -s SIGSEGV $$ , 可以看到/tmp/corefile下生成了一個core文件,說明已經設置成功。

在下列條件下不產生core 文件

進程是設置- 用戶-ID ,而且當前用戶並非程序文件的所有者;
進程是設置- 組-ID ,而且當前用戶並非該程序文件的組所有者;
用戶沒有寫當前工作目錄的許可權;
文件太大。core 文件的許可權( 假定該文件在此之前並不存在) 通常是用戶讀/ 寫,組讀和其他讀。

core dump的產生原理

發生coredump一般都是在進程收到某個信號的時候,Linux上現在大概有60多個信號,可以使用 kill -l 命令全部列出來。

針對特定的信號,應用程序可以寫對應的信號處理函數。如果不指定,則采取默認的處理方式, 默認處理是coredump的信號如下:

3)SIGQUIT   4)SIGILL    6)SIGABRT   8)SIGFPE    11)SIGSEGV    7)SIGBUS    31)SIGSYS
5)SIGTRAP   24)SIGXCPU  25)SIGXFSZ  29)SIGIOT

我們看到SIGSEGV在其中,一般數組越界或是訪問空指針都會產生這個信號。另外雖然默認是這樣的,但是你也可以寫自己的信號處理函數改變默認行為,更多信號相關可以自行Google。

core dump文件調試

#include <stdio.h>
 
int func(int *p)
{
        *p = 0;
}
 
int main()
{
        func(NULL);
        return 0;
}

上述代碼為會產生coredump的實例代碼

 此時此可執行程序下面產生了新的core文件

查看進程崩潰在何處

定位到崩潰的所在行

在編譯的時候開啟-g調試開關就可以

gcc main.c -g -o a.c

如果不想設置coredum全局模式,只需要針對當前進程產生可以定位崩潰位置的core文件,只需要4個操作,
ulimit -c unlimited
echo "/tmp/core-%e-%p" > /proc/sys/kernel/core_pattern
gcc -o main -g a.c
gdb main /tmp/core-main-10815 

上邊的程序編譯的時候有一點需要注意,需要帶上參數-g, 這樣生成的可執行程序中會帶上足夠的調試信息。編譯運行之后你就應該能看見期待已久的“Segment Fault(core dumped)”或是“段錯誤 (核心已轉儲)”之類的字眼了。看看當前目錄下是不是有個core或是core.xxx的文件。使用linux下經典的調試器GDB,首先帶着core文件載入程序:gdb exefile core,這里需要注意的這個core文件必須是exefile產生的,否則符號表會對不上。載入之后大概是這個樣子的

sagi@sagi-laptop:~$ gdb coredump core
Core was generated by ./coredump'.
    Program terminated with signal 11, Segmentation fault.
#0  0x080483a7 in crash () at coredump.c:8
    8       xxx[1] = 'D';
(gdb)

我們看到已經能直接定位到出core的地方了,在第8行寫了一個只讀的內存區域導致觸發Segment Fault信號。在載入core的時候有個小技巧,如果你事先不知道這個core文件是由哪個程序產生的,你可以先隨便找個代替一下,比如/usr/bin/w就是不錯的選擇。比如我們采用這種方法載入上邊產生的core,gdb會有類似的輸出

sagi@sagi-laptop:~$ gdb /usr/bin/w core
Core was generated by ./coredump'.
    Program terminated with signal 11, Segmentation fault.
#0  0x080483a7 in ?? ()
    (gdb)

可以看到GDB已經提示你了,這個core是由哪個程序產生的。

GDB 常用操作

上邊的程序比較簡單,不需要另外的操作就能直接找到問題所在。現實卻不是這樣的,常常需要進行單步跟蹤,設置斷點之類的操作才能順利定位問題。下邊列出了GDB一些常用的操作。

啟動程序:run
設置斷點:b 行號|函數名
刪除斷點:delete 斷點編號
禁用斷點:disable 斷點編號
啟用斷點:enable 斷點編號
單步跟蹤:next 也可以簡寫 n
單步跟蹤:step 也可以簡寫 s
打印變量:print 變量名字
設置變量:set var=value
查看變量類型:ptype var
順序執行到結束:cont
順序執行到某一行: util lineno
打印堆棧信息:bt

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM