生成coredump文件
1、ulimit 限制
可以用 ulimit
命令设置允许生成的core
文件大小,默认值是0
表示不能生成core
文件;
可以设置具体数值,可以看到单位是blocks
,1个block
大约是 4KB,可以用stat
命令查看;
或设置为 unlimited
表示无限大:
$ ulimit -a|grep core
core file size (blocks, -c) 0
$ ulimit -c
0
$ ulimit -c unlimited
$ ulimit -c
unlimited
$ ulimit -a|grep core
core file size (blocks, -c) unlimited
$ stat -f ~ | grep size
Block size: 4096 Fundamental block size: 4096
对应C
代码中的系统调用函数有:
int getrlimit(int resource, struct rlimit *rlim);
int setrlimit(int resource, const struct rlimit *rlim);
下面是设置为 unlimited
的例子:
#include<sys/resource.h>
int set_rlimit_infinity()
{
struct rlimit limit;
limit.rlim_cur = limit.rlim_max = RLIM_INFINITY;
return setrlimit(RLIMIT_CORE, &limit);
}
在很多开源软件中都有使用 setrlimit
函数,比如
goahead-5.1.1/src/http.c
nginx-1.14.2/src/os/unix/ngx_process_cycle.c
2、格式化文件名
默认在当前目录下生成一个叫 core
的文件:
$ cat /proc/sys/kernel/core_pattern
core
对应的 kernel 代码在:
https://elixir.bootlin.com/linux/v5.0/source/fs/coredump.c#L56
该文件除了可以命名为 core
,还可以通过core_pattern
自定义格式,具体的格式在 kernel 代码的 switch 语句里面有写:
https://elixir.bootlin.com/linux/v5.0/source/fs/coredump.c#L218
在man 5 core
中也有说明,比如常用的:
%p
表示 pid,
%e
表示可执行程序名,
%t
表示时间戳,
例如:
sudo sh -c "echo '/xxx/yyy/core.%e.%p.%t.%h.%s.%u' > /proc/sys/kernel/core_pattern"
另外,当 core_pattern
中没有配置 %p
时,
如果 /proc/sys/kernel/core_uses_pid
配置为 1
,表示会在文件名最后加上 .pid
。
3、目录权限
如果目录没有写权限则不能生成 core
文件,比如这个 xxx 目录,chmod 555 xxx
。
4、分区属性与权限
如果分区没用写权限,也不能生成core
文件。
在嵌入式开发的板子上,正式版本很多分区是只读的,而 debug 时需要临时改为可读写,通常可以用 mount -o rw,remount /xxx/xxx
命令把一个 ro
分区改为一个 rw
分区。
但如果该分区不是 Ext4
文件系统,而是 SquashFS
文件系统,则无法在运行时配置为 rw
,必须在编译时改好。
5、检查
一个简单的检验当前配置是否能生成 core
文件的方法是,用 kill
命令向 sleep
发送相关信号,比如:
$ sleep 60 &
$ kill -6 $(pidof sleep)