在现代 Linux 发行版(如较新版本的 Ubuntu、Fedora 等)上,系统默认使用 zstd 这种高效的压缩算法来压缩 core dump 文件,从而生成 .zst 后缀的文件,以节省磁盘空间。

要查看和分析这种 core 文件,需要先将其解压,然后再用调试工具(如 GDB)加载。以下是详细的步骤:

步骤 1:安装必要的工具

首先,确保你的系统已经安装了 zstd 压缩工具和 gdb 调试器。

在基于 Debian/Ubuntu 的系统上:

1
2
sudo apt update
sudo apt install zstd gdb

在基于 RHEL/CentOS/Fedora 的系统上:

1
2
3
4
5
6
# Fedora/CentOS 8+
sudo dnf install zstd gdb
# 或者
# CentOS 7
sudo yum install epel-release
sudo yum install zstd gdb

步骤 2:解压 .zst 格式的 core 文件

使用 zstd 命令来解压文件。zstd 非常智能,它既可以压缩也可以解压。

基本解压命令:

1
2
3
zstd -d core.%pid.%executable.%signal.%timestamp.zst
# 或者使用更简短的格式,-d 代表 decompress(解压)
zstd -d core.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(或者带有长长后缀的名字)。

  1. 找到你的程序路径: 如果你是在当前目录编译和运行的,程序可能就是 ./my_app

  2. 运行 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
  3. 在 GDB 中查看信息: 加载成功后,GDB 会显示程序崩溃时的位置(信号、函数、代码行等)。常用的命令有:

    • btwhere:打印回溯信息(backtrace),这是最关键的一步,它会显示崩溃时函数的调用栈。
    • info registers:查看寄存器状态。
    • list:查看崩溃位置附近的代码。
    • print <变量名>:打印变量的值。

完整工作流示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 1. 解压 core 文件(假设文件名为 core.1234.my_app.11.1712345678.zst)
$ zstd -d -k core.1234.my_app.11.1712345678.zst

# 解压后得到 core.1234.my_app.11.1712345678

# 2. 使用 GDB 进行分析
$ gdb ./my_app core.1234.my_app.11.1712345678

# 3. 在 GDB 界面中,立即会看到崩溃信息,然后输入 ‘bt‘ 查看详细堆栈
(gdb) bt
#0 0x00007f1234567890 in some_crash_function () at src/main.c:123
#1 0x0000555555555123 in main (argc=1, argv=0x7ffc5f0a8d68) at src/main.c:456
...

(gdb) quit

补充说明:为什么会有 .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
2
3
4
5
6
7
8
# 列出所有 coredump
coredumpctl list

# 用 GDB 打开最新的一个 coredump(会自动处理压缩和解压)
coredumpctl gdb

# 用 GDB 打开特定程序的最后一个 coredump
coredumpctl gdb <程序名>

使用 coredumpctl 通常是更推荐的方式,因为它能自动匹配程序和 core 文件。

总结

  1. 安装工具:确保安装了 zstdgdb
  2. 解压文件:使用 zstd -d core-file.zst 解压。
  3. 分析调试:使用 gdb /path/to/program /path/to/decompressed-core 加载分析。
  4. 查看堆栈:在 GDB 中使用 bt 命令查看崩溃调用栈。
  5. (推荐) 如果系统使用 systemd-coredump,直接使用 coredumpctl gdb 命令更为方便。