嵌入式的核心能力-Debug调试能力(一)

一、栈回溯

引入:调试程序时,经常会发生这类错误:

读写某个地址,程序报错;调用某个空函数,导致程序报错等等。

解决方法是,可以利用异常处理函数去打印出“发生错误瞬间”的所有寄存器地址

根据这些打印出来的地址信息,回溯发生错误的位置,并且需要知道位于调用链路。

1.栈回溯的原理

本质还是看汇编,C语言函数的返回地址,保存在栈里、

2.修改异常处理函数打印栈内容

位于硬件错误异常中 HardFault_Handler 都是死循环,并不能提供更多的信息,例如RT thread做的就很好,会有对应的寄存器信息 以及相关反馈。

整个流程大致为:发生错误

中断运行->硬件 原本LR先入栈 LR等于异常返回地址 保存程序状态(软件也要保存硬件保存剩余寄存器) 返回地址PC值->执行异常向量函数 打印栈

STMFD   r0!, {r4 - r11}         ; push r4 - r11 register
STMFD   r0!, {lr}               ; push exec_return register

来自RTthread的函数

3.分析stack,找出函数调用关系

得到反汇编,例如fromelf --text -a -c --output=all.dis test\test.axf

通过分析反汇编以及地址

二、修改bin文件实现断点

引入:什么情况下需要打断点,在没有调试器,不方便使用调试器,想查看代码任意位置的状态

如何触发?修改原来的代码 改为未定义指令 并且修改异常处理函数打印寄存器和栈内容

需要得到.dis以及.bin 比如MDK是利用

fromelf  --text  -a -c  --output=all.dis    test\test.axf
fromelf  --bin  --output=test.bin test\test.axf

本质是通过软断点的方式实现(把正确的指令改错),软断点的关键是利用特定的指令替换被调试程序中的某些指令,迫使程序在执行到该位置时产生异常。

硬断点就例如MDK中打的断点了有限制次数,处理器硬件支持的调试机制,例如位于flash中打断点,ARM架构的功能watchpower,并且有次数限制。

重新烧写

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

7yewh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值