C++ 当Cortex-M3出现硬故障时,如何保留堆栈跟踪?
使用以下设置:C++ 当Cortex-M3出现硬故障时,如何保留堆栈跟踪?,c++,c,cortex-m3,freertos,C++,C,Cortex M3,Freertos,使用以下设置: 基于Cortex-M3的µC 使用C和C++ FreeRtos 7.5.3 月蚀 Segger Jlink与JLinkGDBServer 使用JLinkGDBServer和eclipse作为调试前端,我在遍历代码时总是有一个很好的stacktrace。在使用Code freertos工具(eclipse插件)时,我还可以看到当前未运行的所有线程的堆栈跟踪(没有该插件,我只看到活动线程的堆栈跟踪)。到目前为止还不错 但是现在,当我的应用程序陷入硬故障时,stacktrace
- 基于Cortex-M3的µC
- 使用C和C++
- FreeRtos 7.5.3
- 月蚀
- Segger Jlink与JLinkGDBServer
__attribute__((optimize("O0"))) static void checkHardfault() {
volatile uint32_t* varAtOddAddress = (uint32_t*)-1;
(*varAtOddAddress)++;
}
当进入checkHardfault()
时,我的stacktrace看起来像这样:
gdb-> backtrace
#0 checkHardfault () at Main.cxx:179
#1 0x100360f6 in GetOneEvent () at Main.cxx:185
#2 0x1003604e in executeMainLoop () at Main.cxx:121
#3 0x1001783a in vMainTask (pvParameters=0x0) at Main.cxx:408
#4 0x00000000 in ?? ()
当运行到硬故障(在(*varatodaddress)+
)并发现自己在硬故障处理程序()中时,堆栈跟踪是:
gdb-> backtrace
#0 HardFault_Handler () at Hardfault.c:312
#1 <signal handler called>
#2 0x10015f36 in prvPortStartFirstTask () at freertos/portable/GCC/ARM_CM3/port.c:224
#3 0x10015fd6 in xPortStartScheduler () at freertos/portable/GCC/ARM_CM3/port.c:301
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
gdb->backtrace
#0 HardFault\u处理程序()位于HardFault.c:312
#1
#freertos/portable/GCC/ARM_CM3/port.c:224处prvPortStartFirstTask()中的2 0x10015f36
#freertos/portable/GCC/ARM_CM3/port.c:301上的xPortStartScheduler()中的3 0x10015fd6
回溯已停止:此帧内部的上一帧(堆栈损坏?)
让调试器向您提供硬故障之前状态的详细信息的最快方法是将处理器返回到硬故障之前的状态
在调试器中,编写一个脚本,从各种硬件寄存器获取信息,并将PC、LR、R0-R14恢复到导致硬故障之前的状态,然后执行堆栈转储
当然,这并不总是有帮助的,当你最终在硬故障,因为弹出的东西从一个吹堆栈或跺脚的东西在内存中。您通常会损坏一堆重要的寄存器,返回内存中的某个疯狂点,然后执行其中的任何内容。在真正的问题发生后,您可能会导致数千(数百万?)个周期的硬断层 考虑使用以下gdb宏恢复寄存器内容:
define hfstack
set $frame_ptr = (unsigned *)$sp
if $lr & 0x10
set $sp = $frame_ptr + (8 * 4)
else
set $sp = $frame_ptr + (26 * 4)
end
set $lr = $frame_ptr[5]
set $pc = $frame_ptr[6]
bt
end
document hfstack
set the correct stack context after a hard fault on Cortex M
end
我可以给你一个STM32的解决方案,它是基于大脑皮层的。请看我在类似问题上给出的两个答案,并且(这一个更详细,因为它指的是你问题范围之外的一个特定问题)。如果记忆正常,然后PC和LR在中断发生之前将最后两个函数的地址存储在调用堆栈中,R0到R3存储传递给这些函数的参数。建议的解决方案与上所述的相同(正如我在问题中也提到的)。它只是给PC
留下了一个提示,最终导致了硬故障(以及LR
中的一个调用级别,正如我现在从您的评论中了解到的),但它不会提供堆栈跟踪。@Joe您能在这方面取得进展吗?事实证明,我也处于类似的情况