将大型核心文件转换为"minicore"文件档案 [英] Convert large core files to "minicore" files

查看:77
本文介绍了将大型核心文件转换为"minicore"文件档案的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何将核心文件减少为仅线程的堆栈?

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