在现代操作系统中,Core Dump 指当程序异常终止或崩溃时,将程序此时的内存中的内容拷贝到磁盘文件中存储的技术。
在终端中输入如下命令可以检查当前系统的Core dump策略。
ulimit -c
如果输出是0,说明默认是关闭core dump。在这种情况下,即使程序异常终止也不会生成core dump文件。
在开始菜单中找到”终端“,打开终端。在终端内输入 ulimit -c
unlimited 。上面这个表示临时开启Core Dump,并且设置大小不受限。用上面的命令只会对当前的终端环境有效。
下面有三种方法:
方法一
修改 /etc/security/limits.conf 在最后增加一行:
* soft core unlimited
方法二
在 /etc/profile 中加入如下命令
ulimit -c unlimited
方法三
在 ~/.bashrc 中添加如下命令。
ulimit -c unlimited
然后执行命令
source ~/.bashrc
让修改立刻生效。
方法一和方法二需要重启系统,才能生效。方法三只对当前用户有效。
这里提供一个错误的例子。
为了进行如下的操作请先安装 build-essential 和 gdb 。
在终端中输入以下指令:
sudo apt update && sudo apt install build-essential gdb
代码如下:
main.c
#include <stdio.h>
int main()
{
int a = 0;
int b = 1;
printf("%d",b/a);
return 0;
}
在终端中输入如下命令来编译该源文件生成可执行程序。需要注意的是:
需要切换到main.c所在的目录中执行命令
gcc main.c -g -o test
注意:需要加入-g 来方便调试。
./test
正常情况下会有如下的输出:
[1] 42790 floating point exception (core dumped) ./test
与此同时,会在test 所在目录下生成core文件。
使用gdb 查看core文件的语法如下:
gdb [程序] [生成的core dump文件]
在我们这个例子中,应该使用如下的命令:
gdb ./test core
命令的输出如下:
GNU gdb (Uos 11.2-1) 11.2
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./test...
[New LWP 42790]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `./test'.
Program terminated with signal SIGFPE, Arithmetic exception.
#0 0x0000000000401140 in main () at main.c:6
6 printf("%d",b/a);
我们输入 bt 查看backstrace来检查程序运行在哪里,来定位core dump发生在哪一行。
(gdb) bt
#0 0x0000000000401140 in main () at main.c:6
从上面的结果可以看出,程序在main.c 的第6行 printf("%d",a/b); 出了问题。
上述测试中,所有的core dump都会生成core文件。会有覆盖的问题,存在我们需要的文件被覆盖的情况。如果系统中其他的程序运行时发生崩溃,那么我们程序生成的core dump文件会被覆盖。为了解决这种情况,需要进行额外设置。
输入如下命令就可以临时让core 文件带进程号 (pid) 扩展名。
sudo bash -c "echo 1 > /proc/sys/kernel/core_uses_pid"
/proc/sys/kernel/core_uses_pid 为0表示生成的core 文件统一命名为core,为1表示添加进程号 (pid) 作为扩展名 (格式为core.xxxx) 。
echo "/corefile/core-%e-%p-%t" > core_pattern
上面的命令可以将core文件统一存放到 /corefile 目录下。文件格式
为 core-程序名-pid-时间戳
方法一
使用 sysctl -w name=value 命令。例如:
/sbin/sysctl -w kernel.core_pattern=/corefile/core-%e-%p-%t
方法二
修改 /etc/sysctl.conf 文件。修改 (如果不存在就添加)
如下两个变量:
kernel.core_pattern = /var/core/core_%e_%p
kernel.core_uses_pid=0
上面修改会让生成的core文件存放在 /var/core/ 目录下。如果想直接生成在可执行文件相同的目录,前面不需要加任何目录。
例如:
kernel.core_pattern=core_%e_%p
执行下面命令让更改生效
sysctl -p /etc/sysctl.conf
下面是参数列表:
参数 | 功能 |
---|---|
%p | 添加进程号 pid |
%u | 添加用户号 uid |
%g | 添加组号 gid |
%s | 添加导致产生core 的信号 |
%t | 添加时间戳 |
%h | 添加主机名 |
%e | 添加程序名 |
上述例子中,我们将coree dump的大小设置为不受限。这可能会导致core文件过大导致系统磁盘占用过多问题。需要我们定期清理磁盘上的core文件。系统也提供了一个限制单次所生成的core文件大小的方法。
方法一
修改 /etc/security/limits.conf 文件,添加(或者修改)一行。
* soft core limit
上面的limit 改成我们需要的大小(单位是KB)。
方法二
修改 /etc/profile 文件,添加(或者修改)一行。
ulimit -c limit
方法三
修改 ~/.bashrc 文件,添加 (或者修改) 一行。
ulimit -c limit
输入命令让下面生效。
source ~/.bashrc
上面的limit 改成我们需要的大小(单位是KB)。
方法一和方法二都需要重启系统,让更改生效。方法三只对当前用户有效。
在终端输入下面命令就可以让更改临时生效。
ulimit -c limit
注意:core dump 是程序地址空间的全部镜像。包括代码,栈和堆。所以大小会比程序大。通过这种方法限制core dump文件大小可能会导致生成的core文件不完整。不完整的core会导致解码失败。
https://www.shuzhiduo.com/A/kvJ3nx0gzg/
https://www.jianshu.com/p/1e30b53be6ab
https://stackoverflow.com/questions/2762879/linux-core-dumps-are-toolarge
此文档由统信软件销售中心输出