繁体   English   中英

ARM cortex-M4 上的堆栈跟踪

[英]Stacktrace on ARM cortex-M4

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

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

这篇博客文章参考 MIPS 架构讨论了这个问题 - 这些原则可以很容易地适应 ARM 架构。

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

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

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

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

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

ImageCraft 的 Richard 是对的。

更多信息可以在这里找到

这适用于 C 代码。 我更难将它应用于 C++,但这并非不可能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM