登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  文章 >  linux

Linux coredumpctl 怎样提取指定进程的崩溃转储

来源:17golang原创

时间:2026-11-02 13:52:24 419浏览 收藏

要提取指定进程的崩溃转储,先用 coredumpctl info PID 确认目标记录,再用 coredumpctl --output=文件路径 dump PID 把二进制 core 写入文件。不要直接把 dump 的输出留在终端,也不要只看到同一个程序名就默认它对应最近一次崩溃。

官方地址:https://www.freedesktop.org/software/systemd/man/258/coredumpctl.html

下面的 PID、程序名和路径都是占位示例,重点是定位条件、存储状态和权限边界。coredumpctl 读取的是 systemd-coredump 保存的崩溃元数据与 core;记录还在 journal 中,不代表对应的 core 文件一定仍然存在。

先把“指定进程”说清楚

我会先固定一个目标身份,再决定匹配方式。按 PID 查询最窄,适合已经从服务日志或监控记录拿到崩溃进程号的场景;按 COMM 查询适合知道可执行文件名但不知道完整路径的场景;按 EXE 查询则要求使用带斜杠的可执行文件路径。它们都在匹配 journal 里的崩溃记录,不是让 coredumpctl 重新扫描正在运行的进程。

# 例中 PID 仅用于说明参数位置,请替换成已经确认过的崩溃进程号。
crash_pid=24680

# 先列出这个 PID 对应的记录,避免直接导出错对象。
coredumpctl --no-pager list "$crash_pid"

# 已知程序名时按 COMM 查询;名称不能包含斜杠。
coredumpctl --no-pager list my-worker

# 已知完整可执行文件路径时按 EXE 查询;路径至少包含一个斜杠。
coredumpctl --no-pager list /usr/local/bin/my-worker

如果同一程序崩溃多次,程序名查询可能返回多行;这时不能把“能查到”当成“已经选对”。先看时间、PID、信号和 COREFILE,再进入导出动作。下图把三种匹配入口、journal 条目和可用性字段放在同一个静态边界里,方便理解每个条件负责什么。

coredumpctl 的 PID、COMM、EXE 与 journal 条目和 COREFILE 的静态关系说明图
图1:结构说明图,查看 PID、COMM、EXE、journal 条目与 COREFILE 的静态关系;这不是终端截图,也不表示执行顺序。

先看 COREFILE,再决定能不能提取

coredumpctl info PID 会给出崩溃信号、时间、可执行文件、存储位置等详细信息。列表里的 COREFILE 状态是导出前最有价值的判断线索:present 表示当前用户可访问 core,journal 表示数据存放在 journal,truncated 表示没有完整保存,missing 表示曾经有文件但现在已经被删除,error 通常指访问失败,none 则表示没有保存 core。

# 查询指定 PID 的详细元数据;--no-pager 让结果直接返回到当前输出。
crash_pid=24680
coredumpctl --no-pager info "$crash_pid"

# 同一程序有多条记录时,先按时间窗口收窄,再查看详细信息。
coredumpctl --no-pager --since "2026-11-01 00:00:00" --until "2026-11-02 00:00:00" info my-worker

列表仍在而 core 已丢失并不矛盾。systemd-coredump 会把元数据写入 journal,而外部 core 文件还受保留策略、磁盘空间和权限影响。普通用户通常只能看到自己有权访问的 journal 内容;跨用户或系统服务排查时,若结果为空或 COREFILE 显示 error,应先确认读取 journal 和存储文件的权限。

用 --output 把指定 core 写入文件

确认记录后,再把导出动作和目标路径写明确。dump 默认把 core 写到标准输出;加上 --output=FILE 后,coredumpctl 将它写入指定文件。下面示例把目录权限收窄,避免 core 中可能包含的进程内存数据被其他本地用户读取。

# 建立专门的导出目录,并限制目录默认权限。
export_dir=/var/tmp/coredump-export
mkdir -p "$export_dir"
chmod 700 "$export_dir"

# 使用明确文件名保存指定 PID 的 core;不要把二进制内容打印到终端。
crash_pid=24680
core_file="$export_dir/my-worker-$crash_pid.core"
coredumpctl --output="$core_file" dump "$crash_pid"

# 导出完成后只查看文件元信息,不把 core 内容当作文本读取。
stat -- "$core_file"

