转储文件(core dump)本来是在程序运行出错的时候产生的。转储文件记录了进程出错时的内存映像,以及进程执行的上下文环境,如寄存器的值等。它的主要用途是在程序运行崩溃时记录下进程的瞬时情况,从而为找出导致程序崩溃的原因提供宝贵的信息。
如果程序在执行过程中崩溃,在一定的条件下有可能会产生转储文件(常被称为core dump文件),core文件是该进程(异常终止时)的内存映像(同时加上调试信息)。此时也可以指定要调试程序的可执行映像和对应的转储文件。假设一个程序的的名字是prog执行出错,产生的转储文件名为prog.core。那么可以用下述方式启动GDB、
gdb prog prog.core
或者也可能指定GDB所启动的被调试程序的PID(process ID ,即进程ID号)。假设指定的进程ID为1234,则可以按如下的方式启动:
gdb prog 1234
core 文件里,方便程序员找到程序出现问题的地方,最常出现的,几乎所有C程序员都出现过的错误就是“段错误”了。有了Core文件,当程序调试崩溃时,我们不会再束手无策了!
1.core文件的生成开关和大小限制
---------------------------------
1)使用ulimit -c命令可查看core文件的生成开关。若结果为0,则表示关闭了此功能,不会生成core文件。
2)使用ulimit -c filesize命令,可以限制core文件的大小(filesize的单位为kbyte)。若ulimit -c unlimited,则表示core文件的大小不受限制。如果生成的信息超过此大小,将会被裁剪,最终生成一个不完整的core文件。在调试此core文件的时候,gdb会提示错误。
3)如果想要永久生效可以,也可以修改系统文件来调整core选项
在/etc/profile通常会有这样一句话来禁止产生core文件,通常这种设置是合理的:
# No core files by default
ulimit -S -c 0 > /dev/null 2>&1
但是在开发过程中有时为了调试问题,还是需要在特定的用户环境下打开core文件产生的设置。在用户的~/.bash_profile里加上ulimit -c unlimited来让特定的用户可以产生core文件
如果ulimit -c 0 则也是禁止产生core文件,而ulimit -c 1024则限制产生的core文件的大小不能超过1024kb。也可以使用下面的语句,在/etc/profile文件中。
ulimit -S -c 100 > /dev/null 2>&1
表示生成的core文件的大小可以是100 * 1024 byte。
2.core文件的名称和生成路径
----------------------------
core文件生成路径:
输入可执行文件运行命令的同一路径下。
若系统生成的core文件不带其它任何扩展名称,则全部命名为core。新的core文件生成将覆盖原来的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)proc/sys/kernel/core_pattern可以控制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 添加命令名
3 不产生core文件的情况
1) 进程是设置用户 ID 的,而且当前用户并非程序文件的所有者;
2) 进程是这是组 ID 的,而且当前用户并非该程序文件的组所有者;
3) 用户没有写当前工作目录的权限;
4) 该文件已存在,而且用户对该文件没有写权限;(上述 4 条超级用户除外)
5) 该文件太大(超过了 RLIMIT_CORE 限制,下面将介绍:查询、更改该值的方法)
下面是摘自《UNIX环境高级编程》第10章信号
使用core文件调试程序
看下面的例子
/*core_dump_test.c*/
#include<stdio.h>
const char *str = "test";
void core_test()
{
str[1] ='T';
}
int main()
{
core_test();
return 0;
}
|
编译的时候会出现段错误。如果core文件的开关是打开的话,就可以使用GDB进行调试core文件了,一般情况下生成的core文件是core.XXXX,后面的xxxx,表示的是进程的ID号。在GDB中,可以使用where查看出错的堆栈的信息,我们很容易找到我们程序在是后崩溃的时候调用了core_dump_test.c文件中的str[i]='T',导致了程序的崩溃。需要注意的是,在调试时要加上-g选项来,在生成的二进制文件中添加调试信息。
在Linux下可以使用GDB来调试core文件。
gdb core_dump_test core.1234
附录产生core文件的条件:
当进程接收到以下信号时,默认动作会产生core文件:
UNIX System signals
Name | Description
| ISO C | SUS
| FreeBSD5.2.1 | Linux2.4.22
| MacOSX10.3
| Solaris9 | 默认动作
|
SIGABRT | 异常终止(abort) | Y | Y | Y | Y | Y | Y | 终止+core |
SIGBUS | 硬件故障 | | Y | Y | Y | Y | Y | 终止+core |
SIGEMT | 硬件故障 | | | Y | Y | Y | Y | 终止+core |
SIGFPE | 算术异常 | Y | Y | Y | Y | Y | Y | 终止+core |
SIGILL | 非法硬件指令 | Y | Y | Y | Y | Y | Y | 终止+core |
SIGIOT | 硬件故障 | | | Y | Y | Y | Y | 终止+core |
SIGQUIT | 终端退出符 | | Y | Y | Y | Y | Y | 终止+core |
SIGSEGV | 无效内存引用 | Y | Y | Y | Y | Y | Y | 终止+core |
SIGSYS | 无效系统调用 | | XSI | Y | Y | Y | Y | 终止+core |
SIGTRAP | 硬件故障
| | XSI | Y | Y | Y | Y | 终止+core |
SIGXCPU | 超过CPU限制(setrlimit) | | XSI | Y | Y | Y | Y | 终止+core |
SIGXFSZ | 超过文件长度限制(setrlimit) | | XSI | Y | Y | Y | Y | 终止+core
|
阅读(4886) | 评论(0) | 转发(3) |