来自 ARM 皮层 M0 NRF51822 上的硬故障处理程序的 GDB 回溯

GDB backtrace from hard fault handler on ARM cortex M0 NRF51822

本文关键字:故障处理 GDB 回溯 程序 ARM 皮层 M0 NRF51822 来自      更新时间:2023-10-16

我正在使用Segger JLink的ARM Cortex M0(Nordic NRF51822)。 当我的代码出现硬错误(例如由于取消引用无效指针)时,我只看到以下堆栈跟踪:

(gdb) bt
#0  HardFault_HandlerC (hardfault_args=<optimized out>) at main_display.cpp:440
#1  0x00011290 in ?? ()

我安装了一个硬故障处理程序,它可以给我 lr 和 pc:

(gdb) p/x stacked_pc
$1 = 0x18ea6
(gdb) p/x stacked_lr
$2 = 0x18b35

我知道我可以使用 addr-to-line 将这些转换为源代码行:

> arm-none-eabi-addr2line -e main_display.elf 0x18ea6
/Users/cmason/code/nrf/src/../libs/epaper/EPD_Display.cpp:33
> arm-none-eabi-addr2line -e main_display.elf 0x18b35
/Users/cmason/code/nrf/src/../libs/epaper/EPD.cpp:414

我可以以某种方式获取其余的回溯吗? 如果我在正常的断点处停止,我可以得到回溯,所以我知道 GDB 可以做(有点复杂的)算法来展开 ARM 上的堆栈。 我知道,在一般情况下,堆栈可能会被我的代码搞砸到不可读的地步,但我认为

在这种情况下不会发生这种情况。

我认为北欧的内存保护计划可能会使这变得复杂。 他们的蓝牙堆栈安装自己的中断向量并阻止访问某些内存区域。 或者也许这是赛格尔的错? 在 Cortex M0 的其他例子中,大多数人是否看到来自硬故障的常规回溯痕迹?

谢谢!

-c

Cortex-M0 和 Cortex-M3 足够接近,你可以使用这个问题的答案:使用 GCC 编译器的 ARM 内核堆栈回溯(当有 MSP 到 PSP 切换时)

简而言之:GCC有一个函数_Unwind_Backtrace来生成一个完整的调用堆栈;这需要稍微修改一下,以模拟在异常条目发生之前进行回溯。链接问题中的详细信息。