http://www.cnblogs.com/hazir/p/linxu_core_dump.htmlhtml
當程序運行的過程當中異常終止或崩潰,操做系統會將程序當時的內存狀態記錄下來,保存在一個文件中,這種行爲就叫作 Core Dump(中文有的翻譯成「核心轉儲」)。咱們能夠認爲 Core Dump 是「內存快照」,但實際上,除了內存信息以外,還有些關鍵的程序運行狀態也會同時 Dump 下來,例如寄存器信息(包括程序指針、棧指針等)、內存管理信息、其餘處理器和操做系統狀態和信息。
Core Dump 對於編程人員診斷和調試程序是很是有幫助的,由於對於有些程序錯誤是很難重現的,例如指針異常,而 Core Dump 文件能夠再現程序出錯時的情景。linux
在半導體做爲電腦內存材料以前,電腦內存使用的是磁芯內存(Magnetic Core Memory),Core Dump 中的 Core 沿用了磁芯內存的 Core 表達。圖爲磁芯內存的一個單元,來自 Wikipedia.編程
在 APUE 一書中做者有句話這樣寫的:bash
Because the file is named core, it shows how long this feature has
been part of the Unix System.併發
這裏的 core 就是沿用的是早期電腦磁芯內存中的表達,也能看出 Unix 系統 Core Dump 機制的悠久歷史。dom
Dump 指的是拷貝一種存儲介質中的部份內容到另外一個存儲介質,或者將內容打印、顯示或者其它輸出設備。dump 出來的內容是格式化的,能夠使用一些工具來解析它。異步
現代操做系統中,用 Core Dump 表示當程序異常終止或崩潰時,將進程此時的內存中的內容拷貝到磁盤文件中存儲,以方便編程人員調試。函數
上面說當程序運行過程當中異常終止或崩潰時會發生 core dump,但還沒說到什麼具體的情景程序會發生異常終止或崩潰,例如咱們使用 kill -9 命令殺死一個進程會發生 core dump 嗎?實驗證實是不能的,那麼什麼狀況會產生呢?工具
Linux 中信號是一種異步事件處理的機制,每種信號對應有其默認的操做,你能夠在 這裏 查看 Linux 系統提供的信號以及默認處理。默認操做主要包括忽略該信號(Ingore)、暫停進程(Stop)、終止進程(Terminate)、終止併發生core dump(core)等。若是咱們信號均是採用默認操做,那麼,如下列出幾種信號,它們在發生時會產生 core dump:ui
bashSignal Action Comment SIGQUIT Core Quit from keyboard SIGILL Core Illegal Instruction SIGABRT Core Abort signal from abort SIGSEGV Core Invalid memory reference SIGTRAP Core Trace/breakpoint trap
固然不只限於上面的幾種信號。這就是爲何咱們使用 Ctrl+z 來掛起一個進程或者 Ctrl+C 結束一個進程均不會產生 core dump,由於前者會向進程發出 SIGTSTP 信號,該信號的默認操做爲暫停進程(Stop Process);後者會向進程發出SIGINT 信號,該信號默認操做爲終止進程(Terminate Process)。一樣上面提到的 kill -9 命令會發出 SIGKILL 命令,該命令默認爲終止進程。而若是咱們使用 Ctrl+\ 來終止一個進程,會向進程發出 SIGQUIT 信號,默認是會產生 core dump 的。還有其它情景會產生 core dump, 如:程序調用 abort() 函數、訪存錯誤、非法指令等等。
在終端中輸入命令 ulimit -c ,輸出的結果爲 0,說明默認是關閉 core dump 的,即當程序異常終止時,也不會生成 core dump 文件。
咱們能夠使用命令 ulimit -c unlimited 來開啓 core dump 功能,而且不限制 core dump 文件的大小; 若是須要限制文件的大小,將 unlimited 改爲你想生成 core 文件最大的大小,注意單位爲 blocks(KB)。
用上面命令只會對當前的終端環境有效,若是想須要永久生效,能夠修改文件 /etc/security/limits.conf文件,關於此文件的設置參看 這裏 。增長一行:
#/etc/security/limits.conf # #Each line describes a limit for a user in the form: # #<domain> <type> <item> <value> * soft core unlimited
默認生成的 core 文件保存在可執行文件所在的目錄下,文件名就爲 core。
經過修改 /proc/sys/kernel/core_uses_pid
文件可讓生成 core 文件名是否自動加上 pid 號。
例如 echo 1 > /proc/sys/kernel/core_uses_pid
,生成的 core 文件名將會變成 core.pid,其中 pid 表示該進程的 PID。
還能夠經過修改 /proc/sys/kernel/core_pattern
來控制生成 core 文件保存的位置以及文件名格式。
例如能夠用 echo "/tmp/corefile-%e-%p-%t" > /proc/sys/kernel/core_pattern
設置生成的 core 文件保存在 「/tmp/corefile」 目錄下,文件名格式爲 「core-命令名-pid-時間戳」。這裏 有更多詳細的說明!
產生了 core 文件,咱們該如何使用該 core 文件進行調試呢?Linux 中能夠使用 GDB 來調試 core 文件,步驟以下:
下面用一個簡單的例子來講明:
c#include <stdio.h> int func(int *p) { int y = *p; return y; } int main() { int *p = NULL; return func(p); }
編譯加上調試信息, 運行以後core dump, 使用 gdb 查看 core 文件.
bashguohailin@guohailin:~$ gcc core_demo.c -o core_demo -g guohailin@guohailin:~$ ./core_demo Segmentation fault (core dumped) guohailin@guohailin:~$ gdb core_demo core_demo.core.24816 ... Core was generated by './core_demo'. Program terminated with signal 11, Segmentation fault. #0 0x080483cd in func (p=0x0) at core_demo.c:5 5 int y = *p; (gdb) where #0 0x080483cd in func (p=0x0) at core_demo.c:5 #1 0x080483ef in main () at core_demo.c:12 (gdb) info frame Stack level 0, frame at 0xffd590a4: eip = 0x80483cd in func (core_demo.c:5); saved eip 0x80483ef called by frame at 0xffd590c0 source language c. Arglist at 0xffd5909c, args: p=0x0 Locals at 0xffd5909c, Previous frame's sp is 0xffd590a4 Saved registers: ebp at 0xffd5909c, eip at 0xffd590a0 (gdb)
從上面能夠看出,咱們能夠還原 core_demo 執行時的場景,並使用 where 能夠查看當前程序調用函數棧幀, 還能夠使用 gdb 中的命令查看寄存器,變量等信息.
http://whatis.techtarget.com/definition/core-dump
http://man7.org/linux/man-pages/man5/core.5.html