ARM cortex-M4上的Stacktrace

时间:2017-02-06 15:57:21

标签: c arm cortex-m

当我在ARM cortex-M4(Thumb)上遇到故障处理程序时,我会在故障发生之前获得CPU寄存器的快照。有了这些信息,我可以找到堆栈指针所在的位置。现在,我想要的是回溯它传递的所有函数。我在这里看到的唯一问题是我没有框架指针,所以我无法确定某个子程序在哪里保存了LR,无限期。

如果帧指针在r7中不可用,如何解决这个问题?

3 个答案:

答案 0 :(得分:0)

This blog post参考MIPS架构讨论了这个问题 - 这些原则可以很容易地适应ARM架构。

简而言之,它描述了为给定SP和PC定位堆栈帧的三种可能性:

  • 使用编译器生成的调试信息(未包含在可执行映像中)进行计算。
  • 使用编译器生成的堆栈展开(异常处理)信息(包含在可执行映像中)来计算它。
  • 扫描呼叫站点以找到调整堆栈指针的序言或结尾代码,并从中推断出堆栈帧地址。

显然它依赖于编译器和编译器选项,并不能保证在所有情况下都能正常工作。

答案 1 :(得分:0)

R7不是M4上的帧指针,而是R11。 R7是Cortex-M0 + / M1的FP,其中通常只有低位寄存器可用。无论如何,当Cortex-M使用BL及其变体调用函数时,它将返回地址保存到LR(链接寄存器)中。在函数输入时,LR被保存到堆栈中。因此,从理论上讲,要跟踪呼叫,您将“追逐” LR的链。

很遗憾,调用约定未定义LR在堆栈上的保存位置,并且必须从DWARF记录(在中的函数条目)的调试信息中推导出其位置。 elf文件)。我不知道是否有实用程序可以从ELF文件中提取LR位置,但这应该不会太困难。

答案 2 :(得分:0)

ImageCraft的理查德是对的。

可以找到更多信息here

这在C代码下可以正常工作。我很难将其应用于C ++,但这并非没有可能。