核心轉儲是進程意外終止時包含進程地址空間(內存)的文件。核心轉儲可以按需生成(例如由 debugger 生成),也可以在進程終止時自動生成。核心轉儲由內核在程序崩潰時觸發,並可能傳遞給輔助程序(如 systemd-coredump(8))進行進一步處理。普通用戶通常不會使用核心轉儲,但開發人員可以將其用作程序崩潰時的狀態快照,尤其是在故障難以可靠重現的情況下。
禁用自動核心轉儲
出於多種原因,用戶可能希望禁用自動核心轉儲:
- 性能:為占用內存大的進程生成核心轉儲會浪費系統資源並延遲內存清理。
- 磁碟空間:如果不壓縮,占用內存大的進程的核心轉儲占用的磁碟空間可能等於甚至大於該進程的內存占用空間。
- 安全性:核心轉儲雖然通常只有 root 可讀,但敏感數據(如密碼或加密密鑰)會在崩潰後寫入磁碟。
使用 sysctl
可以將 kernel.core_pattern
設置為空值以使 sysctl 不處理核心轉儲。請創建以下文件:
/etc/sysctl.d/50-coredump.conf
kernel.core_pattern=|/bin/false
要立即應用設置,請執行以下命令:
# sysctl -p /etc/sysctl.d/50-coredump.conf
使用 systemd
/usr/lib/sysctl.d/50-coredump.conf
文件定義了 systemd 的默認行為,該文件將kernel.core_pattern
設置為調用 systemd-coredump
,並在 /var/lib/systemd/coredump
為所有進程生成核心轉儲。請在 /etc/systemd/coredump.conf.d/
目錄中創建包含以下內容的配置以覆蓋 systemd-coredump
行為(參見 coredump.conf(5) § DESCRIPTION, [1]):
/etc/systemd/coredump.conf.d/custom.conf
[Coredump] Storage=none ProcessSizeMax=0
[Coredump]
部分名稱,否則該選項將被忽略。之後用 daemon-reload 重新加載 systemd 配置文件。
參見 systemd-coredump(8) § Disabling coredump processing。
使用 PAM 限制
通過 PAM 登錄的用戶,其最大核心轉儲大小由 limits.conf 定義的。用戶將其設置為零將完全禁用核心轉儲。[2]
/etc/security/limits.conf
* hard core 0
使用 ulimit
像是bash,zsh這樣的 命令行解釋器 中提供了內置的 ulimit 命令,這條命令可用於報告或設置 shell 和由 shell 啟動的進程的資源限制。詳見 bash(1) § SHELL BUILTIN COMMANDS 或 zshbuiltins(1) 。
在當前shell禁用核心轉儲:
$ ulimit -c 0
如果系統設置為使用 kernel.core_pattern
將核心轉儲通過管道傳遞到諸如 systemd-coredump 之類的程序中,那麼 Linux 內核本身會忽略 ulimit 設置(參見 core(5))。因此,是否遵循該設置取決於接收轉儲的程序(systemd-coredump 仍會遵循此設置)。
對於未使用 ulimit 設置的崩潰進程的程序,可以使用 dumpable
和 prctl(2) 來禁用特定進程的核心轉儲處理。
生成核心轉儲
要生成任意進程的核心轉儲,首先要 安裝 gdb包 軟體包。然後查找正在運行的進程的 PID,例如使用「『pgrep』」:
$ pgrep -f firefox
2071 firefox
關聯進程:
$ gdb -p 2071
在 (gdb)
提示下:
(gdb) generate-core-file Saved corefile core.2071 (gdb) quit
現在您有了一個名為 core.2071
的 coredump 文件。
核心轉儲文件去哪兒了?
kernel.core_pattern
內核模式 sysctl 決定自動核心轉儲的位置。默認情況下,核心轉儲將被發送到 systemd-coredump ,可以使用 /etc/systemd/coredump.conf
來定義其行為。默認下,所有的核心轉儲文件儲存在 /var/lib/systemd/coredump
(因為配置了 Storage=external
),它們被 zstd
壓縮(因為配置了 Compress=yes
)。此外,還可以配置存儲的各種大小限制。
/usr/lib/sysctl.d/50-coredump.conf
中配置了 kernel.core_pattern
的默認值,
如果遵循默認的 sysctl.d(5) 規則,該文件可能會被屏蔽或覆蓋。要從日誌中獲取核心轉儲,請參見 coredumpctl(1) 。
管理核心轉儲
使用 coredumpctl 查找相應的轉儲文件。請注意,普通用戶無需特殊權限即可運行 coredumpctl 來管理其進程的核心轉儲。
# coredumpctl list
清理核心轉儲
存儲在 /var/lib/systemd/coredump/
中的核心轉儲文件會被 systemd-tmpfiles --clean
自動清理,該命令由 systemd-tmpfiles-clean.timer
每天觸發。核心轉儲文件的默認保留時間為至少 3 天,具體配置可通過運行 systemd-tmpfiles --cat-config
查看。
分析核心轉儲
首先,您需要找到需要相關轉儲。可通過指定 PID
、可執行文件名稱、可執行文件路徑或 journalctl 謂詞來實現(詳見 coredumpctl(1) 和 journalctl(1) )。
要查看核心轉儲的詳細信息:
# coredumpctl info match
注意 「Signal」 行,它有助於確定崩潰原因。分析時,通常使用調試器(默認為 gdb(1) )檢查回溯:
# coredumpctl debug match
啟動 gdb 後,使用 bt
命令列印完整的回溯:
(gdb) thread apply all backtrace full
在許多情況下,輸出將包含問號作為缺失調試符號的占位符。如何獲取這些符號,請參閱 調試/獲取跟蹤數據 。
另見
- american fuzzy lop - 一個自動測試內核和程序的工具
- Filesystem fuzzing - LWN 有關測試文件系統錯誤的文章