当Cortex-M3出现硬故障时,如何保持堆栈竞争

How to retain a stacktrace when Cortex-M3 gone in hardfault?

本文关键字:何保持 堆栈 竞争 Cortex-M3 硬故障      更新时间:2023-10-16

使用以下设置:

  • 基于Cortex-M3的µC
  • gcc臂交叉工具链
  • 使用C和C++
  • FreeRtos 7.5.3
  • 月食Luna
  • Segger Jlink与JLinkGDBServer
  • 代码信心FreeRtos调试插件

使用JLinkGDBServer和eclipse作为调试前端,我在执行代码时总是有一个很好的堆栈。当使用Code Confidence freertos工具(eclipse插件(时,我还会看到当前未运行的所有线程的堆栈争用(如果没有该插件,我只看到活动线程的堆栈竞用(。到目前为止还不错。

但现在,当我的应用程序出现硬故障时,堆栈竞争就失去了。好吧,我知道如何找出导致硬故障的代码地址的技术(如图所示(。但与完全堆叠相比,这是非常糟糕的信息。

好吧,有些时候,当陷入硬故障时,无法保留堆栈争用,例如,当堆栈被故障代码损坏时。但如果堆栈是健康的,我认为进行堆栈竞赛可能是可能的(不是吗?(。

我认为在硬故障时失去堆栈跟踪的原因是,Cortex-M3架构会自动将堆栈指针从PSP切换到MSP。现在的一个想法是,(也许(将MSP设置为以前的PSP值(也许还需要做一些额外的堆栈准备?(。

关于如何做到这一点或其他方法,在出现硬故障时保持堆栈竞争,有什么建议吗?

编辑2015-07-07,增加更多细节。

我用这个代码来引发一个硬故障:

__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 ?? ()

当遇到硬故障(在(*varAtOddAddress)++;(并发现自己在HardFault_Handler()中时,堆栈竞争是:

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?)

让调试器向您提供硬故障前状态详细信息的最快方法是将处理器返回到硬故障前的状态。

在调试器中,编写一个脚本,从各种硬件寄存器获取信息,并将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