将大型核心文件转换为"minicore"文件档案 [英] Convert large core files to "minicore" files
问题描述
如何将核心文件减少为仅线程的堆栈?
How do I reduce core files to just the threads' stacks?
我希望能够运行gdb thread在mini core上应用所有bt
而不再
I want to be able to run gdb thread apply all bt
on the mini core and no more
我正在处理大型(> 4GB)多线程Linux ELF核心文件,这些文件太大而无法进行分析.
I'm dealing with large (>4GB) multi-threaded Linux ELF core files that are too big to get back for analysis.
我已经看到了 google-breakpad 进程崩溃时的最小转储".在 google-breakpad 中,有两个实用程序 core2md
和 minidump-2-core
,它们乍一看应该能够将核心文件转换为minidump格式,然后仅从堆栈信息中将其从minidump返回到核心文件.问题是core2md需要/proc/$ PID/下的进程信息,而我没有.
I've see google-breakpad which is meant to create a "minidump" when a process crashes. In google-breakpad there are two utilities core2md
and minidump-2-core
which at first glance should be able to convert a core file to minidump format, and then back to a core file from the minidump with just the stack information. The problem with this is that core2md requires the process information from under /proc/$PID/ and that's not something I have.
推荐答案
您也许可以编写一个简单的程序,从核心文件中删除很多数据.
You can probably write a simple program which remove much of the data from the core file.
核心文件由代表不同VMA的 PT_LOAD
程序头条目组成:
The core file is made of PT_LOAD
program header entries representing the different VMAs:
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
NOTE 0x0000000000004b80 0x0000000000000000 0x0000000000000000
0x0000000000009064 0x0000000000000000 R 1
LOAD 0x000000000000dbe4 0x0000000000400000 0x0000000000000000
0x0000000000000000 0x000000000009d000 R E 1
LOAD 0x000000000000dbe4 0x000000000069c000 0x0000000000000000
0x0000000000004000 0x0000000000004000 RW 1
LOAD 0x0000000000011be4 0x00000000006a0000 0x0000000000000000
0x0000000000004000 0x0000000000004000 RW 1
LOAD 0x0000000000015be4 0x0000000001872000 0x0000000000000000
0x0000000000ed4000 0x0000000000ed4000 RW 1
LOAD 0x0000000000ee9be4 0x00007f248c000000 0x0000000000000000
0x0000000000021000 0x0000000000021000 RW 1
LOAD 0x0000000000f0abe4 0x00007f2490885000 0x0000000000000000
0x000000000001c000 0x000000000001c000 R 1
LOAD 0x0000000000f26be4 0x00007f24908a1000 0x0000000000000000
0x000000000001c000 0x000000000001c000 R 1
[...]
PT_NOTE
条目包含(除其他事项外)有关线程状态的信息:
The PT_NOTE
entry contains (among other things) informations about the thread state:
Displaying notes found at file offset 0x00004b80 with length 0x00009064:
Owner Data size Description
CORE 0x00000088 NT_PRPSINFO (prpsinfo structure)
[Thread #1]
CORE 0x00000150 NT_PRSTATUS (prstatus structure)
CORE 0x00000200 NT_FPREGSET (floating point registers)
LINUX 0x00000440 NT_X86_XSTATE (x86 XSAVE extended state)
CORE 0x00000080 NT_SIGINFO (siginfo_t data)
[other threads ...]
PT_NOTE处理
您要保留此 PT_NOTE
程序头条目.
此外,您可以从 prstatus
结构中提取堆栈指针:
Moreover you can extract the stack pointers from the prstatus
structures:
struct elf_prstatus {
[...]
elf_gregset_t pr_reg; /* GP registers */
[...]
};
PT_LOAD处理
一旦从所有线程中提取了所有堆栈指针,就可以处理 PT_LOAD
条目:
-
如果
FileSize == 0
,则此程序头文件不会占用核心文件中的任何内存,并且可以忽略;
if
FileSize == 0
, this program header does not consume any memory in the core file and can be ignored;
如果某个线程的堆栈指针位于虚拟内存的此区域中,则可能是一个堆栈,您可能需要保留它;
if the stack pointer of some thread is in this region of virtual memory, this is probably a stack and you might need to keep it;
否则,您可以将其从核心文件中删除(将其替换为带有 FileSize == 0
的程序头条目).
otherwise, you might be able to remove it from the core file (replace it with a program header entry with FileSize == 0
).
或者,您可能可以完全删除所有非堆栈区域的程序头条目.
Alternatively, you might be able to completely remove the program header entries of all the non-stack regions.
另一种解决方案是编写一个核心转储程序,该转储程序直接生成该转储程序,并在/proc/sys/kernel/core_pattern
(man内核)中注册.
Another solution would be to write a core dumper which generated this directly and register in /proc/sys/kernel/core_pattern
(man core).
这篇关于将大型核心文件转换为"minicore"文件档案的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!