原帖 | Lili_iliLX | 2025-05-25 00:42 | 👍6 | 阅读约1
栈回溯学会了,总结一下:栈回溯解决的是HardFault类问题,这类问题的现象是程序跑飞了,但是不同与其他类型的跑飞,其他类型的跑飞一般都能通过debug、全速运行、暂停,找到具体是程序哪里出问题了,就是bug的故障点很好定位。HardFault类的错误是,程序出现不可挽回的错误的时候会进入HardFault中断处理函数,所以当我们采用debug的方式寻找故障点的时候总是进入的是HardFault中断处理函数,我们无法找到真正出问题的点。
栈回溯就为我们提供了解决这种类型错误的方式,当发生函数调用的时候LR寄存器总是会保存函数的返回地址(LR 最低位的 1 是 Thumb 状态标志,详见 老师,LR保存函数的返回地址,我理解为函数跳转前的PC指针的值),但是当被调用函数内部比较复杂或者被调用函数内部又发生函数调用的时候,最外层的调用关系中,被调用函数就会把返回地址压入栈中,而HardFault就是采用了将返回地址压入栈中的形式,所以当发生HardFault类型错误的时候,我们就可以这样解决:
首先进入debug模式,观察CPU寄存器状态(debug界面的左侧Core列表),找到SP指针的值,然后观察HardFault中断处理函数的栈帧内存,在这段内存里是存储了LR寄存器的,我们只需要找到LR寄存器的值,就能找到进入HardFault的原因,即真正导致系统出错的故障点。具体该怎么找呢,如果项目中没有使用分散加载将某些函数定位到sram的话,那么函数的地址都应该是0x0800xxxx,所以说在这段内存找到08,然后再前找三个字节,这四个字节就是函数返回地址。

相关笔记