使用以下设置:
使用JLinkGDBServer和eclipse作为调试前端,在单步执行代码时,我总是有一个不错的stacktrace。当使用Code Confidence freertos工具(eclipse插件)时,我还会看到当前未运行的所有线程的堆栈跟踪(没有该插件,我只会看到活动线程的堆栈跟踪)。到目前为止一切顺利。
但是现在,当我的应用程序陷入困境时,堆栈跟踪就会丢失。好吧,我知道有关如何找出导致硬故障的代码地址的技术(如here所示)。但是与完整的堆栈跟踪相比,这是非常差的信息。
好吧,有时候陷入硬件故障时,无法保留堆栈跟踪,例如当堆栈被错误的代码损坏时。但是,如果堆栈具有健康性,我认为可能可以获取堆栈跟踪信息(不是吗?)。
我认为在发生硬故障时失去堆栈跟踪的原因是,Cortex-M3架构会将堆栈指针自动从PSP夹到MSP。现在的一个想法是,(可能)将MSP设置为先前的PSP值(并且可能必须执行一些其他的堆栈准备工作?)。
有关在发生故障时如何执行此操作或其他方法来保留堆栈跟踪的任何建议?
编辑2015-07-07,添加了更多详细信息。
我使用此代码来发起硬故障:
__attribute__((optimize("O0"))) static void checkHardfault() {
volatile uint32_t* varAtOddAddress = (uint32_t*)-1;
(*varAtOddAddress)++;
}
进入checkHardfault()
时,我的堆栈跟踪看起来像这样:
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?)
使用以下设置:使用C和C ++ FreeRtos的基于Cortex-M3的µC gcc-arm交叉工具链7.5.3使用JLinkGDBServer的Eclipse Luna Segger Jlink代码信心FreeRtos调试插件使用...
[在调试器中,编写一个脚本,该脚本从各个硬件寄存器中获取信息,并将PC,LR,R0-R14还原到引起硬故障之前的状态,然后执行堆栈转储。