在程序不尋常退出時,內(nèi)核會在當(dāng)前工作目錄下生成一個core文件(是一個內(nèi)存映像,同時加上調(diào)試信息)。使用gdb來查看core文件,可以指示出導(dǎo)致程序出錯的代碼所在文件和行數(shù)。 1.core文件的生成開關(guān)和大小限制 1)使用ulimit -c命令可查看core文件的生成開關(guān)。若結(jié)果為0,則表示關(guān)閉了此功能,不會生成core文件。 2)使用ulimit -c filesize命令,可以限制core文件的大?。╢ilesize的單位為kbyte)。若ulimit -c unlimited,則表示core文件的大小不受限制。如果生成的信息超過此大小,將會被裁剪,最終生成一個不完整的core文件。在調(diào)試此core文件的時候,gdb會提示錯誤。
2.core文件的名稱和生成路徑 core文件生成路徑: 輸入可執(zhí)行文件運(yùn)行命令的同一路徑下。 若系統(tǒng)生成的core文件不帶其它任何擴(kuò)展名稱,則全部命名為core。新的core文件生成將覆蓋原來的core文件。
1)/proc/sys/kernel/core_uses_pid可以控制core文件的文件名中是否添加pid作為擴(kuò)展。文件內(nèi)容為1,表示添加pid作為擴(kuò)展名,生成的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文件統(tǒng)一生成到/corefile目錄下,產(chǎn)生的文件名為core-命令名-pid-時間戳 以下是參數(shù)列表: %p - insert pid into filename 添加pid %u - insert current uid into filename 添加當(dāng)前uid %g - insert current gid into filename 添加當(dāng)前gid %s - insert signal that caused the coredump into the filename 添加導(dǎo)致產(chǎn)生core的信號 %t - insert UNIX time that the coredump occurred into filename 添加core文件生成時的unix時間 %h - insert hostname where the coredump happened into filename 添加主機(jī)名 %e - insert coredumping executable name into filename 添加命令名 3.core文件的查看 core文件需要使用gdb來查看。 gdb ./a.out core-file core.xxxx 使用bt命令即可看到程序出錯的地方。 以下兩種命令方式具有相同的效果,但是在有些環(huán)境下不生效,所以推薦使用上面的命令。 1)gdb -core=core.xxxx file ./a.out bt 2)gdb -c core.xxxx file ./a.out bt
例子: 首先看看默認(rèn)的一些core的參數(shù),注意core file size是個0,程序出錯時不會產(chǎn)生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文件是不是會被產(chǎn)生。
$ 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
$ ./a.out
Segmentation fault
$ ls -l core.*
ls: core.*: No such file or directory
沒有找到core文件,我們改改ulimit的設(shè)置,讓它產(chǎn)生。1024是隨便取的,要是core文件大于1024個塊,就產(chǎn)生不出來了。
$ ulimit -c 1024 (轉(zhuǎn)者注: 使用-c unlimited不限制core文件大?。?br>
$ 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 dumped)。確實(shí)產(chǎn)生了一個core文件,9128是該進(jìn)程的PID。我們用GDB來看看這個core。
(轉(zhuǎn)者注:默認(rèn)生成的文件就叫core,不帶PID,如果要帶PID需要設(shè)置,通過echo "1" > /proc/sys/kernel/core_uses_pid能夠設(shè)置pid)
$ 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 GDB 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,也就是調(diào)用堆棧,原來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
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);
|