C++ ARM cortex M0 NRF51822上硬故障处理程序的GDB回溯
我在使用Segger JLink的手臂Cortex M0(北欧NRF51822)上。当我的代码出现硬错误时(比如由于取消引用无效指针),我只看到以下堆栈跟踪:C++ ARM cortex M0 NRF51822上硬故障处理程序的GDB回溯,c++,gdb,arm,C++,Gdb,Arm,我在使用Segger JLink的手臂Cortex M0(北欧NRF51822)上。当我的代码出现硬错误时(比如由于取消引用无效指针),我只看到以下堆栈跟踪: (gdb) bt #0 HardFault_HandlerC (hardfault_args=<optimized out>) at main_display.cpp:440 #1 0x00011290 in ?? () 我知道我可以使用addr to line将这些代码转换为源代码行: > arm-none-ea
(gdb) bt
#0 HardFault_HandlerC (hardfault_args=<optimized out>) at main_display.cpp:440
#1 0x00011290 in ?? ()
我知道我可以使用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上的堆栈。我知道,在一般情况下,堆栈可能会被我的代码搞得无法读取,但我不认为在这种情况下会发生这种情况
我认为这可能因为北欧的记忆保护计划而变得复杂。他们的蓝牙协议栈安装了自己的中断向量,并阻止对某些内存区域的访问。或者这是塞格的错?在皮质M0的其他例子中,大多数人都能看到硬断层的常规痕迹吗
谢谢
-cCortex-M0和Cortex-M3足够接近,您可以使用此问题的答案:
简而言之:GCC有一个函数_Unwind_Backtrace生成一个完整的调用堆栈;这需要稍微修改一下,以模拟在异常条目发生之前执行回溯。链接问题中的详细信息。可能没有;堆栈跟踪只是反转存储在堆栈上的帧。如果已损坏堆栈,则跟踪将无法工作;链接列表将损坏,此时将无法跟踪。请参阅:了解更多信息。获取注册列表可能会有所帮助。再看看处理器模式,如果您不是普通用户模式,您可以看到保存的
pc
。正如我所说,我不相信在这种情况下堆栈已损坏。我认为0x00011290是Nordic的硬故障处理程序,它在备用非用户模式堆栈上执行。我猜我的堆栈还在内存中的某个地方。我也在上发布了。你需要得到stacked\u fp
,这在中不存在。我不认为每个人都知道这件事;您已经安装了一个向量处理程序,它记录一些状态,然后中断到调试器。异常可能会覆盖用户模式fp
,然后gdb
无法跟踪;与损坏堆栈的效果相同。这是否回答了您的问题?
> 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