linux core dump

core dump及應用

【1】core dump 概念

http://en.wikipedia.org.nyud.net:8080/wiki/Core_dump

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.

【2】示例:在Linux下產生並調試core文件

參考http://www.zedware.org/code/code-coredump.html

先看看我用的是個什麼機器:

$ uname -a
Linux dev 2.4.21-9.30AXsmp #1 SMP Wed May 26 23:37:09 EDT 2004 i686 i686 i386 GNU/Linux

再看看默認的一些參數,注意core file size是個0,程序出錯時不會產生core文件了。

$ ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
file size (blocks, -f) unlimited
max locked memory (kbytes, -l) 4
max memory size (kbytes, -m) unlimited
open files (-n) 2048
pipe size (512 bytes, -p) 8
stack size (kbytes, -s) 10240
cpu time (seconds, -t) unlimited
max user processes (-u) 7168
virtual memory (kbytes, -v) unlimited

寫個簡單的程序,看看core文件是不是會被產生。創建foo.c,使內容如下。

$ more foo.c

#include <stdio.h>

static void sub(void);

int main(void)
{
     sub();
     return 0;
}

static void sub(void)
{
     int *p = NULL;

     /* derefernce a null pointer, expect core dump. */
     printf("%d", *p);

}

$ gcc -Wall -g foo.c   【-Wall :[Warning all] 顯示所有常用的編譯警告信息。 -g選項,將調試信息加入到目標文件或可執行文件中。】
$ ./a.out
Segmentation fault   所謂的Segmentation Fault(段錯誤)就是指訪問的內存超出了系統所給這個程序的內存空間】

$ ls -l core*
ls: core*: No such file or directory

沒有找到core文件,我們改改ulimit的設置,讓它產生,1024是隨便取的,也可以使用ulimit -c unlimited不限制大小。

$ ulimit -c 1024

$ ulimit -a
core file size (blocks, -c) 1024
data seg size (kbytes, -d) unlimited
file size (blocks, -f) unlimited
max locked memory (kbytes, -l) 4
max memory size (kbytes, -m) unlimited
open files (-n) 2048
pipe size (512 bytes, -p) 8
stack size (kbytes, -s) 10240
cpu time (seconds, -t) unlimited
max user processes (-u) 7168
virtual memory (kbytes, -v) unlimited

$ ./a.out
Segmentation fault (core dumped)
$ ls -l core*
-rw------- 1 uniware uniware 53248 Jun 30 17:10 core.9128 此處也可能是名稱爲core的文件】

注意看上述的輸出信息,多了個(core dumped)。確實產生了一個core文件,9128是該進程的PID。我們用GDB來看看這個core。

gdb --core=core.9128
GNU gdb Asianux (6.0post-0.20040223.17.1AX)
Copyright 2004 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 was configured as "i386-asianux-linux-gnu".
Core was generated by `./a.out'.
Program terminated with signal 11, Segmentation fault.
#0 0x08048373 in ?? ()
(gdb) bt
#0 0x08048373 in ?? ()
#1 0xbfffd8f8 in ?? ()
#2 0x0804839e in ?? ()
#3 0xb74cc6b3 in ?? ()
#4 0x00000000 in ?? ()

此時用bt看不到backtrace,也就是調用堆棧,原來GDB還不知道符號信息在哪裏。我們告訴它一下:

(gdb) file ./a.out
Reading symbols from ./a.out...done.
Using host libthread_db library "/lib/tls/libthread_db.so.1".
(gdb) bt
#0 0x08048373 in sub () at foo.c:17
#1 0x08048359 in main () at foo.c:8


此時backtrace出來了。

(gdb) l   (此處是“L”的小寫,不是數字“1”)
8         sub();
9         return 0;
10     }
11
12      static void sub(void)
13      {
14          int *p = NULL;
15
16          /* derefernce a null pointer, expect core dump. */
17          printf("%d", *p);
(gdb)

【3】總結

參考http://blog.csdn.net/shaovey/archive/2008/07/31/2744487.aspx

在程序不尋常退出時,內核會在當前工作目錄下生成一個core文件(是一個內存映像,同時加上調試信息)。使用gdb來查看core文件,可以指示出導致程序出錯的代碼所在文件和行數。


1.core文件的生成開關和大小限制
1)使用ulimit -c命令可查看core文件的生成開關。若結果爲0,則表示關閉了此功能,不會生成core文件。
2)使用ulimit -c filesize命令,可以限制core文件的大小(filesize的單位爲kbyte)。如果生成的信息超過此大小,將會被裁剪,最終生成一個不完整的core文件。在調試此core文件的時候,gdb會提示錯誤。若ulimit -c unlimited,則表示core文件的大小不受限制。ulimit -c 0關閉該功能。
PS: ulimit使用方法見
http://www.ibm.com/developerworks/cn/linux/l-cn-ulimit/


2.core文件的名稱和生成路徑
core文件生成路徑:輸入可執行文件運行命令的同一路徑下。
若系統生成的core文件不帶其它任何擴展名稱,則全部命名爲core。新的core文件生成將覆蓋原來的core文件。

1)/proc/sys/kernel/core_uses_pid可以控制core文件的文件名中是否添加pid作爲擴展。文件內容爲1,表示添加pid作爲擴展名,生成的core文件格式爲core.xxxx;爲0則表示生成的core文件同一命名爲core。
可通過以下命令修改此文件:
echo "1" > /proc/sys/kernel/core_uses_pid

2)proc/sys/kernel/core_pattern可以控制core文件保存位置和文件名格式。
可通過以下命令修改此文件:
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 添加命令名


3.core文件的查看
core文件需要使用gdb來查看。
gdb ./a.out
core-file core.xxxx
使用bt命令即可看到程序出錯的地方。 
以下兩種命令方式具有相同的效果,但是在有些環境下不生效,所以推薦使用上面的命令。 
1)gdb -core=core.xxxx
file ./a.out
bt 
2)gdb -c core.xxxx
file ./a.out
bt


4.開發板上使用core文件調試
如果開發板的操作系統也是linux,core調試方法依然適用。如果開發板上不支持gdb,可將開發板的環境(依賴庫)、可執行文件和core文件拷貝到PC的linux下。
在PC上調試開發板上產生的core文件,需要使用交叉編譯器自帶的gdb,並且需要在gdb中指定solib-absolute-prefix和solib-search-path兩個變量以保證gdb能夠找到可執行程序的依賴庫路徑。有一種建立配置文件的方法,不需要每次啓動gdb都配置以上變量,即:在待運行gdb的路徑下建立.gdbinit。
配置文件內容:
set solib-absolute-prefix YOUR_CROSS_COMPILE_PATH
set solib-search-path YOUR_CROSS_COMPILE_PATH
set solib-search-path YOUR_DEVELOPER_TOOLS_LIB_PATH
handle SIG32 nostop noprint pass


注意:待調試的可執行文件,在編譯的時候需要加-g,core文件才能正常顯示出錯信息!有時候core信息很大,超出了開發板的空間限制,生成的core信息會殘缺不全而無法使用,可以通過掛載到PC的方式來規避這一點。

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