国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Linux > 正文

Linux Core Dump

2024-06-28 13:27:40
字體:
來源:轉載
供稿:網友
linux Core Dump

轉載聲明:本文轉自http://www.CUOXin.com/hazir/p/linxu_core_dump.html#commentform

當程序運行的過程中異常終止或崩潰,操作系統會將程序當時的內存狀態記錄下來,保存在一個文件中,這種行為就叫做Core Dump(中文有的翻譯成“核心轉儲”)。我們可以認為 core dump 是“內存快照”,但實際上,除了內存信息之外,還有些關鍵的程序運行狀態也會同時 dump 下來,例如寄存器信息(包括程序指針、棧指針等)、內存管理信息、其他處理器和操作系統狀態和信息。core dump 對于編程人員診斷和調試程序是非常有幫助的,因為對于有些程序錯誤是很難重現的,例如指針異常,而 core dump 文件可以再現程序出錯時的情景。

Core Dump 名詞解釋

在半導體作為電腦內存材料之前,電腦內存使用的是磁芯內存(Magnetic Core Memory),Core Dump 中的 Core 沿用了磁芯內存的Core表達。圖為磁芯內存的一個單元,來自Wikipedia.

在APUE一書中作者有句話這樣寫的:

Because the file is namedcore, it shows how long this feature has been part of the Unix System.

這里的 core 就是沿用的是早期電腦磁芯內存中的表達,也能看出 Unix 系統 Core Dump 機制的悠久歷史。

Dump指的是拷貝一種存儲介質中的部分內容到另一個存儲介質,或者將內容打印、顯示或者其它輸出設備。dump 出來的內容是格式化的,可以使用一些工具來解析它。

現代操作系統中,用Core Dump表示當程序異常終止或崩潰時,將進程此時的內存中的內容拷貝到磁盤文件中存儲,以方便編程人員調試。

Core Dump 如何產生

上面說當程序運行過程中異常終止或崩潰時會發生 core dump,但還沒說到什么具體的情景程序會發生異常終止或崩潰,例如我們使用kill -9命令殺死一個進程會發生 core dump 嗎?實驗證明是不能的,那么什么情況會產生呢?

Linux 中信號是一種異步事件處理的機制,每種信號對應有其默認的操作,你可以在這里查看 Linux 系統提供的信號以及默認處理。默認操作主要包括忽略該信號(Ingore)、暫停進程(Stop)、終止進程(Terminate)、終止并發生core dump(core)等。如果我們信號均是采用默認操作,那么,以下列出幾種信號,它們在發生時會產生 core dump:

SignalActionComment
SIGQUITCoreQuit from keyboard
SIGILLCoreIllegal Instruction
SIGABRTCoreAbort signal fromabort
SIGSEGVCoreInvalid memory reference
SIGTRAPCoreTrace/breakpoint trap

當然不僅限于上面的幾種信號。這就是為什么我們使用Ctrl+z來掛起一個進程或者Ctrl+C結束一個進程均不會產生 core dump,因為前者會向進程發出SIGTSTP信號,該信號的默認操作為暫停進程(Stop PRocess);后者會向進程發出SIGINT信號,該信號默認操作為終止進程(Terminate Process)。同樣上面提到的kill -9命令會發出SIGKILL命令,該命令默認為終止進程。而如果我們使用Ctrl+/來終止一個進程,會向進程發出SIGQUIT信號,默認是會產生 core dump 的。還有其它情景會產生 core dump, 如:程序調用abort()函數、訪存錯誤、非法指令等等。

下面舉兩個例子來說明:

  • 終端下比較Ctrl+CCtrl+/

    guohailin@guohailin:~$ sleep 10        #使用sleep命令休眠 10 s^C                           #使用 Ctrl+C 終止該程序,不會產生 core dumpguohailin@guohailin:~$ sleep 10^/Quit (core dumped)                #使用 Ctrl+/ 退出程序, 會產生 core dumpguohailin@guohailin:~$ ls         #多出下面一個 core 文件-rw------- 1 guohailin guohailin 335872 10月 22 11:31 sleep.core.21990
  • 小程序產生 core dump

    #include <stdio.h>int main(){    int *null_ptr = NULL;    *null_ptr = 10;            //對空指針指向的內存區域寫,會發生段錯誤    return 0;}
    #編譯執行guohailin@guohailin:~$ ./a.outSegmentation fault (core dumped)guohailin@guohailin:~$ ls      #多出下面一個 core 文件-rw-------  1 guohailin guohailin 200704 10月 22 11:35 a.out.core.22070    
Linux 下打開 Core Dump

我使用的 Linux 發行版是 Ubuntu 13.04,設置生成 core dump 文件的方法如下:

  • 打開 core dump 功能

    • 在終端中輸入命令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 文件保存在可執行文件所在的目錄下,文件名就為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-時間戳”。這里有更多詳細的說明!
使用 gdb 調試 Core 文件

產生了 core 文件,我們該如何使用該 Core 文件進行調試呢?Linux 中可以使用 GDB 來調試 core 文件,步驟如下:

  • 首先,使用 gcc 編譯源文件,加上-g以增加調試信息;
  • 按照上面打開 core dump 以使程序異常終止時能生成 core 文件;
  • 運行程序,當core dump 之后,使用命令gdb program core來查看 core 文件,其中 program 為可執行程序名,core 為生成的 core 文件名。

下面用一個簡單的例子來說明:

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

編譯加上調試信息, 運行之后core dump, 使用 gdb 查看 core 文件.

guohailin@guohailin:~$ gcc core_demo.c -o core_demo -gguohailin@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:55       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 frameStack 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
  • http://en.wikipedia.org/wiki/Core_dump

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 榆树市| 上林县| 龙川县| 建瓯市| 龙胜| 陆良县| 新化县| 禹州市| 灵宝市| 桐庐县| 甘孜县| 庆安县| 武川县| 苍梧县| 江华| 南乐县| 丁青县| 克拉玛依市| 哈尔滨市| 长兴县| 蓬安县| 安岳县| 麻栗坡县| 驻马店市| 旬阳县| 株洲市| 宝丰县| 文登市| 新田县| 囊谦县| 贵南县| 镇平县| 峨眉山市| 横山县| 承德县| 东乡县| 沈阳市| 无为县| 上虞市| 阳泉市| 南江县|