Раздел 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)