这里的 stat 只是用于确认目标文件名和大小,不等于证明内容一定完整;完整性仍受 COREFILE 状态、处理上限和保存策略影响。若命令提示没有匹配记录、core 不可访问或写入目标失败,应保留原始错误,分别检查选择条件、权限和目标目录,而不是换一个 PID 盲目重试。

多次崩溃时,用时间和最新记录选对对象

同一个可执行文件可能在一次部署窗口内产生多条 core。-1 等价于反向排列后取一条最新记录;也可以用 --reverse -n 1 表达相同意图。若“最新”并不等于本次事故,还应配合 --since 和 --until,把搜索范围限制在明确的时间段。

# 只看指定程序在时间窗口内的最新一条记录。
export_dir=/var/tmp/coredump-export
core_file="$export_dir/my-worker-latest.core"

# -1 只选择匹配结果中最新的一条;仍要先确认它属于本次事故。
coredumpctl --since "2026-11-01 09:00:00" --until "2026-11-01 10:00:00" -1 info /usr/local/bin/my-worker

# 确认时间、PID 和 COREFILE 后,再用同一条件导出。
coredumpctl --since "2026-11-01 09:00:00" --until "2026-11-01 10:00:00" -1 --output="$core_file" dump /usr/local/bin/my-worker

关键取舍是“先确认,再导出”。如果只写程序路径和 --output,命令可能合法运行,但你未必知道它选中的哪一次崩溃。发生时间、PID、信号和 COREFILE 组成一组定位信息;不要只依赖文件名或程序名猜测。

导出的 core 怎样交给调试器

如果只是查看记录中的调用栈和环境信息,可以继续用 coredumpctl info PID。如果要让默认调试器处理匹配到的最后一条记录,可以使用 coredumpctl debug PID;如果需要把文件交给另一个环境或保留给后续分析,则使用上面的 --output 导出更合适。

# 直接让 coredumpctl 为指定 PID 选择调试器入口。
crash_pid=24680
coredumpctl debug "$crash_pid"

# 已经导出文件时,后续调试工具读取这个文件;路径只是占位示例。
core_file=/var/tmp/coredump-export/my-worker-24680.core
gdb /usr/local/bin/my-worker "$core_file"

调试器能否还原有意义的栈,还取决于可执行文件和调试符号是否匹配;导出 core 本身不会自动补齐符号。下图强调的是静态边界:dump 负责生成文件,info 负责提供元数据,gdb 把 core 文件作为调试输入,它们不是同一个动作。

coredumpctl dump、--output、core 文件、info 元数据与 gdb 调试输入的静态关系说明图
图2:关系说明图,查看导出接口、core 文件、元数据和 gdb 输入之间的关系;这不是运行结果截图。

常见状态应该怎样判断

现象先看什么判断边界
能列出记录但无法导出COREFILE、权限、存储路径journal 元数据存在,不保证 core 文件可读
同一程序出现多条记录时间、PID、信号和 --since/--until程序名只能缩小范围,不能独立完成选中
导出命令没有结果匹配条件和用户能看到的 journal 范围没有匹配记录会以失败状态结束
core 文件很大或不完整COREFILE 是否为 truncated,并查看 coredump 配置提取动作不能恢复没有保存的内存内容

在生产排障中,我会把“选中的记录”和“导出的文件”分开记录:前者包含时间、PID、信号和 COREFILE,后者包含导出路径和文件权限。这样即便后续调试失败,也能判断问题是在匹配、保存,还是符号与调试工具阶段。

只知道程序名,可以直接 dump 吗?

可以把程序名作为匹配条件,但不建议跳过 list 或 info。同名程序可能有多条记录,先确认时间、PID 和 COREFILE,再把同一个条件交给 dump。

为什么 journal 里有记录,导出的文件却不存在?

journal 条目和外部 core 文件的保留周期、权限与存储位置可能不同。遇到 missing、none 或 error 时,提取命令没有办法补回已经删除或未保存的完整 core。

导出前一定要用 root 吗?

不一定,取决于目标 journal 条目和 core 文件的访问权限。普通用户通常只能看到自己有权访问的内容;如果是系统服务或其他用户的崩溃,先按组织的权限策略申请必要访问,不要把权限错误误判成没有发生崩溃。

最小可靠配方可以记成三句话:用 info 确认目标,用 COREFILE 判断可用性,用 --output 保存指定 core。多次崩溃时再加时间窗口和最新记录选择,最后才把文件交给 gdb 或其他调试环境。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>