0

我在任何地方都找不到一个很好的解释——我正在使用一个 cortex-m4 设备(具体来说,它是一个 STM32L4 发现板)并且我尝试编写一个工具来为我打印调用堆栈(具体来说我想要获取最后 10 次函数调用,即对应的程序计数器值)。显然这是可以做到的,因为当我调试电路板时(使用带有 cortex-debug 扩展的 VS 代码,并且当我使用 J-link 设备连接到 MCU 时)我可以看到完整的调用堆栈,甚至可以看到传递给堆栈中每个函数的值。但是,我无法理解这是如何完成的(cortex-debug/Vs 代码如何获得回溯)。

在查看汇编代码时,我看不到任何帧指针(我看到核心以某种有线方式使用 R7,但我无法回溯使用它)。所以我想我可能需要使用展开表,但是当我使用测试精灵是否包含这些部分(.ARM.exidx 和 .ARM.extbl)时,arm-none-eabi-readelf --unwind test.elf我发现没有展开部分。那么在这种情况下 VS 代码如何展开堆栈呢?是否有一些与 J-link 相关的特殊硬件以某种方式保持该跟踪,然后 J-link gdb 服务器可以访问它?这些东西是如何工作的有什么好的来源吗?谢谢

4

1 回答 1

0

就我对这个主题的有限了解而言,调试器可以在调试基于 .elf 文件的数据时向您显示调用堆栈,从中“知道”堆栈帧的大小等。换句话说,它使用从 MCU 读取的数据和嵌入在 .elf 文件中的数据(其中一部分转换为二进制加载到 MCU)。

这也意味着您不能例如“从代码”(_Unwind_Backtrace)获取回溯,除非您在加载到 MCU 的二进制文件中包含必要的信息(-funwind-tables选项)。

于 2022-01-10T13:00:49.320 回答