在现代 Linux 发行版(如较新版本的 Ubuntu、Fedora 等)上,系统默认使用 zstd 这种高效的压缩算法来压缩 core dump 文件,从而生成 .zst 后缀的文件,以节省磁盘空间。
要查看和分析这种 core 文件,需要先将其解压,然后再用调试工具(如 GDB)加载。以下是详细的步骤:
步骤 1:安装必要的工具
首先,确保你的系统已经安装了 zstd 压缩工具和 gdb 调试器。
在基于 Debian/Ubuntu 的系统上:
1 | sudo apt update |
在基于 RHEL/CentOS/Fedora 的系统上:
1 | # Fedora/CentOS 8+ |
步骤 2:解压 .zst 格式的 core 文件
使用 zstd 命令来解压文件。zstd 非常智能,它既可以压缩也可以解压。
基本解压命令:
1 | zstd -d core.%pid.%executable.%signal.%timestamp.zst |
解压成功后,会生成一个同名的但没有 .zst 后缀的文件。例如,解压 core.1234.vim.11.1712345678.zst 后会得到 core.1234.vim.11.1712345678。
如果你想保留原始的 .zst 文件,可以使用 -k 选项:
1 | zstd -d -k core.zst |
你也可以指定输出文件的名称:
1 | zstd -d -o my_core_file core.zst |
这将把解压后的内容输出到 my_core_file,而原始 core.zst 保持不变。
步骤 3:使用 GDB 分析解压后的 core 文件
解压完成后,你就可以像分析普通 core 文件一样,使用 GDB 来调试它了。
命令格式:
1 | gdb <生成core文件的可执行程序路径> <解压后的core文件路径> |
举个例子:
假设你的程序名为 my_app,解压后的 core 文件就是 core(或者带有长长后缀的名字)。
找到你的程序路径: 如果你是在当前目录编译和运行的,程序可能就是
./my_app。运行 GDB:
1
2
3
4
5
6
7
8# 如果 core 文件就在当前目录,并且名字就是 ‘core'
gdb ./my_app core
# 如果 core 文件有复杂的名字
gdb ./my_app core.1234.vim.11.1712345678
# 如果程序和core文件不在当前目录
gdb /path/to/my_app /path/to/core在 GDB 中查看信息: 加载成功后,GDB 会显示程序崩溃时的位置(信号、函数、代码行等)。常用的命令有:
bt或where:打印回溯信息(backtrace),这是最关键的一步,它会显示崩溃时函数的调用栈。info registers:查看寄存器状态。list:查看崩溃位置附近的代码。print <变量名>:打印变量的值。
完整工作流示例
1 | # 1. 解压 core 文件(假设文件名为 core.1234.my_app.11.1712345678.zst) |
补充说明:为什么会有 .zst 文件?
这是由 /proc/sys/kernel/core_pattern 配置决定的。现代系统通常将其设置为通过 systemd-coredump 服务来处理 core 文件,该服务默认会压缩存储 core 文件。
你可以通过以下命令查看你系统的设置:
1 | cat /proc/sys/kernel/core_pattern |
如果输出是 |/usr/lib/systemd/systemd-coredump %P %u %g %s %t %c %h 之类的格式,说明你正在使用 systemd-coredump。在这种情况下,你还可以使用 coredumpctl 命令来列表和管理 core 文件,而无需手动解压。
例如:
1 | # 列出所有 coredump |
使用 coredumpctl 通常是更推荐的方式,因为它能自动匹配程序和 core 文件。
总结
- 安装工具:确保安装了
zstd和gdb。 - 解压文件:使用
zstd -d core-file.zst解压。 - 分析调试:使用
gdb /path/to/program /path/to/decompressed-core加载分析。 - 查看堆栈:在 GDB 中使用
bt命令查看崩溃调用栈。 - (推荐) 如果系统使用
systemd-coredump,直接使用coredumpctl gdb命令更为方便。