如何確定哪個主機生成了核心文件?
我有一個設置,其中幾台機器通過 NFS 共享相同的文件系統。通過排隊系統處理作業可以送出給幾台電腦(具有不同的屬性)。
有時,作業會崩潰並留下一個核心文件(名稱類似於
core.1234
)。有沒有辦法找出哪個主機生成了該核心文件?它的主機名是什麼?
(這是在 Linux 64 位上,如果有區別的話)。
在ELF系統上,核心文件幾乎可以肯定是有效的 ELF 文件。
$ readelf -a core ELF Header: Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 Class: ELF32 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: CORE (Core file) Machine: Intel 80386 [...]
將特定於平台數量的“註釋”添加到 NOTES 段中,以便調試器可以找到它的方式,例如對於 Solaris,請參見core(4),您會注意到包含來自系統呼叫
NT_UTSNAME
的資料結構的結構。是閱讀它的方式,但據我所知,Solaris 是唯一可以執行此操作的作業系統(我懷疑只有 Solaris 11可以按預期工作)。uname(2)``elfdump -n``elfdump
一個簡單但有點繁瑣且沒有保證的方法是嘗試將
HOST
orHOSTNAME
變數(由一些啟動腳本和 shell 設置,bash
至少設置HOSTNAME
)從核心轉儲環境中取出。您可以使用 執行此操作gdb
,但您需要原始二進製文件:$ gdb /usr/bin/sleep core [... snip ...] (gdb) print (char ***) &environ $1 = (char ***) 0x600bf8 (gdb) print $1[0][0]@10 $2 = {0x7fffffffd9c9 "HOST=myhostname", 0x7fffffffd9d9 "TERM=screen", 0x7fffffffd9e5 "SHELL=/bin/csh", [...]
這會從符號列印一大塊字元串
environ
。雖然這是一個可怕的黑客,但strings | grep HOSTNAME=
也可能會奏效。因此,對“有沒有辦法找出哪個主機生成了該核心文件”的簡短回答是:不容易,而且在 Linux 上也不可靠。
FWIW,Linux 上的相關 coredump 程式碼在 中
fs/binfmt_elf.c
,並且有一個鉤子允許通過 的方式進行額外的“註釋”ARCH_HAVE_EXTRA_ELF_NOTES
,目前僅在 PowerPC 上使用。)正如@jlliagre 所建議的那樣,一個更好的計劃是使用 sysctl 在每個客戶端上設置核心文件名:
sysctl kernel.core_pattern="%h-%t-%e.core"
(
sysctl
在/proc
這裡搜尋是等價的,我更喜歡,sysctl
因為更改可以保存在文件中,/etc/sysctl.conf
並且它也用於 *BSD 系統。)