环境
本文以笔者操作系统ubuntu14.04 LTS为例介绍core dump功能。
首先查看系统是否使能了core dump功能:
$ ulimit -c
0
返回0表示没有使能,我们需要使能该功能:
ulimit -c 1
示例
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
int main(int argc, char *argv[])
{
errno = EINVAL;
printf("Error:%s\n", strerror(errno));
perror(argv[0]);
exit(0);
}
编译
使用-g选项重新编译目标执行文件:
gcc test.c -g -o error
运行:
$ ./error
段错误 (核心已转储)
$ ls -a
. .. core error test.c
产生了一个命名为“core”的文件,这个就是我们需要的core dump文件。
调试
gdb error core
使用gdb加载对应的core dump,需要的格式为:“gdb program_name core_name”
GNU gdb (Ubuntu 7.7-0ubuntu3) 7.7
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
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 "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from error...done.
[New LWP 15614]
Core was generated by `./error'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x00007f6b20e61943 in _IO_vfprintf_internal (s=<optimized out>, format=<optimized out>, ap=ap@entry=0x7fff3f3e1a78) at vfprintf.c:1661
1661 vfprintf.c: 没有那个文件或目录.
(gdb) frame
#0 0x00007f6b20e61943 in _IO_vfprintf_internal (s=<optimized out>, format=<optimized out>, ap=ap@entry=0x7fff3f3e1a78) at vfprintf.c:1661
1661 in vfprintf.c
(gdb) bt
#0 0x00007f6b20e61943 in _IO_vfprintf_internal (s=<optimized out>, format=<optimized out>, ap=ap@entry=0x7fff3f3e1a78) at vfprintf.c:1661
#1 0x00007f6b20e6a3d9 in __printf (format=<optimized out>) at printf.c:33
#2 0x0000000000400697 in main (argc=1, argv=0x7fff3f3e1c48) at error.c:8
主要调试命令:
bt: 栈回溯
frame:当前停止位置的frame
frame 1:回到对应标号的frame,标号就是bt命令输出的#数字
info args:查看参数
info locals:查看本地变量
print xxx:打印变量值
除了使用core dump进行调试,还可以直接使用gdb运行程序进行调试:
gdb error
增加如下几个常用的gdb 命令:
b main:设置main为breakpoint
run:开始运行
c:continue的缩写
n:单步运行(不跳入)
s:单步运行(跳入)
finish:跳出
这个示例的错误之处是没有加入头文件:
#include <string.h>
所以printf打印%s会报错。