马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
core dump 是什么,以及 Ubuntu 20.04 下生成不了 core 文件的解决办法
程序崩了却复现不了,是调试里最难受的场景。core dump 就是把进程崩溃那一刻的内存镜像留下来,事后再慢慢分析。这篇先讲 core 和 term 的区别、coredump 的用途,再重点解决 Ubuntu 20.04 上明明 ulimit -c 设了却生不成 core 文件的问题。
一、core 与 term 的区别
前面讲信号时提过,终止进程的信号动作分两种:term(termination)直接把进程干掉,什么也不留;core 同样是终止进程,但会在终止的同时把进程的核心数据转储到磁盘,形成 core dump 文件。同一个信号是走 core 还是走 term,取决于信号自身的默认动作,也受当前 ulimit -c 限制。
二、coredump 文件的作用
- 定位崩溃点:core 里保留了崩溃瞬间的内存状态,including 变量值、函数调用栈,
gdb ./a.out core 直接能看到崩在第几行。
- 查内存泄漏:既然记录了崩溃时的堆状态,配合调试符号能找出哪些内存没被释放。
- 复现难复现的问题:线上偶发崩溃在本地环境复现不出来,留下 core 就等于把现场带回了本地。这种方式也叫事后调试(post-mortem debugging)。
三、先打开 core 文件功能
Linux 默认关掉了 core 生成,也就是 ulimit -c 为 0:
ulimit -c 10240 # 允许 core 文件最大 10240 KB(约 10 MB),0 表示关闭
ulimit -c # 查看当前值
设完之后写一个除零的测试程序:
#include <iostream>
using namespace std;
int main()
{
int a = 10;
a /= 0;
return 0;
}
编译运行,ulimit -c 已经是 10240 了,可当前目录里啥也没有——这就是 Ubuntu 20.04 的经典坑。
四、Ubuntu 20.04 下生成不了的解决办法
1. 把 core_pattern 设成 core
Ubuntu 20.04 上 /proc/sys/kernel/core_pattern 的内容默认是空的(实际指向 apport 之类的处理管道),导致 core 被吞掉而不是落在当前目录。用 root 或 sudo 提权写进去:
sudo bash -c "echo core > /proc/sys/kernel/core_pattern"
设成 core 之后,崩溃时内核就把文件命名为当前目录下的 core,而不是带一堆 pid、时间戳的默认名字。core 文件名是可以自定义的,但建议就用 core,后续脚本处理最省事。
再回到那个除零程序重新编译运行,core 文件出来了。用 gdb 一开就指明错在第 6 行(a /= 0):
gdb ./a.out core
(gdb) bt
(gdb) list
2. 为什么非要用 shell 写 /proc
试过用 vim 编辑 core_pattern 的同学多半撞过红字报错。原因是 /proc 是伪文件系统:它只存在于内存里,不占磁盘空间,下面的文件也不是真正的磁盘文件,而是内核运行时暴露出来的状态与参数接口。
换句话说,你用 vim 往 /proc/sys/kernel/core_pattern 里"存盘",实际是在尝试修改内核参数,内核不允许,编辑器自然报错。改这类文件正确的姿势就是用 shell 重定向:
sudo bash -c "echo core > /proc/sys/kernel/core_pattern"
五、结论与补充
- core 与 term 是信号终止进程的两种动作,core 会额外产出内存镜像供事后调试。
- 生成 core 需要两件事同时成立:
ulimit -c 不为 0,且 core_pattern 指向一个可写位置。Ubuntu 20.04 默认卡在第二点。
- 网上也有说禁用 apport 就能在当前目录出 core,但在 20.04 上实测并不管用,改
core_pattern 才是有效解。
- 把
ulimit -c unlimited 写进 /etc/security/limits.conf,可以对全会话永久生效,避免每次开终端都要重设。
调 core 的时候记得先 ulimit -c 0 关掉,不然一个跑飞的程序能把磁盘塞满——这也是"磁盘被 core 文件写满导致系统起不来"这类事故的常见成因。
qidao123.com企服评测-应用市场 编辑提示 |