1. 段错误相关概念
1)什么是段错误 ?
段错误是指访问的内存超出了系统给这个程序设定的内存空间,简单来说就是访问了非法内存。
2)什么是 Core文件 ?
当段错误发生时,操作系统会把程序crash时的内存内容dump出来,并保存到一个文件里即core文件。
3) core文件名字的由来
在使用半导体作为内存材料前,人们采用线圈作为内存的材料,线圈英文名 core,用线圈做的内存就叫做core memory。现在随着半导体工业的飞速发展,已经不再使用core memory了,但是人们还是把记忆体叫做core。因此,把保存程序crash时内存内容的文件称作core文件。
2. core文件命名与存储规则
通常core文件名称为 "core.进程号",是否以进程号为后缀是由内核相关参数来控制的,即/proc/sys/kernel/core_uses_pid。我们可以通过cat命令查看其值:
1 root@xzkj:/home/xzkj# cat /proc/sys/kernel/core_uses_pid
2 1
当然也可以设置该值,(需超级用户权限):
1 root@xzkj:/home/xzkj# echo 1 > /proc/sys/kernel/core_uses_pid
2 root@xzkj:/home/xzkj# cat /proc/sys/kernel/core_uses_pid
3 1
此外,我们还可以设置该文件的保存位置与名称格式,这通过/proc/sys/kernel/core_pattern参数来控制
root@xzkj:/home/xzkj# echo "./core-%e-%p-%t" > /proc/sys/kernel/core_pattern
即将core文件保存在当前目录下,产生的core文件名称为"core-程序名-进程号-时间戳",参数含义如下:
%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文件的情况。默认core文件保存在启动该进程时所在的目录,但脚本启动时可能会修改当前目录,此时进程真正的当前目录就会与执行脚本时所在目录不同。这种情况可通过查看"/proc/进程号/cwd"来查找真正的当前目录。
3. 确保产生core文件注意事项
- 保证存放core文件的目录存在且进程对其具有写权限
- 当程序调用了setuid/setgid改变进程有效用户或组时,则一般不会产生core文件。此时可通过设置下列参数使能产生core文件功能
root@xzkj:/home/xzkj# echo 1 > /proc/sys/fs/suid_dumpable
- core dump默认是关闭的,采用以下命令开启
root@xzkj:/home/xzkj# ulimit -c unlimited
root@xzkj:/home/xzkj# ulimit -c 3
unlimited
4. 程序中开启core功能
上面都是采用命令方式使能或开启core dump功能,其实程序中也可以开启core dump。下面贴出示例源码
1#include <unistd.h>
2#include <sys/time.h>
3#include <sys/resource.h>
4#include <stdio.h>
5
6#define CORE_SIZE 1024 * 1024 * 50
7
8int main()
9{
10 struct rlimit rlmt;
11 if (getrlimit(RLIMIT_CORE, &rlmt) == -1) {
12 return -1;
13 }
14 printf("Before set rlimit CORE dump current is:%d, max is:%d\n", (int)rlmt.rlim_cur, (int)rlmt.rlim_max);
15
16 rlmt.rlim_cur = (rlim_t)CORE_SIZE;
17 rlmt.rlim_max = (rlim_t)CORE_SIZE;
18
19 if (setrlimit(RLIMIT_CORE, &rlmt) == -1) {
20 return -1;
21 }
22
23 if (getrlimit(RLIMIT_CORE, &rlmt) == -1) {
24 return -1;
25 }
26 printf("After set rlimit CORE dump current is:%d, max is:%d\n", (int)rlmt.rlim_cur, (int)rlmt.rlim_max);
27
28 return 0;
29}
未完,待续~
更多文章,欢迎关注公众号交流~