Файл ядра содержит команду, из которой он был создан. В идеале это будет включать полный путь к соответствующему исполняемому файлу. Например:
$ file core.29529
core.29529: ELF 64-bit LSB core file x86-64, version 1 (SYSV), SVR4-style, from '/bin/sleep 60'
Запуск ldd
в двоичном файле ELF покажет, от каких библиотек он зависит:
$ ldd /bin/sleep
linux-vdso.so.1 => (0x00007fff1d3ff000)
libc.so.6 => /lib64/libc.so.6 (0x0000003d3ce00000)
/lib64/ld-linux-x86-64.so.2 (0x0000003d3ca00000)
Итак, теперь я знаю исполняемый файл и библиотеки, необходимые для анализа дампа ядра.
Сложная задача - извлечь путь к исполняемому файлу из файла ядра. Там не кажется хорошим инструментом для чтения этого непосредственно. Данные кодируются в структуре prpsinfo (из /usr/include/sys/procfs.h
), и вы можете найти размер расположения данных, используя readelf
:
$ readelf -n core.29529
Notes at offset 0x00000468 with length 0x00000558:
Owner Data size Description
CORE 0x00000150 NT_PRSTATUS (prstatus structure)
CORE 0x00000088 NT_PRPSINFO (prpsinfo structure)
CORE 0x00000130 NT_AUXV (auxiliary vector)
CORE 0x00000200 NT_FPREGSET (floating point registers)
... так что теоретически можно написать фрагмент кода, чтобы извлечь командную строку из этой структуры и распечатать ее таким образом, чтобы упростить автоматизацию всего этого процесса. Конечно, вы можете просто проанализировать вывод file
:
$ file core.29529 | sed "s/.*from '\([^']*\)'/\1/"
/bin/sleep 60
Так что это все части. Вот отправная точка для того, чтобы собрать все это вместе:
#!/bin/sh
core=$1
exe=$(file $core | sed "s/.*from '\([^']*\)'/\1/" | awk '{print $1}')
libs=$(
ldd $exe |
awk '
/=> \// {print $3}
! /=>/ {print $1}
'
)
cat <<EOF | tar -cah -T- -f $1-all.tar.xz
$libs
$exe
EOF
Для моего примера, если я назову этот сценарий packcore
и запустим его в основном файле из команды sleep
, я получу следующее:
$ packcore core.29529
tar: Removing leading `/' from member names
$ tar -c -f core.29529-all.tar.xz
core.29529
lib64/libc.so.6
lib64/ld-linux-x86-64.so.2
bin/sleep
В нынешнем виде этот скрипт довольно хрупкий; Я сделал много предположений о выводе из ldd
, основываясь только на этом примере вывода.