一、前言
linux下开发时,有时候程序突然崩溃了,没有任何日志。
从core文件中分析原因,通过gdb看出程序挂在哪里,分析前后的变量,找出问题的原因。
core文件都带有进程名称、进程ID、和时间,这又是怎么做到的呢?接下来记录core文件的生成和配置。
二、基本概念
当程序运行的过程中异常终止或崩溃,操作系统会将程序当时的内存状态记录下来,保存在一个文件中,这种行为就叫做Core Dump(中文有的翻译成“核心转储”)。我们可以认为 core dump 是“内存快照”,但实际上,除了内存信息之外,还有些关键的程序运行状态也会同时 dump 下来,例如寄存器信息(包括程序指针、栈指针等)、内存管理信息、其他处理器和操作系统状态和信息。
core dump 对于编程人员诊断和调试程序是非常有帮助的,因为对于有些程序错误是很难重现的,例如指针异常,而 core dump 文件可以再现程序出错时的情景。
三、配置系统,开启core dump
1、查看系统中core文件生成的开关是否打开
1)使用ulimit -c命令可查看core文件的生成开关,若结果为0,则便是关闭了此功能,不会生成core文件。
2、设置core文件生成
可使用命令ulimit开启,或在程序中通过setrlimit系统调用开启。
(1)使用命令 ulimit -c filesize (只对当前shell进程有效)
若 ulimit -c unlimited ,则标识此core文件的大小不受限制
若指定 ulimit -c 1024,如果生成的信息超过1024,将会被裁剪,最终生成一个不完整的core文件,在调 试此core文件时,gdb会提示错误。
(2)但是若想整个系统中生效则方法如下:
<1> 编辑 /root/.bash_profile 文件,在其中加入 ulitmit -S -c unlimited (一劳永逸)
<2> source /root/.bash_profile
# ulimit -c
0
$ ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
file size (blocks, -f) unlimited
3、core文件的设置
1) /proc/sys/kernel/core_uses_pid 可以控制core文件的问价名是否添加PID作为扩展,文件的内容为1,
标识添加PID作为扩展,生成的core文件格式为core.XXXX;为0则表示生成的core文件统一命名为core;
可通过一下命令修改此文件:
echo "1" > /proc/sys/kernel/core_uses_pid
2)core文件的保存位置和文件名格式
echo "/corefile/core-%e-%p-%t" > core_pattern,
可以将core文件统一生成到/corefile目录下,产生的文件名为core-命令名-pid-时间戳,以下是参数列表:
%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时间
%h - insert hostname where the coredump happened into filename 添加主机名
%e - insert coredumping executable name into filename 添加命令名
三、用gdb查看core文件
发生core dump之后, 用gdb进行查看core文件的内容, 以定位文件中引发core dump的行.
gdb [exec file] [core file]
如: gdb ./selfminitor core.23314
使用gdb 调试方法,首先要在gcc编译时加入-g选项。
调试core文件,在Linux命令行下:gdb pname corefile。
例如,程序名为selfminitor,core文件为core.3421,则为:gdb selfminitor core.3421。
这样进入了gdb core调试模式。
追踪产生segmenttation fault的位置及代码函数调用情况:
gdb>bt
这样,一般就可以看到出错的代码是哪一句了,还可以打印出相应变量的数值,进行进一步分析。
gdb>print 变量名