核心转储说明部分 [英] Core dump note section
问题描述
根据我关于手动生成核心转储文件的问题,我决定深入研究进去弄脏我的手.
Following my question about manually generating a core dump file, I decided to dive into it and get my hands dirty.
我能够构建基本的核心转储结构并将死程序的内存重新放入大 LOAD 部分中的核心转储中.在 GDB 中调试时,我的变量又回来了,这没问题.棘手的部分来了,我如何让 GDB 检索有关程序崩溃时所在位置的信息.
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.
我知道核心转储的注释部分包含此信息(cpu 寄存器等).这是 objdump -h 为真正的"核心转储提供的内容:
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 ...
感谢readelf,我发现那些 .reg 部分包含从某些结构映射的数据:
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)
有人可以告诉我注释部分的结构吗?我尝试将这些结构直接写入我的文件,但它不起作用,我显然在这里遗漏了一些东西.我查看了 Google Coredumper 代码 并从中获取了一些信息,但编写了note 部分并不那么简单,欢迎提供有关其确切内容和格式的任何详细信息.
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.
编辑#1:跟随第一条评论
我发现我的 Elf 文件的结构应该如下:
I figured out my Elf file should be structured as follows :
- 精灵头 ElfW(Ehdr)
- 程序头(Ehdr.e_phnum 乘以 ElfW(Phdr)),这里我基本上使用了一个 PT_NOTE 和一个 PT_LOAD 头
- 注意部分:
- 节的标题 (ElfW(Nhdr))
- 部分的名称(.n_namesz 长)
- 节的数据(.n_descsz 长)
然后我必须放 3 条笔记记录,一条用于 prstatus,一条用于 prpsinfo,一条用于 辅助向量.
Then i will have to put 3 note records, one for the prstatus, one for prpsinfo and one for the auxiliary vector.
这似乎是正确的方法,因为 readelf 给我的输出与我上面通过真正的核心转储得到的输出相似.
This seems to be the right way as readelf gives me a similar output as what I got above with the real core dump.
编辑#2:得到正确的结构之后
我现在正在为组成笔记记录的不同结构而苦苦挣扎.
I am now struggling with the different structures composing the note records.
这是我在核心转储上运行 eu-readelf --notes 时得到的结果:
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 ?
谢谢!
推荐答案
经过一些测试,我想通了,回答任何寻找此信息的人:
After some tests I figured things out, answering for anyone looking for this information :
有人可以确认我以正确的方式构建我的 Elf 文件吗?
Can someone confirm I am going the right way structuring my Elf file this way ?
是的.
由于 GDB 正在接受文件,这似乎是正确的做法.readelf -a 显示的结果显示了正确的结构,到目前为止很好.
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 ?
赋予
Phdr.p_offset
的偏移量应该指向数据在Elf 文件中的位置.它们从文件的最开头开始.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.例如:
PT_NOTE
程序头的 p_offset 应设置为sizeof(ElfW(Ehdr)) + ehdr.e_phnum*sizeof(ElfW(Phdr))
.ehdr.e_phnum
是 Elf 文件中程序头的编号.The p_offset for the
PT_NOTE
program header should be set atsizeof(ElfW(Ehdr)) + ehdr.e_phnum*sizeof(ElfW(Phdr))
.ehdr.e_phnum
being the number of program header present in the Elf file.对于
PT_LOAD
程序头,这有点长,因为我们还必须添加所有注释部分的长度.对于带有包含NT_PRSTATUS
、NT_PRPSINFO
和NT_AUXV
部分的注释段的标准"核心转储,PT_LOAD 数据的偏移量(Phdr.p_offset
) 将是: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 containgNT_PRSTATUS
,NT_PRPSINFO
andNT_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)
这篇关于核心转储说明部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!