Parsing 可执行和可链接格式(ELF)是否可流化?

Parsing 可执行和可链接格式(ELF)是否可流化?,parsing,streaming,elf,crash-dumps,Parsing,Streaming,Elf,Crash Dumps,我想从内存占用较大的崩溃应用程序中提取stacktrace。理想情况下,用户无需等待整个coredump写入磁盘 我目前的想法是在/proc/sys/kernel/core_pattern上安装一个coredump钩子,它将通过stdin解析传入的coredump并仅提取stacktrace。但是,在内存中创建coredump的完整副本是不切实际的,所以流式方法会更好 我是ELF格式()的新手,不知道它是否支持流式解析器。我还没有写过任何类型的流解析器——我熟悉这个概念,但需要关于如何分析流能力

我想从内存占用较大的崩溃应用程序中提取stacktrace。理想情况下,用户无需等待整个coredump写入磁盘

我目前的想法是在
/proc/sys/kernel/core_pattern
上安装一个coredump钩子,它将通过stdin解析传入的coredump并仅提取stacktrace。但是,在内存中创建coredump的完整副本是不切实际的,所以流式方法会更好

我是ELF格式()的新手,不知道它是否支持流式解析器。我还没有写过任何类型的流解析器——我熟悉这个概念,但需要关于如何分析流能力格式的指针

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

cat core | readelf -a
但是,readelf似乎不支持stdin的输入

我还发现了这个python elf解析器,但乍一看它似乎将整个elf读入内存:

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


非常感谢

谷歌的coredumper记录了ELF核心文件格式:

此代码段也很有帮助:

stacktrace似乎包含在elf的单个段中。解决办法是:

  • 阅读elf标题
  • 查找NT_PRSTATUS类型的便笺条目
  • 从该项中的寄存器获取堆栈顶部地址
  • 去那个地址
  • 读取堆栈跟踪
  • 忽略coredump的其余部分
  • 在解析符号等方面,我还有一些工作要做。但是,如果我的方法发生重大变化,我会编辑这个答案。虽然该格式是否可以“流式传输”并不是真正应该问的问题,但我确实找到了一个解决方案,它允许我在不将整个coredump写入磁盘的情况下读取stacktrace

    编辑:

    根据对的回答,似乎在所有情况下重建堆栈都相当复杂。我相信这个问题的最终答案是,不,不可能从ELF核心中提取堆栈,并且ELF核心不“可流化”


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

    请注意,您找到的解决方案回溯解决方案仅适用于32位二进制文件,并且只适用于未经优化编译的二进制文件,或者适用于较旧版本的GCC。@EmployedRussian-您能否提供更多详细信息,以了解为什么回溯解决方案不适用于64位?@matthewtablet回溯代码使用帧指针,默认情况下,在启用优化的情况下,在x86_64上禁用。使用较新版本的GCC,帧指针也会在
    ix86
    (32位)上通过优化禁用。没有帧指针的展开要复杂得多;你需要像Libundwind这样的东西。@EmployedRussian-谢谢!这很有帮助。