可执行和可链接格式(ELF)是否可流式传输?

时间:2014-11-12 22:02:48

标签: parsing streaming elf crash-dumps

我想从具有大内存占用的崩溃应用程序中提取堆栈跟踪。理想情况下,当整个coredump写入磁盘时,用户不需要等待。

我目前的想法是在/proc/sys/kernel/core_pattern安装一个coredump挂钩,它将通过stdin解析传入的coredump并仅提取堆栈跟踪。但是,在内存中创建完整的coredump副本是不切实际的,因此流式处理方法会更好。

我是ELF格式的新手(http://en.wikipedia.org/wiki/Executable_and_Linkable_Format),并想知道它是否支持流解析器。我还没有写过任何类型的流解析器 - 我熟悉这个概念,但需要指出如何分析流能力的格式。

作为第一次尝试,我尝试了:

cat core | readelf -a

但是,看起来readelf似乎不支持stdin的输入。

我也发现了这个python elf解析器,但它乍一看似乎将整个精灵读入内存: https://github.com/eliben/pyelftools

但是,如果需要,也许我可以使用他们的实现作为流解析器的参考。

非常感谢!

1 个答案:

答案 0 :(得分:0)

事实证明,Google的coredumper记录了ELF核心文件格式: https://code.google.com/p/google-coredumper/source/browse/trunk/src/elfcore.c

此代码段也很有帮助: http://emntech.blogspot.com/2012/08/printing-backtracestack-trace-using.html

似乎堆栈跟踪包含在elf的单个段中。解决方案是:

  1. 阅读精灵标题
  2. 查找类型为NT_PRSTATUS的备注条目
  3. 从此条目中的注册表中获取堆栈地址的顶部
  4. 转到该地址
  5. 阅读stacktrace
  6. 忽略coredump的其余部分
  7. 我在解决符号等方面还有一些工作要做。但是,如果我的方法发生重大变化,我会编辑这个答案。虽然格式是否可以“流式传输”并不是一个值得提出的问题,但我确实找到了一个解决方案,它允许我在不将整个coredump写入磁盘的情况下读取堆栈跟踪。

    编辑:

    根据How gdb reconstructs stacktrace for C++?的答案,似乎在所有情况下重建堆栈都非常复杂。我相信这个问题的最终答案是,不,不可能从ELF核心中提取堆栈而且ELF核心不是“可流动的”。

    我相信虽然堆有可能位于coredump中并被删除。这将使堆栈保持完整,允许gdb仍然重建它。