linux中對於core文件的分析2


前段時間調試程序時用到的,轉過來大夥共享一下
//----------------------------
-----------------------------------
1. core
文件的簡單介紹
//---------------------------------------------------------------

在一個程序崩潰時,它一般會在指定目錄下生成一個core文件。core文件僅僅是一個內存映象(同時加上調試信息),主要是用來調試的。



//---------------------------------------------------------------
2. 
開啓或關閉core文件的生成

//---------------------------------------------------------------

用以下命令來阻止系統生成core文件:

ulimit -c 0

下面的命令可以檢查生成core文件的選項是否打開:

ulimit -a

該命令將顯示所有的用戶定製,其中選項-a代表“all”

也可以修改系統文件來調整core選項

/etc/profile

通常會有這樣一句話來禁止產生core文件,通常這種設置是合理的:
# No core files by default

ulimit -S -c 0 > /dev/null 2>&1

但是在開發過程中有時爲了調試問題,還是需要在特定的用戶環境下打開core文件產生的設置
在用戶的

~/.bash_profile

里加上

ulimit -c unlimited

來讓特定的用戶可以產生core文件
如果

ulimit -c 0 

則也是禁止產生core文件,而

ulimit -c 1024

則限制產生的core文件的大小不能超過1024kb


//---------------------------------------------------------------
3. 
設置Core Dump的核心轉儲文件目錄和命名規則

//---------------------------------------------------------------

/proc/sys/kernel/core_uses_pid

可以控制產生的core文件的文件名中是否添加pid作爲擴展,如果添加則文件內容爲1,否則爲0

proc/sys/kernel/core_pattern

可以設置格式化的core文件保存位置或文件名,比如原來文件內容是core-%e
可以這樣修改:

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 
添加命令名


//---------------------------------------------------------------
4. 
使用core文件
//---------------------------------------------------------------

core文件所在目錄下鍵入:

gdb -c core

它會啓動GNU的調試器,來調試core文件,並且會顯示生成此core文件的程序名,中止此程序的信號等等
如果你已經知道是由什麼程序生成此core文件的,比如MyServer崩潰了生成core.12345,那麼用此指令調試:

gdb -c core MyServer

以下怎麼辦就該去學習gdb的使用了


//---------------------------------------------------------------
5. 
一個小方法來測試產生core文件

//---------------------------------------------------------------

直接輸入指令:

kill -s SIGSEGV $$

當我們的程序崩潰時,內核有可能把該程序當前內存映射到core文件裏,方便程序員找到程序出現問題的地方。最常出現的,幾乎所有C程序員都出現過的錯誤就是段錯誤了。也是最難查出問題原因的一個錯誤。下面我們就針對段錯誤來分析core文件的產生、以及我們如何利用core文件找到出現崩潰的地方。

何謂core文件


當一個程序崩潰時,在進程當前工作目錄的core文件中複製了該進程的存儲圖像。core文件僅僅是一個內存映象(同時加上調試信息),主要是用來調試的。


當程序接收到以下UNIX信號會產生core文件:


名字

說明

ANSI C  POSIX.1
SVR4  4.3+BSD
缺省動作


SIGABRT
異常終止
(abort)
   .       .
   .      .
終止
w/core

SIGBUS
硬件故障

           .
   .      .
終止
w/core

SIGEMT
硬件故障

 
   .      .
終止
w/core

SIGFPE
算術異常

   .       .
   .      .
終止
w/core

SIGILL
非法硬件指令

   .       .
   .      .
終止
w/core

SIGIOT
硬件故障

 
   .      .
終止
w/core

SIGQUIT
終端退出符

           .
   .      .
終止
w/core

SIGSEGV
無效存儲訪問

   .       .
   .      .
終止
w/core

SIGSYS
無效系統調用

 
   .      .
終止
w/core

SIGTRAP
硬件故障

 
   .      .
終止
w/core

SIGXCPU
超過CPU限制
(setrlimit)
 
   .      .
終止
w/core

SIGXFSZ
超過文件長度限制
(setrlimit)
 
   .      .
終止
w/core


在系統默認動作列,終止w/core”表示在進程當前工作目錄的core文件中複製了該進程的存儲圖像(該文件名爲core,由此可以看出這種功能很久之前就是UNIX功能的一部分)。大多數UNIX調試程序都使用core文件以檢查進程在終止時的狀態。


core
文件的產生不是POSIX.1所屬部分,而是很多UNIX版本的實現特徵。UNIX6版沒有檢查條件 (a)(b),並且其源代碼中包含如下說明:如果你正在找尋保護信號,那麼當設置-用戶-ID命令執行時,將可能產生大量的這種信號4.3 + BSD產生名爲core.prog的文件,其中prog是被執行的程序名的前1 6個字符。它對core文件給予了某種標識,所以是一種改進特徵。


表中硬件故障對應於實現定義的硬件故障。這些名字中有很多取自UNIX早先在DP-11上的實現。請查看你所使用的系統的手冊,以確切地確定這些信號對應於哪些錯誤類型。


下面比較詳細地說明這些信號。


• SIGABRT
調用abort函數時產生此信號。進程異常終止。


