Em um sistema ELF , um arquivo principal é quase certamente um arquivo ELF válido.
$ 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
[...]
Um número específico de "notas" da plataforma é adicionado a um segmento NOTES para que um depurador possa ser encontrado, por exemplo, para Solaris, veja o núcleo (4) , e você notará o NT_UTSNAME
estrutura que contém a estrutura de dados do uname(2)
syscall. elfdump -n
é a maneira de ler isso, mas até onde sei, o Solaris é o único SO que faz isso (e eu suspeito que apenas o Solaris 11 elfdump
funcione como esperado).
Uma maneira simples, embora um pouco complicada e não garantida, é tentar pescar as variáveis HOST
ou HOSTNAME
(definidas por alguns scripts e shells de inicialização, bash
pelo menos define HOSTNAME
) fora do ambiente de despejo de núcleo. Você pode fazer isso com gdb
, embora precise do binário original:
$ 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",
[...]
Este imprime um trecho de strings do environ
símbolo . Embora seja um hack horrível, o strings | grep HOSTNAME=
também pode funcionar.
Portanto, a resposta curta para " Existe uma maneira de descobrir qual host gerou o arquivo principal " é: não é fácil, e não confiavelmente no Linux.
FWIW, o código relevante do coredump no Linux está em fs/binfmt_elf.c
, e existe um gancho para permitir "anotações" extras por meio de ARCH_HAVE_EXTRA_ELF_NOTES
, atualmente usado apenas no PowerPC.
Um plano melhor é usar o sysctl para definir o nome do arquivo principal em cada cliente , como sugerido por @jlliagre:
sysctl kernel.core_pattern="%h-%t-%e.core"
( sysctl
e pesquisa em /proc
são equivalentes aqui, eu prefiro sysctl
, pois as alterações podem ser mantidas documentadas em /etc/sysctl.conf
e também são usadas em sistemas * BSD.)