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

Linux core_pattern 管道处理程序怎么接收崩溃信息

来源:17golang原创

时间:2026-10-05 03:17:21 132浏览 收藏

Linux 的 core_pattern 管道处理程序接收崩溃信息,靠的是两条并行通道:内核把 core dump 的字节流写入处理程序的标准输入,把模板中的 %P、%u、%g、%s、%t、%c、%e 展开后作为命令行参数传入。处理程序不是去某个固定文件名读取 core,而是持续读取 stdin;PID、UID、GID、信号和进程名等定位信息则从 argv 取得。

要点速览
  • core_pattern 以 | 开头时,管道后必须紧跟处理程序的绝对路径。
  • 标准输入是 core 字节流,命令行参数是内核展开的崩溃元数据,两者不要混用。
  • 处理程序通常以 root 身份、初始命名空间运行;要访问崩溃进程的 /proc 信息,优先传入 %P。
  • core_pipe_limit=0 允许并发捕获但不保证等待处理程序,生产环境应按处理能力设置上限。

core_pattern 管道到底把什么交给处理程序

当 /proc/sys/kernel/core_pattern 的第一个字符是竖线时,竖线后面的内容会被解释为用户态程序的命令行。内核不再把转储直接写成当前目录里的 core 文件,而是启动这个程序,并把转储内容接到它的标准输入。

通道数据来源典型内容处理方式
标准输入 stdin内核生成的 core dump二进制字节流循环读取并写入受控存储或转发给分析服务
命令行 argvcore_pattern 模板展开PID、UID、GID、信号、时间、大小限制、进程名用于命名、索引和定位,不当作 core 内容读取
/proc/崩溃进程的内核视图cwd、comm、status 等信息仅在等待保证与权限条件满足时按需读取
Linux core_pattern 管道中崩溃进程、内核、标准输入 core 字节流、argv 元数据与 proc PID 信息的静态关系图
图1:core_pattern 管道的输入通道说明图;标准输入承载 core 字节流,argv 与 proc PID 负责提供定位元数据,不是运行截图。

最小配置:用绝对路径接收 core 字节流

先用临时配置确认管道形态。下面的参数把 PID、真实 UID/GID、触发信号、时间、进程 core 大小软限制和可执行文件名传给处理程序:

# 临时把崩溃转储交给固定路径的处理程序
sudo sysctl -w 'kernel.core_pattern=|/usr/local/sbin/core-handler %P %u %g %s %t %c %e'

# 查看当前模板,确认首字符确实是竖线
cat /proc/sys/kernel/core_pattern

# 并发崩溃较多时限制同时运行的管道处理程序数量
sudo sysctl -w kernel.core_pipe_limit=4

处理程序路径必须是绝对路径,并且紧跟在 | 后面。管道程序由内核在初始命名空间启动,不会自动继承崩溃进程的当前工作目录、root 目录或 mount namespace;如果要检查崩溃进程的上下文,应使用传入的 %P 去访问对应的 /proc/。

确认逻辑稳定后再持久化,例如写入 /etc/sysctl.d/50-core-handler.conf,然后由系统的 sysctl 机制加载。不要把可执行文件名直接拼成目录名:%e 是可控的进程标识,应该只用于元数据或经过严格清洗的文件名字段。

处理程序如何同时读取 stdin 和 argv

处理程序的核心逻辑很短:启动时检查参数数量,把 argv 保存为元数据,再从二进制标准输入持续复制到一个预先创建、权限受控的文件。下面是示意实现,重点是读取方式,不代表已经在某台主机执行过。

#!/usr/bin/env python3
import shutil
import sys
from pathlib import Path

# argv[1:] 对应 core_pattern 中的 %P %u %g %s %t %c %e
if len(sys.argv) 

这里的 core_limit 只是崩溃进程的软限制值,不等于最终一定写出的字节数。管道模式下,内核不会用 RLIMIT_CORE 限制这次传输;真正的存储上限、保留周期和失败重试应由处理程序自己设计。

接收不到信息时先查四个边界

  1. 模板是否被 systemd 接管。如果 core_pattern 类似 |/usr/lib/systemd/systemd-coredump %P %u %g %s %t %c %e,崩溃信息先交给 systemd-coredump,而不是自定义程序;此时应使用 coredumpctl 查询,或明确配置覆盖关系。
  2. 处理程序是否太慢或不退出。core_pipe_limit 控制可以并行交给用户态处理程序的崩溃数。超过上限时,后续转储会被跳过并写入内核日志;设置为 0 表示并发不设上限,但不保证处理程序还能访问 /proc/。
  3. 权限和安全策略是否允许读取。管道程序通常以 root 和初始命名空间运行,但 SELinux 等 LSM 仍可能阻止它访问崩溃进程的细节。存储目录应由 root 控制,不能把进程名或 PID 直接当作未校验路径。
  4. 确认输入不是“文件路径”。处理程序若只读取 argv 而没有消费 stdin,会让 core 字节流无人处理;若只读 stdin 而忘记传入 %P,后续很难把文件和崩溃进程对应起来。
Linux core_pattern 管道的绝对路径、模板参数、core_pipe_limit、systemd-coredump 与权限边界静态关系图
图2:管道处理程序的配置边界说明图;它把模板参数、并发限制、systemd 接管和命名空间权限放在同一张静态关系图中,不是运行结果截图。

常见问题

管道处理程序能从命令行参数拿到 core 文件内容吗?

不能。argv 只有模板展开后的字符串,core 内容在标准输入中,必须从 sys.stdin.buffer 或等价的二进制文件描述符读取。

为什么处理程序必须写绝对路径?

内核按初始命名空间解释处理程序路径,不采用崩溃进程的当前目录和 mount namespace。绝对路径能避免工作目录不同导致的找不到程序问题。

core_pipe_limit 设置越大越好吗?

不是。值越大,处理程序和磁盘可能同时承受更多输入;值为 0 还取消了等待保证。应按处理速度、磁盘容量和允许丢弃的故障量设置,并观察内核日志。

已经配置了自定义处理程序,为什么仍然看不到它的文件?

先检查 core_pattern 是否被 systemd-coredump 覆盖,再检查处理程序是否可执行、存储目录权限是否正确,以及 LSM 是否拦截了访问。不要先把问题归因于 %e 或文件名模板。

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