4

我在使用 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 上的堆栈。我知道,在一般情况下,堆栈可能会被我的代码搞砸到无法读取的程度,但我认为在这种情况下不会发生这种情况。

我认为这可能会因 Nordic 的内存保护方案而复杂化。他们的蓝牙堆栈安装了自己的中断向量并防止访问某些内存区域。或者这可能是 Segger 的错?在 Cortex M0 的其他示例中,大多数人是否看到硬故障的常规回溯?

谢谢!

-C

4

1 回答 1

0

Cortex-M0 和 Cortex-M3 足够接近,您可以使用以下问题的答案: Stack Backtrace for ARM core using GCC compiler (when there is a MSP to PSP switch)

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

于 2018-06-19T08:26:56.120 回答