使用命令ulimit可以查看内核转储功能是否开启:
用以下方式启动gdb:
$ ulimit -c
0
|
-c选项表示内核转储文件的大小限制。0表示内核转储无效。
可以使用下面的命令开启:
$ ulimit -c unlimited
|
再次查看:
$ ulimit -c
unlimited
|
运行测试程序
$ ./test_ulimit 段错误 (核心已转储) |
当前目录下会生成core文件,下面查看本文件的类型:
$ file core
core: ELF 32-bit LSB core file Intel 80386, version 1 (SYSV), SVR4-style, from './test_ulimit'
|
用以下方式启动gdb:
gdb -c core ./test_ulimit
Core was generated by `./test_ulimit'. Program terminated with signal 11, Segmentation fault. #0 0x080483c4 in main () at test_ulimit.c:13 13 *a = 1; |
查看文件test_ulimit.c的内容:
/* filename: test_ulimit.c
* description: this program used to show the core dump
* author: Howard
* version: v1.0
* time: 2013-11-22
*/
#include <stdio.h>
int main(void)
{
int *a = NULL;
*a = 1;
return 0;
}
可见在第13行的地方,给指向空地址(NULL或者为0)赋值1,在Linux内存分布中0地址属于内核地址,不属于进程自己的地址,所以出现段错误。
为了管理上的方便我们让内核转储文件在特殊的位置上,需要修改/etc/sysctl.conf文件,在文件中添加:
kernel.core_pattern = /home/<username>/Core/%t-%e-%p-%c.core |
其中username是用户自己的用户名。
接下来重复执行test_ulimit程序:
$ ./test_ulimit
段错误 (核心已转储)
$ ls ../Core
1385020307-test_ulimit-3982-4294967295.core
$ file ../Core/1385020307-test_ulimit-3982-4294967295.core ../Core/1385020307-test_ulimit-3982-4294967295.core: ELF 32-bit LSB core file Intel 80386, version 1 (SYSV), SVR4-style, from './test_ulimit' |
注:要是想转储到其他的目录,要确定有写权限,而且路径中所有的目录正确。 |
kernel.core_pattern中可设置的格式符:
格式符 | 说明 |
%% | %字符本身 |
%p | 被转储进程的ID |
%u | 被转储进程的真实用户ID |
%g | 被转储进程的真实组ID |
%s | 引发转储的信号编号 |
%t | 转储时刻(从1970年1月1号0点开始的秒数) |
%h | 主机名 |
%e | 可执行文件名 |
%c | 转储文件大小的上限 |