Раздел Core Примечание сброса
после моего вопроса о ручная генерация файла дампа ядра, я решил нырнуть в него и испачкать руки.
Я могу построить основную структуру дампа ядра и вернуть память моей мертвой программы обратно в дамп ядра в разделе большой нагрузки. При отладке в GDB мои переменные возвращаются, никаких проблем с этим. Вот сложная часть, как я могу получить GDB для получения информации о том, где была программа, когда она разбилась.
I знайте, что раздел Примечание дампа ядра содержит эту информацию (регистры cpu среди других). Вот что такое objdump-h дает для" реального " дампа ядра:
core.28339: file format elf32-i386
Sections:
Idx Name Size VMA LMA File off Algn
0 note0 000001e8 00000000 00000000 000000f4 2**0
CONTENTS, READONLY
1 .reg/28339 00000044 00000000 00000000 00000150 2**2
CONTENTS
2 .reg 00000044 00000000 00000000 00000150 2**2
CONTENTS
3 .auxv 000000a0 00000000 00000000 0000023c 2**2
CONTENTS
4 load1a 00001000 08010000 00000000 00001000 2**12
CONTENTS, ALLOC, LOAD, READONLY, CODE
.. other load sections ...
Я понял, спасибо readelf выступает что те .разделы reg содержат данные, отображаемые из некоторых структур:
Notes at offset 0x000000f4 with length 0x000001e8:
Owner Data size Description
CORE 0x00000090 NT_PRSTATUS (prstatus structure)
CORE 0x0000007c NT_PRPSINFO (prpsinfo structure)
CORE 0x000000a0 NT_AUXV (auxiliary vector)
может кто-нибудь дать мне указания о том, как структурирован раздел Notes ? Я попытался написать непосредственно эти структуры в свой файл, это не сработало, и я очевидно, здесь чего-то не хватает. Я посмотрел на Google Coredumper код и взял некоторые его биты, но написание раздела заметки не так просто, и любая подробная информация о том, что он точно содержит и его формат приветствуется.
Edit #1: следующий 1-й комментарий
Я понял, что мой файл Elf должен быть структурирован следующим образом:
- ELF заголовок ElfW (Ehdr)
- заголовки программ (Ehdr.e_phnum times ElfW (Phdr)), здесь я в основном использовал один pt_note и один pt_load заголовки
- разделы Записки :
- заголовок раздела (ElfW (Nhdr))
- название раздела (.n_namesz long)
- данные раздела (.n_descsz long)
- раздел Программы, содержащий всю память моей программы
тогда мне придется поставить 3 записи заметок, один для prstatus, для prpsinfo и для вспомогательный вектор.
Это, кажется, правильный путь как readelf выступает дает мне аналогичный выход, как то, что я получил выше с реальным дампом ядра.
Edit #2: после получения правильной структуры
теперь я борюсь с различными структурами, составляющими записи заметок.
вот что я получаю при запуске ЕС-readelf -- Примечания на моем дампе :
Note segment of 540 bytes at offset 0x74:
Owner Data size Type
CORE 336 PRSTATUS
CORE 136 PRPSINFO
CORE 8 AUXV
NULL
вот что я получаю при выполнении той же команды на реальном дампе ядра:
Note segment of 488 bytes at offset 0xf4:
Owner Data size Type
CORE 144 PRSTATUS
info.si_signo: 11, info.si_code: 0, info.si_errno: 0, cursig: 11
sigpend: <>
sighold: <>
pid: 28339, ppid: 41446, pgrp: 28339, sid: 41446
utime: 0.000000, stime: 0.000000, cutime: 0.000000, cstime: 0.000000
orig_eax: -1, fpvalid: 0
ebx: -1 ecx: 0 edx: 0
esi: 0 edi: 0 ebp: 0xffb9fcbc
eax: -1 eip: 0x08014b26 eflags: 0x00010286
esp: 0xffb9fcb4
ds: 0x002b es: 0x002b fs: 0x0000 gs: 0x0000 cs: 0x0023 ss: 0x002b
CORE 124 PRPSINFO
state: 0, sname: R, zomb: 0, nice: 0, flag: 0x00400400
uid: 9432, gid: 6246, pid: 28339, ppid: 41446, pgrp: 28339, sid: 41446
fname: pikeos_app, psargs: ./pikeos_app
CORE 160 AUXV
SYSINFO: 0xf7768420
SYSINFO_EHDR: 0xf7768000
HWCAP: 0xbfebfbff <fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe>
PAGESZ: 4096
CLKTCK: 100
PHDR: 0x8010034
PHENT: 32
PHNUM: 2
BASE: 0
FLAGS: 0
ENTRY: 0x80100be
UID: 9432
EUID: 9432
GID: 6246
EGID: 6246
SECURE: 0
RANDOM: 0xffb9ffab
EXECFN: 0xffba1feb
PLATFORM: 0xffb9ffbb
NULL
есть ли у кого-нибудь какие-либо подсказки или объяснения о том, почему мои записи заметок не читаются должным образом ? Я думал, что это может быть из-за неправильных смещений, но тогда почему записи будут правильно перечислены ?
спасибо !
3 ответов
некоторое время назад у меня были такие же проблемы с моим проектом преобразования изображений CRIU в основные дампы. Он полностью написан на python (даже структуры elf находятся в ctypes), поэтому его можно использовать в качестве руководства. См.https://github.com/efiop/criu-coredump .Т. е. как все структурировано, можно было увидеть здесь https://github.com/efiop/criu-coredump/blob/master/criu_coredump/core_dump.py .
может кто-нибудь дать мне указания о том, как структурирован раздел Notes?
раздел Примечания представляет собой конкатенацию записей заметок переменного размера. Каждая запись заметки начинается с ElfW(Nhdr)
структура, за которой следует (переменный размер) имя (длины .n_namesz
, проложенный таким образом, общий размер имени на диске делится на 4) и данные (длины .n_descsz
, так же мягкий).
после некоторых тестов я понял, что, отвечая за всех, кто ищет эту информацию:
может ли кто-нибудь подтвердить, что я иду правильным путем, структурируя мой файл Elf таким образом ?
да.
поскольку GDB принимает файл,это кажется правильным способом. Результаты, показанные readelf выступает -это покажите правильную структуру, хорошую до сих пор.
Я не уверен, о том, где следует заложить данные (примечание и разделы программы) в мой файл : существует ли обязательный порядок или это смещение заголовков моей программы, которое определяет, где находятся данные ?
смещения, данные Phdr.p_offset
должен указывать, где данные лежат в файле Elf. Они начинаются с самого начала файла.
например :
p_offset для PT_NOTE
заголовок программы должен быть установлен на sizeof(ElfW(Ehdr)) + ehdr.e_phnum*sizeof(ElfW(Phdr))
. ehdr.e_phnum
быть номером заголовка программы, присутствующим в Elf файл.
на PT_LOAD
заголовок программы, это немного дольше, потому что нам также придется добавить длину всех разделов заметки. Для" стандартного " дампа ядра с сегментом заметки containg NT_PRSTATUS
, NT_PRPSINFO
и NT_AUXV
разделы, смещение для данных PT_LOAD (Phdr.p_offset
) составит :
sizeof(ElfW(Ehdr)) + ehdr.e_phnum*sizeof(ElfW(Phdr))
+ sizeof(ElfW(Nhdr)) + sizeof(name_of_section) + sizeof(struct prstatus)
+ sizeof(ElfW(Nhdr)) + sizeof(name_of_section) + sizeof(struct prpsinfo)
+ sizeof(ElfW(Nhdr)) + sizeof(name_of_section) + sizeof(struct auxv_t)