Coredump 调试
Coredump是什么?
Linux环境下,当程序异常退出(发生段错误)时,会产生一个core文件,该文件记录了程序运行时的内存,寄存器状态,堆栈指针,内存管理信息还有各种函数调用堆栈信息等,我们可以理解为是程序工作当前状态存储生成的一个文件,通过工具分析这个文件,我们可以定位到程序异常退出的时候对应的堆栈调用等信息,找出问题所在并进行及时解决。
前期设置
- 设置core文件生成的目录,其中%e表示程序文件名,%p表示进程ID,否则会在程序的当前目录生成dore文件。
echo /home/xuanxuan/data/coredump/core.%e.%p >/proc/sys/kernel/core_pattern
- 当前执行程序的用户对core目录有写权限且右足够的空间存储core文件。
- 生成不受限制的core文件。
ulimit -c unlimited
什么情况下会导致程序异常退出?
非法指针的访问,堆栈溢出。
如何调试
- 编译的时候添加-g选项,增加调试信息。
- gdb program core_file
**示例:**一个会产生异常退出的程序,非法指针访问。demo.c
#include <stdio.h>
int func(int* p){
int y = *p;
return y;
}
int main(void){
int *p = NULL;
return func(p);
}
编译,运行,错误已产生。如下图所示。
执行调试命令,结果如下图所示。
gdb demo /home/xuanxuan/data/coredump/core.demo.3102
bt/where命令查看堆栈调用信息
如果要查看某一层的信息,你需要切换当前的栈,一般来说,程序停止时,最顶层的栈就是当前栈,如果你要查看栈下面层的详细信息,首先要做的就是切换当前。
- frame/f n
frame n
f n
n是一个从0开始的整数,是栈中的层编号,比如:frame 0,表示栈顶,frame 1,表示栈的第二层。
- up
up n
表示向栈的上面移动n层,不指定n,则为向上移动一层。
- down
down n
表示向栈的下面移动n层,不指定n,则为向下移动一层。
如若不想打印对应栈层的信息,可以使用如下三个命令。
select-frame n #对应于 frame 命令
up-silently n #对应于 up 命令
down-silently n #对应于 down 命令
- frame/f
frame/f查看当前栈层信息。
会打印出:
- 栈的层编号
- 当前的函数名
- 函数参数值
- 函数所在文件及行号
- 函数执行到的语句
- info frame/f
可以查看到更详细的当前栈层的信息,只不过,大多数都是运行时的内存地址。比如:函数地址,被调用函数的地址,目前的函数是由什么样的程序语言写的,函数的参数地址及值,局部变量的地址等。如下图所示。
- info args
打印出当前函数的参数名及其值。
- info locals
打印出当前函数中所有局部变量及其值。