Core dump note section

6

Following my question about manually generating a core dump file, I decided to dive into it and get my hands dirty.

I am able to build the basic core dump structure and get my dead program's memory back into the core dump within a big LOAD section. When debugging in GDB, my variables are back, no problem with that. Here comes the tricky part, how do I get GDB to retrieve information about where the program was when it crashed.

I know that the note section of the core dump contains this information (cpu registers among others). Here is what a objdump -h gives for a "real" core dump :

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 ...

I figured out thanks to readelf that those .reg sections contain data mapped from some structures :

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)

Can someone give me directions on how is structured the Notes section ? I tried writing directly those structures to my file, it did not work and I am obviously missing something here. I looked at the Google Coredumper code and took some bits of it, but writing the note section is not that simple and any detailed information about what it exactly contains and its format are welcomed.

Edit #1 : following 1st comment

I figured out my Elf file should be structured as follows :

  • Elf header ElfW(Ehdr)
  • Program headers (Ehdr.e_phnum times ElfW(Phdr)), here i basically used one PT_NOTE and one PT_LOAD headers
  • Note sections :
    • Section's header (ElfW(Nhdr))
    • Section's name (.n_namesz long)
    • Section's data (.n_descsz long)
  • Program section containing all my program's memory

Then i will have to put 3 note records, one for the prstatus, one for prpsinfo and one for the auxiliary vector.

This seems to be the right way as readelf gives me a similar output as what I got above with the real core dump.

Edit #2 : after getting the correct structure

I am now struggling with the different structures composing the note records.

Here is what I get when running a eu-readelf --notes on my core dump :

Note segment of 540 bytes at offset 0x74:
  Owner          Data size  Type
  CORE                 336  PRSTATUS
  CORE                 136  PRPSINFO
  CORE                   8  AUXV
    NULL

Here is what I get when running the same command on the real core dump :

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

Does someone have any clue or explanations about why my note records are not read properly ? I thought it might be due to incorrect offsets, but then why would the records be correctly listed ?

Thanks !

gdb
elf
coredump
asked on Stack Overflow Jul 31, 2013 by d6bels • edited May 23, 2017 by Community

3 Answers

4

Was having same troubles some time ago with my project of converting CRIU images into core dumps. It is fully written in python(even elf structures are in ctypes), so it could be used as a guide. See https://github.com/efiop/criu-coredump .I.e. how everything is structured could be seen here https://github.com/efiop/criu-coredump/blob/master/criu_coredump/core_dump.py .

answered on Stack Overflow Sep 27, 2015 by Ruslan Kuprieiev
1

Can someone give me directions on how is structured the Notes section?

The notes section is a concatenation of variable-sized note records. Each note record begins with ElfW(Nhdr) structure, followed by (variable sized) name (of length .n_namesz, padded so total size of name on disk is divisible by 4) and data (of length .n_descsz, similarly padded).

answered on Stack Overflow Jul 31, 2013 by Employed Russian • edited Jul 31, 2013 by Employed Russian
1

After some tests I figured things out, answering for anyone looking for this information :

Can someone confirm I am going the right way structuring my Elf file this way ?

Yes.

As GDB is accepting the file, this seems to be the right way of doing. Results shown by readelf -a show the correct structure, good so far.

I am not sure about where should lay the data (note & program sections) into my file : is there a mandatory order, or is this my program headers offset that define where the data is ?

Offsets given to Phdr.p_offset should point where the data lays in the Elf file. They start at the very beginning of the file.

For example :

The p_offset for the PT_NOTE program header should be set at sizeof(ElfW(Ehdr)) + ehdr.e_phnum*sizeof(ElfW(Phdr)). ehdr.e_phnum being the number of program header present in the Elf file.

For the PT_LOAD program header, this is a bit longer, cause we will also have to add length of all the note sections. For a "standard" core dump with a note segment containg NT_PRSTATUS, NT_PRPSINFO and NT_AUXV sections, offset for the PT_LOAD data (Phdr.p_offset) will be :

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)
answered on Stack Overflow Aug 1, 2013 by d6bels

User contributions licensed under CC BY-SA 3.0