4

如何将核心文件减少到线程堆栈?

我希望能够thread apply all bt在 mini core 上运行 gdb,不再需要

我正在处理大型 (>4GB) 多线程 Linux ELF 核心文件,这些文件太大而无法返回进行分析。

我看到google-breakpad旨在在进程崩溃时创建一个“小型转储”。在google-breakpad中有两个实用程序core2mdminidump-2-core乍一看应该能够将核心文件转换为 minidump 格式,然后从 minidump 中返回核心文件,其中仅包含堆栈信息。问题在于 core2md 需要 /proc/$PID/ 下的进程信息,而这不是我所拥有的。

4

2 回答 2

1

可能你最好的选择是将 google breakpad 集成到你的 Linux 进程中,这样当发生崩溃时,它是 google breakpad 记录崩溃而不是操作系统创建核心文件。这将为您提供所需的信息,然后您可以使用 minidump_stackwalk 转储调用堆栈(便于汇总大量崩溃),也可以使用 minidump-2-core 创建核心文件。

不幸的是,Linux 似乎没有一种有效的方法来创建仅使用线程堆栈的内容的最小核心文件。这些文件(Windows 世界中的小型转储)非常有用——它们具有非常高的信息大小比,可以轻松收集数百万个故障转储。

于 2013-04-23T22:18:33.563 回答
1

您可能可以编写一个简单的程序,从核心文件中删除大部分数据。

核心文件由PT_LOAD代表不同 VMA 的程序头条目组成:

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条目包含(除其他外)有关线程状态的信息:

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

struct elf_prstatus {
  [...]
  elf_gregset_t pr_reg;   /* GP registers */
  [...]
};

PT_LOAD 处理

从所有线程中提取所有堆栈指针后,您可以处理PT_LOAD条目:

  • 如果FileSize == 0,则该程序头不消耗核心文件中的任何内存,可以忽略;

  • 如果某个线程的堆栈指针在这个虚拟内存区域中,这可能是一个堆栈,您可能需要保留它;

  • 否则,您可以将其从核心文件中删除(将其替换为带有 的程序头条目FileSize == 0)。

或者,您可以完全删除所有非堆栈区域的程序头条目。

创建您自己的核心转储程序

另一种解决方案是编写一个核心转储器,它直接生成它并在/proc/sys/kernel/core_pattern(man core)中注册。

于 2016-02-15T00:52:49.107 回答