Core Dump文件的产生和使用
简介
core dump文件是记录某个进程在某个时间点上的镜像。该时间点可能是程序的执行出错时候,也可能是某个随机的时间点。
1 测试环境
$uname -a
linux dev 2.4.21-9.30AXsmp #1 SMP Wed May 26 23:37:09 EDT 2004 i686 i686 i386 GNU/Linux
2 查看默认limit
$ 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 file size为0 ,也就是说,默认是不会产生core文件。
3 设置core dump文件大小
可以通过以下命令来设置core文件大小
$ 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
4 设置core dump文件名
默认情况下,产生的core dump文件名为“core”。如果想设置core dump的文件名,
可以通过修改“/proc/sys/kernel/core_pattern”和“/proc/sys/kernel/core_uses_pid”文件内容来达到该目的。
设置方法如下:
echo "pattern" > /proc/sys/kernel/core_pattern
echo "[0|1]" > /proc/sys/kernel/core_uses_pid
其中“core_pattern”是设置core dump文件名的规则,规则如下:
规则符号 | 解释 |
---|---|
%% | % |
%p | |
%u | |
%g | |
%s | 导致dump的信号的数字 |
%t | dump的时间戳 |
%h | hostname |
%e | 执行文件的名称 |
而“core_uses_pid”是为了向后兼容,用于设置是否在core file的末尾加上“%p”,“1”为是。
我设置的“core_pattern"内容如下:
$cat /proc/sys/kernel/core_pattern
core.%p
这里设置在core后面加上进程pid,通过设置“core_uses_pid”也可以达到这个效果。
5 程序异常产生core dump文件
代码如下:
#include <stdio.h>
#include <unistd.h>
void create_dump(void)
{
if ( 0 == fork() ){
char *p=0;
*p = 'O';
}
}
int main(int argc, const char *argv[])
{
int i;
for (i = 1; i < 100; ++i) {
sleep(1);
printf("i(%03d)\n",i);
if ( 0 == i%11 )
create_dump();
}
return 0;
}
这里通过“create_dump()"函数生成的子进程来产生core dump文件,这样做的好处是不会导致原先进程挂死,而且可用create_dump()来生成程序在某一时刻的镜像。
子进程是利用设置非法指针来产生异常的。
编译该代码,并执行
[10:17:01 core_dump]$gcc -g main.c -o create_core
[10:17:24 core_dump]$ls
create_core main.c Makefile
[10:17:28 core_dump]$./create_core
i(001)
i(002)
i(003)
i(004)
i(005)
i(006)
i(007)
i(008)
i(009)
i(010)
i(011)
^C
[10:17:50 core_dump]$ls
core.4787 create_core main.c Makefile
[10:17:51 core_dump]$
这里已经生成一个名“core.4787“的core dump文件
6 利用abort()产生core dump文件
将上一节的“create_file()"函数中的使用非法指针操作换成“abort()”就行了,代码如下:
#include <stdlib.h>
void create_dump(void)
{
if ( 0 == fork() ){
#if 0
char *p=0;
*p =1;
#else
abort();
#endif
}
}
操作方法与上一节一样。
7 利用gdb工具产生core dump文件
gdb调试工具使用“attach”可以连接指定的已运行进程,并且gdb可以对它调试的程序生成那个时刻的core dump文件。
这里写个小程序进行测试,小程序代码如下:
/*main.c*/
#include <stdio.h>
#include <unistd.h>
int main(int argc, char **argv)
{
int i=0;
while(1) {
sleep(1);
++i;
}
}
下面是具体的操作步骤:
[10:52:23 demo]$gcc -g main.c -o test
[10:52:34 demo]$./test &
[2] 5419
[10:52:37 demo]$sudo gdb
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-linux-gnu".
For bug reporting instructions, please see:
.
(gdb) attach 5419
Attaching to process 5419
Reading symbols from /home/jake/apps/c/src/demo/test...done.
Reading symbols from /lib/i386-linux-gnu/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/i386-linux-gnu/libc.so.6
Reading symbols from /lib/ld-linux.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib/ld-linux.so.2
0xb77b3424 in __kernel_vsyscall ()
(gdb) gcore core.5419
Saved corefile core.5419
(gdb) q
A debugging session is active.
Inferior 1 [process 5419] will be detached.
Quit anyway? (y or n) y
Detaching from program: /home/jake/apps/c/src/demo/test, process 5419
[10:53:57 demo]$ls
core.5419 main.c test
这里可以看到已经生成“core.5419"文件,这里gdb操作需要root权限!
8 利用gcore工具产生core dump文件
gcore工具可直接对指定的进程生成那个时间点的core dump文件,其实gcore工具是对第7节的gdb使用操作进行的封装。使用格式如下:
gcore [-o filename] pid
其中“-o filename"指定生成core dump文件的名字,不指定的话,使用系统配置的。
这里使用第7节的小程序进行测试,具体操作如下:
[10:35:31 demo]$./test &
[1] 5042
[10:35:36 demo]$sudo gcore 5042
0xb77b6424 in __kernel_vsyscall ()
Saved corefile core.5042
[10:35:47 demo]$ls
core.5042 main.c test
[10:35:49 demo]$
gcore工具需要使用root权限执行,可以看到这里生成一个“core.5042"文件。
9 使用gdb分析core dump文件
这里选择对第5节产生的core dump文件进行分析。其具体操作如下:
[11:02:14 core_dump]$gdb ./core_dump
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-linux-gnu".
For bug reporting instructions, please see:
...
Reading symbols from /home/jake/apps/c/src/core_dump/core_dump...done.
(gdb) core-file core.5575
[New LWP 5575]
warning: Can't read pathname for load map: Input/output error.
Core was generated by `./core_dump'.
Program terminated with signal 11, Segmentation fault.
#0 0x0804845d in create_dump () at main.c:10
10 *p =1;
(gdb) bt
#0 0x0804845d in create_dump () at main.c:10
#1 0x080484c4 in main (argc=1, argv=0xbfb89ac4) at main.c:24
(gdb) frame 1
#1 0x080484c4 in main (argc=1, argv=0xbfb89ac4) at main.c:24
24 create_dump();
(gdb) print i
$1 = 11
(gdb) l 10
5 void create_dump(void)
6 {
7 if ( 0 == fork() ){
8 #if 1
9 char *p=0;
10 *p =1;
在第18行可以看到,程序执行到“*p=1"时出现错误,这时通过第27行的操作,打印出附近的代码,发现原来是对0地址的赋值而引起的异常。
同时通过第25行“print i"打印,发现确实"i=11"时执行的操作。
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 add358@163.com
文章标题:Core Dump文件的产生和使用
文章字数:1.6k
本文作者:Jake Yang
发布时间:2018-04-09, 00:00:00
最后更新:2018-11-23, 13:18:26
原始链接:https://add358.github.io/2018/04/09/Linux-2018-04-09-Core-Dump文件的产生和使用/版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。