elf - Get the address that caused segmentation fault from core dump using C -
i trying write c program can parse core dump files. question is, how can address caused core dump in c? know 1 can address using gdb answer:
how can gdb tell me address caused segfault?
but directly retrieve address in c. information highly appreciated. thanks!
notice: know how parse core dump elf. don't know how address caused segfault.
my question is, how can address caused core dump in c?
short answer:
there 2 ways interpret question.
what address of faulting instruction?
what address out of bounds?
elf core dumps keep of meta information in notes, stored in note segment. notes of different types.
to answer #1, need grab registers. @ elf header find program header table. walk program header table find note table (type pt_note). walk note table find note of type nt_prstatus. payload of note struct elf_prstatus
, can found in linux/elfcore.h. 1 of fields of struct of general purpose registers. grab %rip , done.
for #2, similar. time looking note of type nt_siginfo. payload of note siginfo_t structure defined in signal.h. applicable signals (sigill, sigfpe, sigsegv, sigbus), field si_addr contain address tried access couldn't.
more information below. in example core dump, rip 0x400560, instruction address tried illegal access. displayed rest of general purpose registers.
the memory program tried access @ 0x03. displayed rest of signal information.
the long answer:
i think bfd has 25 years of cruft on it, wouldn't use dump contents of core file on linux box. maybe if had write kind of general purpose code needs work bunch of formats, i'm not sure that's how go today.
the elf spec pretty written , not hard walk through tables of program headers or section headers needed. of process meta information in core file contained in set of notes in pt_note program segment can parsed out in few lines of straight c code.
i wrote little program grab registers out of x86_68 core file , print of meta data. put on github. logic getting note payload in function:
void *get_note(void *vp, int nt_type){ elf64_ehdr *eh=vp; for(int i=0; i<eh->e_phnum; ++i){ elf64_phdr *ph=(vp+eh->e_phoff+i*eh->e_phentsize); if(ph->p_type!=pt_note){ continue; } void *note_table=(vp + ph->p_offset); void *note_table_end=(note_table+ph->p_filesz); elf64_nhdr *current_note=note_table; while(current_note<(elf64_nhdr *)note_table_end){ void *note_end=current_note; note_end += 3*sizeof(elf64_word); note_end += roundup8(current_note->n_namesz); if(current_note->n_type==nt_type){ return note_end; } note_end += roundup8(current_note->n_descsz); current_note=note_end; } } return 0; }
the function handed pointer elf file , note type , returns pointer payload of associated note, if exists. various possible note types in elf.h. note types see in core files on machine are:
#define nt_prstatus 1 /* contains copy of prstatus struct */ #define nt_fpregset 2 /* contains copy of fpregset struct */ #define nt_prpsinfo 3 /* contains copy of prpsinfo struct */ #define nt_auxv 6 /* contains copy of auxv array */ #define nt_x86_xstate 0x202 /* x86 extended state using xsave */ #define nt_siginfo 0x53494749 /* contains copy of siginfo_t, size might increase */ #define nt_file 0x46494c45 /* contains information mapped files */
most of these structures in headers under /usr/include/linux. xsave structure couple kb of floating point information described in ch 13 of intel manual. has sse, avx, , mpx, registers in it.
the nt_file payload doesn't seem have associated struct in header, described in kernel comment (fs/binfmt_elf.c):
/* * format of nt_file note: * * long count -- how many files mapped * long page_size -- units file_ofs * array of [count] elements of * long start * long end * long file_ofs * followed count filenames in ascii: "file1" nul "file2" nul... */
the changes parsing elf file 32 bit system pretty trivial. use corresponding elf32_xxx structures , round 4 instead of 8 variable sized fields.
i've been adding stuff little program last couple of days. file header, segment headers, general registers, program status, program info , backtrace. i'll add support rest of notes time. here current output:
$ ./read_pc -biprst core general registers: r15 0x000000000000000000 r14 0x000000000000000000 r13 0x0000007ffc20d36a50 r12 0x000000000000400430 rbp 0x0000007ffc20d36950 rbx 0x000000000000000000 r11 0x000000000000000246 r10 0x000000000000000000 r9 0x000000000000000002 r8 0x000000000000000000 rax 0x000000000000000003 rcx 0x00000000007ffffffe rdx 0x0000007f5817523780 rsi 0x000000000000000001 rdi 0x000000000000000001 ss 0x00000000000000002b rip 0x000000000000400560 cs 0x000000000000000033 eflags 0x000000000000010246 rsp 0x0000007ffc20d36950 fs_base 0x0000007f5817723700 gs_base 0x000000000000000000 ds 0x000000000000000000 es 0x000000000000000000 fs 0x000000000000000000 gs 0x000000000000000000 orig_rax 0x00ffffffffffffffff program status: signo 11 signal code 0 errno 0 cursig 11 sigpend 000000000000000000 sigheld 000000000000000000 pid 27547 ppid 26600 pgrp 27547 sid 26600 utime: 0.000000 stime 0.000000 cutime: 0.000000 cstime 0.000000 fpvalid: 1 signal information: signo: 11 errno 0 code 1 addr 0x3 addr_lsb 0 addr_bnd ((nil), (nil)) process information: state 0 (r) zombie 0 nice 0 flags 0x400600 uid 1000 gid 1000 pid 27547 ppid 26600 pgrp 27547 sid 26600 fname: foo args: ./foo backtrace: rip = 0x000000000000400560 rip = 0x000000000000400591 rip = 0x0000000000004005a1 program headers: type offset virt addr physaddr filesiz memsize flags align note 0x00000000000004a0 0x0000000000000000 0000000000000000 0x0000000000000b98 0x0000000000000000 0x000000 load 0x0000000000002000 0x0000000000400000 0000000000000000 0x0000000000001000 0x0000000000001000 r x 0x001000 load 0x0000000000003000 0x0000000000600000 0000000000000000 0x0000000000001000 0x0000000000001000 x 0x001000 load 0x0000000000004000 0x0000000000601000 0000000000000000 0x0000000000001000 0x0000000000001000 wx 0x001000 load 0x0000000000005000 0x00000000018bf000 0000000000000000 0x0000000000021000 0x0000000000021000 wx 0x001000 load 0x0000000000026000 0x00007f581715e000 0000000000000000 0x0000000000001000 0x00000000001c0000 r x 0x001000 load 0x0000000000027000 0x00007f581731e000 0000000000000000 0x0000000000000000 0x00000000001ff000 0x001000 load 0x0000000000027000 0x00007f581751d000 0000000000000000 0x0000000000004000 0x0000000000004000 x 0x001000 load 0x000000000002b000 0x00007f5817521000 0000000000000000 0x0000000000002000 0x0000000000002000 wx 0x001000 load 0x000000000002d000 0x00007f5817523000 0000000000000000 0x0000000000004000 0x0000000000004000 wx 0x001000 load 0x0000000000031000 0x00007f5817527000 0000000000000000 0x0000000000001000 0x0000000000026000 r x 0x001000 load 0x0000000000032000 0x00007f5817722000 0000000000000000 0x0000000000003000 0x0000000000003000 wx 0x001000 load 0x0000000000035000 0x00007f581774a000 0000000000000000 0x0000000000002000 0x0000000000002000 wx 0x001000 load 0x0000000000037000 0x00007f581774c000 0000000000000000 0x0000000000001000 0x0000000000001000 x 0x001000 load 0x0000000000038000 0x00007f581774d000 0000000000000000 0x0000000000001000 0x0000000000001000 wx 0x001000 load 0x0000000000039000 0x00007f581774e000 0000000000000000 0x0000000000001000 0x0000000000001000 wx 0x001000 load 0x000000000003a000 0x00007ffc20d16000 0000000000000000 0x0000000000022000 0x0000000000022000 wx 0x001000 load 0x000000000005c000 0x00007ffc20d9c000 0000000000000000 0x0000000000002000 0x0000000000002000 x 0x001000 load 0x000000000005e000 0x00007ffc20d9e000 0000000000000000 0x0000000000002000 0x0000000000002000 r x 0x001000 load 0x0000000000060000 0xffffffffff600000 0000000000000000 0x0000000000001000 0x0000000000001000 r x 0x001000 worked
Comments
Post a Comment