• SIGBUS 
指示一個實現定義的硬件故障。


• SIGEMT 
指示一個實現定義的硬件故障。


EMT
這一名字來自PDP-11emulator trap 指令。


• SIGFPE 
此信號表示一個算術運算異常,例如除以0,浮點溢出等。


• SIGILL 
此信號指示進程已執行一條非法硬件指令。


4.3BSD
abort函數產生此信號。SIGABRT現在被用於此。


• SIGIOT 
這指示一個實現定義的硬件故障。


IOT
這個名字來自於PDP-11對於輸入/輸出TRAP(input/output TRAP)指令的縮寫。系統V的早期版本,由abort函數產生此信號。SIGABRT現在被用於此。


• SIGQUIT
當用戶在終端上按退出鍵(一般採用Ctrl-\)時,產生此信號,並送至前臺進


程組中的所有進程。此信號不僅終止前臺進程組(如SIGINT所做的那樣),同時產生一個core文件。


• SIGSEGV
指示進程進行了一次無效的存儲訪問。


名字SEGV表示段違例(segmentation violation


• SIGSYS 
指示一個無效的系統調用。由於某種未知原因,進程執行了一條系統調用指令,


但其指示系統調用類型的參數卻是無效的。


• SIGTRAP
指示一個實現定義的硬件故障。


此信號名來自於PDP-11TRAP指令。


• SIGXCPU SVR4
4.3+BSD支持資源限制的概念。如果進程超過了其軟C P U時間限制,則產生此信號。


• SIGXFSZ
如果進程超過了其軟文件長度限制,則SVR44.3+BSD產生此信號。


摘自《UNIX環境高級編程》第10 信號。




使用core文件調試程序


看下面的例子:


/*core_dump_test.c*/
#include <stdio.h>
const char *str = "test";
void core_test(){
    str[1] = 'T';
}

int main(){
    core_test();
    return 0;
}

編譯:

gcc –g core_dump_test.c -o core_dump_test

如果需要調試程序的話,使用gcc編譯時加上-g選項,這樣調試core文件的時候比較容易找到錯誤的地方。


執行:

./core_dump_test
段錯誤


運行core_dump_test程序出現了段錯誤,但沒有產生core文件。這是因爲系統默認core文件的大小爲0,所以沒有創建。可以用ulimit命令查看和修改core文件的大小。

ulimit -c 0
ulimit -c 1000
ulimit -c 1000

-c
指定修改core文件的大小,1000指定了core文件大小。也可以對core文件的大小不做限制,如:


ulimit -c unlimited
ulimit -c unlimited

如果想讓修改永久生效,則需要修改配置文件,如 .bash_profile/etc/profile/etc/security/limits.conf


再次執行:

./core_dump_test
段錯誤
(core dumped)
ls core.*
core.6133

可以看到已經創建了一個core.6133的文件.6133core_dump_test程序運行的進程ID


調式core文件

core
文件是個二進制文件,需要用相應的工具來分析程序崩潰時的內存映像。


file core.6133

core.6133: ELF 32-bit LSB core file Intel 80386, version 1 (SYSV), SVR4-style, from 'core_dump_test'

Linux下可以用GDB來調試core文件。


gdb core_dump_test core.6133

GNU gdb Red Hat Linux (5.3post-0.20021129.18rh)
Copyright 2003 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...
Core was generated by `./core_dump_test'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /lib/tls/libc.so.6...done.
Loaded symbols for /lib/tls/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
#0  0x080482fd in core_test () at core_dump_test.c:7
7           str[1] = 'T';
(gdb) where
#0  0x080482fd in core_test () at core_dump_test.c:7
#1  0x08048317 in main () at core_dump_test.c:12
#2  0x42015574 in __libc_start_main () from /lib/tls/libc.so.6

GDB
中鍵入where,就會看到程序崩潰時堆棧信息(當前函數之前的所有已調用函數的列表(包括當前函數),gdb只顯示最近幾個),我們很容易找到我們的程序在最後崩潰的時候調用了core_dump_test.c 7行的代碼,導致程序崩潰。注意:在編譯程序的時候要加入選項-g。您也可以試試其他命令, 如 framlist等。更詳細的用法,請查閱GDB文檔。


core
文件創建在什麼位置


在進程當前工作目錄的下創建。通常與程序在相同的路徑下。但如果程序中調用了chdir函數,則有可能改變了當前工作目錄。這時core文件創建在chdir指定的路徑下。有好多程序崩潰了,我們卻找不到core文件放在什麼位置。和chdir函數就有關係。當然程序崩潰了不一定都產生core文件。


什麼時候不產生core文件


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

( a )
進程是設置-用戶-ID,而且當前用戶並非程序文件的所有者;

( b )
進程是設置--ID,而且當前用戶並非該程序文件的組所有者;

( c )
用戶沒有寫當前工作目錄的許可權;

( d )
文件太大。core文件的許可權(假定該文件在此之前並不存在)通常是用戶讀/寫,組讀和其他讀。


利用GDB調試core文件,當遇到程序崩潰時我們不再束手無策。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章