Linux中的core文件简介
在程序不寻常退出时,内核会在当前工作目录下生成一个core文件(是一个内存映像,同时加上调试信息)。使用gdb来查看core文件,可以指示出导致程序出错的代码所在文件和行数。
1.core文件的生成开关和大小限制
(1)使用ulimit -c
命令可查看core文件的生成开关。若结果为0,则表示关闭了此功能,不会生成core文件。
(2)使用ulimit -c filesize命令,可以限制core文件的大小(filesize的单位为kbyte)。例如使用ulimit -c 1000将会把core文件限制为1000KB。如果生成的信息超过此大小,将会被裁剪,最终生成一个不完整的core文件,在调试此core文件的时候,gdb会提示错误。
(3)使用ulimit -c unlimited,则表示core文件的大小不受限制。
(4)可以将ulimit -c unlimited写入到.bashrc中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | [root@lhrblog ~]# echo "ulimit -c 0" >> /root/.bashrc [root@lhrblog ~]# echo "ulimit -c 0" >> /etc/profile [root@lhrblog ~]# ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 15076 max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 1048576 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) unlimited virtual memory (kbytes, -v) unlimited file locks (-x) unlimited |
2.core文件生成路径
默认为输入可执行文件运行命令的同一路径下。若系统生成的core文件不带其它任何扩展名称,则全部命名为core。新的core文件生成将覆盖原来的core文件。
如何查询和修改Linux操作系统生成core dump文件的默认路径?
1 2 | 方法1:cat /proc/sys/kernel/core_pattern 方法2:/sbin/sysctl kernel.core_pattern |
3.控制core文件的文件名中是否添加pid作为扩展
这个文件/proc/sys/kernel/core_uses_pid可以控制core文件的文件名中是否添加pid作为扩展。文件内容为1,表示添加 pid作为扩展名,生成的core文件格式为core.xxxx;为0则表示生成的core文件同一命名为core。
可通过以下命令修改此文件:
echo "1" > /proc/sys/kernel/core_uses_pid
4.修改core dump文件保存路径和文件名格式
方法1:临时修改:修改/proc/sys/kernel/core_pattern文件,但/proc目录本身是动态加载的,每次系统重启都会重新加载,因此这种方法只能作为临时修改。
可以将core文件统一生成到/corefile目录下,产生的文件名为core-命令名-pid-时间戳
1 | echo "/corefile/core-%e-%p-%t" > /proc/sys/kernel/core_pattern |
方法2:永久修改:使用sysctl -w name=value命令。
1 | /sbin/sysctl -w kernel.core_pattern=/corefile/core-%e-%p-%t |
5.为了更详尽的记录core dump当时的系统状态,可通过以下参数来丰富core文件的命名
1 2 3 4 5 6 7 8 | %% - 单个%字符 %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时间(由1970年1月1日计起的秒数) %h - insert hostname where the coredump happened into filename 添加主机名 %e - insert coredumping executable name into filename 添加命令名(程序文件名) |
6.运行示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | root@ubuntu:/home/kk/Desk/python/day5-27# echo "1" > /proc/sys/kernel/core_uses_pid root@ubuntu:/home/kk/Desk/python/day5-27# cd /proc/sys/kernel/ root@ubuntu:/proc/sys/kernel# echo "/tmp/core-%e-%p-%t" > core_pattern root@ubuntu:/proc/sys/kernel# cd - /home/kk/Desk/python/day5-27 root@ubuntu:/home/kk/Desk/python/day5-27# exit exit kk@ubuntu:~/Desk/python/day5-27$ ll /tmp/ kk@ubuntu:~/Desk/python/day5-27$ ll /tmp/core-a.out-3173-1401287037 -rw------- 1 kk kk 413696 5月 28 22:23 /tmp/core-a.out-3173-1401287037 kk@ubuntu:~/Desk/python/day5-27$ gdb ./a.out /tmp/ /tmp/at-spi2 /tmp/ssh-UTCTvudG1989 /tmp/core-a.out-3173-1401287037 /tmp/unity_support_test.1 /tmp/ibus.log /tmp/VMwareDnD /tmp/.ICE-unix /tmp/vmware-kk /tmp/keyring-q0k3an /tmp/vmware-root /tmp/pulse-2L9K88eMlGn7 /tmp/.X0-lock /tmp/pulse-PKdhtXMmr18n /tmp/.X11-unix /tmp/pulse-Y400HBNSM00c kk@ubuntu:~/Desk/python/day5-27$ gdb ./a.out /tmp/core-a.out-3173-1401287037 |
7. 分析调试core文件
core文件是个二进制文件,需要用相应的工具来分析程序崩溃时的内存映像。
1 2 3 | [root@localhost core_dump]$ 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文件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | [root@localhost core_dump]$ 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 0×080482fd in core_test () at core_dump_test.c:7 7 str[1] = ‘T’; (gdb) where #0 0×080482fd in core_test () at core_dump_test.c:7 #1 0×08048317 in main () at core_dump_test.c:12 #2 0×42015574 in __libc_start_main () from /lib/tls/libc.so.6 |
GDB中键入where,就会看到程序崩溃时堆栈信息(当前函数之前的所有已调用函数的列表(包括当前函数),gdb只显示最近几个),我们很容易找到我们的程序在最后崩溃的时候调用了core_dump_test.c 第7行的代码,导致程序崩溃。注意:在编译程序的时候要加入选项-g。您也可以试试其他命令, 如 fram、list等。更详细的用法,请查阅GDB文档。