一、启用core dump
在一般Linux系统中,默认是不会产生core dump文件的。
$ulimit-c
查看coredump文件的大小,一般开始是0表示内核转储无效。
$ulimit -c unlimited //不限制内核转储文件的大小
$ulimit -c 1024 //将转储文件设置未指定大小(单位kbytes)
二、在专用目录中生成core dump文件
转储文件可以通过/etc/sysctl.conf中的kernel.core_pattern变量来设置
如将core dump文件放在/var/core下:
$cat /etc/sysctl.conf
kernel.core_pattern= /var/core/%t-%e-%p-%c.core
kernel.core_uses_pid= 0
$sysctl -p
如果kernel.core_uses_pid= 1 文件末尾会添加PID
kernel.core_pattern可以设置的格式符:
%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 添加命令名
三、自动压缩转储文件
利用用户模式辅助程序来压缩core dump文件。
/etc/sysctl.conf中的kernel.core_pattern变量来设置
$cat /etc/sysctl.conf
kernel.core_pattern= | usr/local/sbin/core_helper %t %e %p %c
kernel.core_uses_pid= 0
$sysctl-p
core_helper的内容:
$cat usr/local/sbin/core_helper
#!/bin/sh
execgzip ->/var/core/$1-$2-$3-$4.core.gz
四、设置转储的共享内存
通过设置/proc/<PID>/coredump_filter来过滤转储的共享内存
coredump_filter使用的是比特位掩码来表示内存
bit 0 匿名专用内存
bit1 匿名共享专用内存
bit2 file-backed专用内存
bit3 file-backed共享内存
bit4 ELF文件映射
要跳过所有的共享内存区段,应将coredump_filter设置为1
$echo 1>/proc/<PID>/coredump_filter
五、例
编译时加上-g发生core dump之后, 用gdb进行查看core文件的内容, 以定位文件中引发coredump的行.
gdb[exec file] [core file]
如:
gdb./test test.core
在进入gdb后, 用bt命令查看backtrace以检查发生程序运行到哪里, 来定位core dump的文件行.
//test.c
void a()
{
char *p = NULL;
printf("%d/n", *p);
}
intmain()
{
a();
return0;
}
编译
gcc -g-o test test.c
运行./test
报segmentationfault(core dump)
如果生成的是test.core.
gdb./test test.core
六、System Dump和Core Dump的区别
(1)System Dump
所有开放式操作系统,都存在系统DUMP问题。
产生原因:
由于系统关键/核心进程,产生严重的无法恢复的错误,为了避免系统相关资源受到更大损害,操作系统都会强行停止运行,并将当前内存中的各种结构,核心进程出错位置及其代码状态,保存下来,以便以后分析。最常见的原因是指令走飞,或者缓冲区溢出,或者内存访问越界。走飞就是说代码流有问题,导致执行到某一步指令混乱,跳转到一些不属于它的指令位置去执行一些莫名其妙的东西(没人知道那些地方本来是代码还是数据,而且是不是正确的代码开始位置),或者调用到不属于此进程的内存空间。写过C程序及汇编程序的人士,对这些现象应当是很清楚的。
系统DUMP生成过程的特点:
在生成DUMP过程中,为了避免过多的操作结构,导致问题所在位置正好也在生成DUMP过程所涉及的资源中,造成DUMP不能正常生成,操作系统都用尽量简单的代码来完成,所以避开了一切复杂的管理结构,如文件系统)LVM等等,所以这就是为什么几乎所有开放系统,都要求DUMP设备空间是物理连续的——不用定位一个个数据块,从DUMP设备开头一直写直到完成,这个过程可以只用BIOS级别的操作就可以。这也是为什么在企业级UNIX普遍使用LVM的现状下,DUMP设备只可能是裸设备而不可能是文件系统文件,而且[b]只[/b]用作DUMP的设备,做 LVM镜像是无用的——系统此时根本没有LVM操作,它不会管什么镜像不镜像,就用第一份连续写下去。
所以UNIX系统也不例外,它会将DUMP写到一个裸设或磁带设备。在重启的时候,如果设置的DUMP转存目录(文件系统中的目录)有足够空间,它将会转存成一个文件系统文件,缺省情况下,[b]对于AIX来说是/var/adm/ras/下的vmcore*这样的文件,对于HPUX来说是 /var/adm/crash下的目录及文件。[/b]
当然,也可以选择将其转存到磁带设备。
会造成系统DUMP的原因主要是:
系统补丁级别不一致或缺少)系统内核扩展有BUG(例如Oracle就会安装系统内核扩展))驱动程序有 BUG(因为设备驱动程序一般是工作在内核级别的),等等。所以一旦经常发生类似的系统DUMP,可以考虑将系统补丁包打到最新并一致化)升级微码)升级设备驱动程序(包括FC多路冗余软件))升级安装了内核扩展的软件的补丁包等等。
(2) 进程Core Dump
进程Core Dump产生的技术原因,基本等同于系统DUMP,就是说从程序原理上来说是基本一致的。
但进程是运行在低一级的优先级上(此优先级不同于系统中对进程定义的优先级,而是指CPU代码指令的优先级),被操作系统所控制,所以操作系统可以在一个进程出问题时,不影响其他进程的情况下,中止此进程的运行,并将相关环境保存下来,这就是core dump文件,可供分析。
如果进程是用高级语言编写并编译的,且用户有源程序,那么可以通过在编译时带上诊断用符号表(所有高级语言编译程序都有这种功能),通过系统提供的分析工具,加上core文件,能够分析到哪一个源程序语句造成的问题,进而比较容易地修正问题,当然,要做到这样,除非一开始就带上了符号表进行编译,否则只能重新编译程序,并重新运行程序,重现错误,才能显示出源程序出错位置。
如果用户没有源程序,那么只能分析到汇编指令的级别,难于查找问题所在并作出修正,所以这种情况下就不必多费心了,找到出问题的地方也没有办法。