2013-07-31 10 views
6

In seguito alla mia domanda su manually generating a core dump file, ho deciso di immergermi e sporcarmi le mani.Nota di core dump sezione

Sono in grado di creare la struttura di base del dump di base e ripristinare la memoria del mio programma morto nel core dump all'interno di una grande sezione LOAD. Quando eseguo il debug in GDB, le mie variabili sono tornate, nessun problema con questo. Ecco la parte difficile, come faccio a ottenere GDB per recuperare informazioni su dove si trovava il programma quando si è bloccato.

So che la sezione delle note del core dump contiene questa informazione (registri della cpu tra gli altri). Qui è ciò che un objdump -h dà per un "vero" 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 ... 

ho capito grazie a readelf che quelle reg sezioni contengono dati mappati da alcune strutture:

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) 

Qualcuno può darmi indicazioni su come è strutturata la sezione Note? Ho provato a scrivere direttamente quelle strutture nel mio file, non ha funzionato e ovviamente mi manca qualcosa qui. Ho guardato il Google Coredumper code e ne ho preso un po ', ma scrivere la sezione delle note non è così semplice e tutte le informazioni dettagliate su ciò che contiene esattamente e il suo formato sono benvenute.

Modifica # 1: dopo primo commento

ho capito il mio file Elf deve essere strutturato come segue:

  • Elf intestazione ElfW (Ehdr)
  • intestazioni di programma (Ehdr.e_phnum times ElfW (Phdr), qui ho usato fondamentalmente uno PT_NOTE e uno PT_LOAD header
  • Note sezioni:
      intestazione
    • di Sezione (ElfW (NHDR)) nome
    • di Sezione (.n_namesz lungo)
    • dati della Sezione (.n_descsz lungo)
  • sezione programma, che comprende tutta la memoria del mio programma

Poi dovrò mettere 3 record nota, uno per il prstatus, uno per prpsinfo e uno per la vettore ausiliario.

Questo sembra essere il modo corretto come readl mi dà un output simile a quello che ho ottenuto con il vero core dump.

Edit # 2: dopo aver ottenuto la corretta struttura

ora sto lottando con le diverse strutture che compongono i record di nota.

Ecco che cosa ottengo quando si esegue un eu-readelf --notes sul mio core dump:

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

Ecco che cosa ottengo quando si esegue lo stesso comando su discarica vero nucleo:

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 

Qualcuno ha qualche indizio o spiegazione sul motivo per cui i miei appunti non vengono letti correttamente? Ho pensato che potrebbe essere dovuto a offset errati, ma perché i record dovrebbero essere elencati correttamente?

Grazie!

+0

precisato la domanda per quanto riguarda le strutture contenute nei registri nota – d6bels

+0

(vecchia questione, ma può essere utile per gli altri) suggerisco di guardare i sorgenti del kernel che generano un coredump di serie: - codice di base: http: // LXR. free-electrons.com/source/fs/coredump.c - Parte specifica per ELF: http://lxr.free-electrons.com/source/fs/binfmt_elf.c#L1090 ​​ – patrickdepinguin

risposta

1

Qualcuno può darmi indicazioni su come è strutturata la sezione Note?

La sezione note è una concatenazione di record di nota di dimensioni variabili. Ogni record di nota inizia con la struttura ElfW(Nhdr), seguita dal nome (di dimensioni variabili) (di lunghezza .n_namesz, riempito in modo che la dimensione totale del nome sul disco sia divisibile per 4) e dati (di lunghezza .n_descsz, similmente riempiti).

+0

Ho modificato la domanda prendendo le tue informazioni in conto e precisi la mia domanda. Grazie. – d6bels

0

Dopo alcuni test ho capito le cose, rispondendo per chi cerca queste informazioni:

Qualcuno può confermare che sto nel modo giusto strutturare il mio file Elf in questo modo?

Sì.

Come GDB sta accettando il file, questo sembra essere il modo giusto di fare. I risultati mostrati da read -a mostrano la struttura corretta, buona finora.

non sono sicuro di dove dovrebbe definire i dati (nota & parti di programma) in mio file: c'è un ordine obbligatorio, o è compensato questo mio intestazioni di programma che definiscono dove i dati sono?

Gli offset assegnati a Phdr.p_offset devono indicare dove si trovano i dati nel file Elf. Iniziano dall'inizio del file.

Ad esempio:

Il p_offset per l'intestazione PT_NOTE programma dovrebbe essere fissata a sizeof(ElfW(Ehdr)) + ehdr.e_phnum*sizeof(ElfW(Phdr)). ehdr.e_phnum indica il numero di intestazione del programma presente nel file Elf.

Per l'intestazione del programma PT_LOAD, questo è un po 'più lungo, perché dovremo anche aggiungere la lunghezza di tutte le sezioni delle note. Per un core dump "standard" con un segmento nota containg NT_PRSTATUS, NT_PRPSINFO e NT_AUXV sezioni, offset per i dati PT_LOAD (Phdr.p_offset) sarà:

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) 
3

stava avendo stessi problemi qualche tempo fa con il mio progetto di convertire CRIU immagini in core dump. È completamente scritto in python (anche le strutture elf sono in ctype), quindi potrebbe essere usato come guida. Vedi https://github.com/efiop/criu-coredump .I.e.come tutto ciò che è strutturato può essere visto qui https://github.com/efiop/criu-coredump/blob/master/criu_coredump/core_dump.py.

+1

Vorrei tanto poterlo usare in passato, sembra fantastico. – d6bels