本文译者是一位开源理念的坚定支持者,所以本文虽然不是软件,但是遵照开源的精神发布。
本文译者十分愿意与他人分享劳动成果,如果你对我的其他翻译作品或者技术文章有兴趣,可以在如下位置查看现有的作品集:
由于译者水平有限,因此不能保证译文内容准确无误。如果你发现了译文中的错误(哪怕是错别字也好),请来信指出,任何提高译文质量的建议我都将虚心接纳。
systemd-coredump, systemd-coredump.socket, systemd-coredump@.service — 获取、保存、处理内存转储
/usr/lib/systemd/systemd-coredump
/usr/lib/systemd/systemd-coredump
--backtrace
systemd-coredump@.service
systemd-coredump.socket
systemd-coredump@.service
是一个系统服务,
它能从操作系统内核中获取内存转储,并能对获取到的数据进行各种处理。该服务的功能实际由 systemd-coredump
可执行程序实现,该程序被先后调用两次:第一次被操作系统内核作为内存转储处理器调用;
第二次被 systemd-coredump@.service
服务调用,
用于将获取到的数据写入文件或日志中。
当操作系统内核调用 systemd-coredump 来处理内存转储时,
它将以特权模式运行,并连接到
systemd-coredump.socket
单元创建的套接字上,接着再派生一个非特权模式的
systemd-coredump@.service
实例来处理所获取的内存转储。可见,
systemd-coredump.socket
与 systemd-coredump@.service
是为了实现对内存转储进行统一管理而
专门设置的辅助单元。
内存转储既可以保存到日志中,也可以保存到单独的文件中, 以便于将来被例如 gdb(1) 这样的工具做进一步的分析和处理。
默认情况下,systemd-coredump 会把内存转储事件以及可能存在的回溯(backtrace)保存到日志中,
同时把内存转储自身的数据(内存镜像)保存到外部的
/var/lib/systemd/coredump/
目录中。
进程在接收到信号后的行为 取决于某些特定的因素(详见 core(5) 手册), 特别需要注意的是,仅在相关系统资源充足且未超出资源限制的前提下,才会进行内存转储操作。
如果在调用 systemd-coredump 时使用了
--backtrace
选项,那么在 systemd-coredump
的标准输入(STDIN)上必须存在一条符合
Journal Export Format
格式的日志,这条日志必须包含一个 MESSAGE=
字段,
并且任何其他元数据字段在调用者看来都必须是合情合理的。 systemd-coredump
将会按照它自己从内核中接收内存转储的方式,在这条日志中添加额外的元数据字段。
注意,在这种模式下,内存转储将不会保存在日志中。
对于被 systemd 进程启动的程序来说,可以通过
LimitCore=
指令来设置资源限制,详见
systemd.exec(5) 手册。
为了被操作系统内核用作内存转储处理器,
systemd-coredump 必须被配置到
sysctl(8)
的 kernel.core_pattern
变量中。此变量的语法详见
core(5) 手册。
systemd 安装的 /usr/lib/sysctl.d/50-coredump.conf
文件就依据该语法配置了
kernel.core_pattern
变量的默认值。
如果想要使用不同的配置,那么可以根据
sysctl.d(5)
规则来屏蔽或覆盖此文件。修改 sysctl 配置之后,必须要刷新内核参数才能真正生效,
详见
sysctl(8)
与
systemd-sysctl.service(8) 手册。
如果想要以 --backtrace
模式运行,那么必须在发送端安装一个适当的回溯处理程序(backtrace
handler)。例如,对于
python(1) 来说,
这就意味着必须安装一个 sys.excepthook
钩子,详见
systemd-coredump-python 手册。
systemd-coredump 自身的行为由
/etc/systemd/coredump.conf
配置文件与对应的
/etc/systemd/coredump.conf.d/*.conf
配置片段共同决定,详见
coredump.conf(5) 手册。
因为每发生一次内核转储都会调用一个 systemd-coredump 新实例,
所以,这些配置文件的变化将会立即体现在下一次内核转储调用调用的新实例上。
内核转储文件所占用的磁盘资源受两种不同方式的约束:
(1)占用磁盘空间的大小受 /etc/systemd/coredump.conf
配置文件以及对应的配置片段的约束;
(2)占用磁盘时间的长短受 systemd-tmpfiles 配置的约束(对应的配置文件默认位于
/usr/lib/tmpfiles.d/systemd.conf
)。
如果想要避免 systemd-coredump 在处理内核转储时对系统资源的大量占用, 那么可以将
Storage=none ProcessSizeMax=0
写入 coredump.conf(5) 中。
存储在日志中的数据,可以按照常规使用 journalctl(1) 进行查看。 coredumpctl(1) 可以用于提取已保存的内存转储,而不必关心实际的保存方式与位置。 如果想要显示相关信息或做进一步处理,可以将输出内容管道传递给例如 gdb 这样的工具。