加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 当Cortex-M3进入硬故障时如何保留堆栈跟踪?

发布时间:2020-12-16 07:13:04 所属栏目:百科 来源:网络整理
导读:使用以下设置: 基于Cortex-M3的μC gcc-arm cross toolchain 使用C和C. FreeRtos 7.5.3 Eclipse Luna Segger Jlink与JLinkGDBServer Code Confidence FreeRtos debug plugin 使用JLinkGDBServer和eclipse作为调试前端,在逐步执行代码时总是有一个很好的堆栈
使用以下设置:

>基于Cortex-M3的μC
> gcc-arm cross toolchain
>使用C和C.
> FreeRtos 7.5.3
> Eclipse Luna
> Segger Jlink与JLinkGDBServer
> Code Confidence FreeRtos debug plugin

使用JLinkGDBServer和eclipse作为调试前端,在逐步执行代码时总是有一个很好的堆栈跟踪.当使用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()时,我的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 ?? ()

当遇到hardfault(at(* varAtOddAddress);)并发现自己在HardFault_Handler()内部时,stacktrace是:

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恢复到导致硬故障之前的状态,然后执行堆栈转储.

当然,当你最终遇到硬故障时,这并不总是有用的,因为从堆栈中弹出东西或者在内存中踩东西.你通常倾向于破坏一堆重要的寄存器,回到内??存中的一些疯狂的位置,然后执行那里的任何事情.在您遇到真正的问题后,最终可能会导致数千(数百万?)个周期出现故障.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读