【Debug1】程序死机,while(1)循环,怎么办?

程序死机:停在HardFault_Handler的while(1)死循环中

问题描述

  • 程序死机,停在停在HardFault_Handler的while(1)死循环中
  • 调试日志疯狂报错:Cannot access Memory (@ 0x0000457e, Read...)。
  • 芯片内核寄存器R14(LR)显示为0xFFFFFFFD,说明异常发生在任何(线程)模式下,使用的是PSP。

原因分析:

走过的弯路

  • 手动查堆栈失败:根据PSP去Memory窗口看压栈的PC和LR,结果找出来的数据全是乱码(0x20001A6A...)。程序发生异常时,栈已经被踩坏,也可能是底层汇编的压栈动作被中断打断。
  • BFAR误导:故障报告里的BFAR显示0xE000EDF8,这是内核调试寄存器地址。

问题定位

  • Call Stack(调用栈):通过Keil自带的Call Stack窗口,直接定位到了出事前的函数调用链:network_entry->air_work_rst_dev。
  • 地址关联:发生崩溃时报错的0x457e和air_work_rst_dev函数的地址0x4543极其接近。
  • Watch(观察)窗口:在嫌疑函数air_work_rst_dev内部打断点,展开相关的全局结构体指针netdev_opt。
  • 一眼定乾坤:在Watch窗口里看到clear_rxbuf的值是0x00000000

根本原因

  • 在初始化do_netdev_opt结构体时,漏掉了对clear_rxbuf 函数指针的赋值。
  • 当air_work_rst_dev执行到netdev_opt->clear_rxbuf( netdev );时,试图调用一个空指针(跳转到0x00000000),瞬间触发硬件异常(HardFault)

该具体问题解决方案:【只针对我做的项目遇到的问题】

总结

以后遇到问题怎么Debug?

以后如果再遇到死机、跑飞、HardFault,按以下步骤:

  • 第一步:看现场
    • 打开Call Stack窗口:看看死机前最后调用的两三个函数是谁,嫌疑犯基本就在这几个函数里。
    • 打开Fault Reports:看看是 CFSR 里的哪位(如 PRECISERR 精确总线错误、UNDEFINSTR 未定义指令)在作祟,并记录下 BFAR(如果有效的话)。
  • 第二步:锁变量(Watch窗口+局部变量)
    • 在Call Stack锁定的嫌疑函数开头打断点
    • 把该函数用到的结构体、指针、关键变量全部拖进Watch窗口。
    • 重点关注指针类型:看看哪个指针变成了0x00000000、0x00000004、0x2000...(非正常数组区)、或者0x000045xx(代码区地址)
  • 第三步:看汇编(Disassembly 窗口)
    • 如果C代码里看不出来问题,去反汇编窗口
    • 跳到报错的PC地址(或者使用Show Disassembly at Address),看看崩在哪条指令。通常是LDR(加载)或STR(存储)指令。
  • 第四步:验堆栈(Memory 窗口 - 进阶)
    • 如果上述方法都找不到,再去用MSP或PSP算地址查堆栈。注意,一定要确保看到了正确的内存块,如果数据全乱,说明发生了栈溢出(Stack Overflow)。

避坑(如何不写Bug)

  1. 函数指针结构体格式必须初始化 :如果用了函数指针结构体,初始化最好用
    .成员名 = 函数名的格式,并且赋值NULL或者写个默认函数,调用前判断一下if(ptr->func != NULL)。
  2. 防御性编程 :在解引用指针(ptr->xxx)之前,一定要判断if(ptr != NULL)。
  3. 警惕数组越界:这次的乱码0x457e也可能是其他数组越界把指针踩坏了。使用数组时检查下标边界。
  4. 善用调试工具:日常开发时,编译选项坚决关闭高等级优化(用 -O0),开启Debug信息,这样单步调式才准。
  5. 多看编译警告:很多时候,把函数当成变量穿,未初始化指针,编译器会给Warning的,不要忽略它们。
相关推荐
Lxx_Zw1 小时前
PID 用顺了,然后呢:增强手术与前馈
c语言·stm32·单片机·嵌入式硬件
张怀民3161 小时前
PFC_CCM_NCP1654详讲
单片机·嵌入式硬件·硬件工程·pfc
xian_wwq1 小时前
【学习笔记】Milvus 是什么?为什么 RAG 系统经常使用它?-14
笔记·学习·milvus
BeiGuTing_code1 小时前
C链表基础(二)有视频模拟!!!
c语言·链表·音视频
燕落南枝1 小时前
HTML 视频标签(video)详解笔记
笔记·html·音视频
linweidong2 小时前
RTC 走偏、时间跳变?嵌入式时间管理的工程避坑
嵌入式硬件·面试·实时音视频·rtc·嵌入式面经·嵌入式ntp·嵌入式对时
Yiran_G2 小时前
ZigBee单播、广播与组播详解:从寻址机制到批量控制设计
嵌入式硬件·物联网·智能家居
学逆向的2 小时前
C 选择结构的执行效率分析
c语言·开发语言·算法·网络安全
youcans_3 小时前
【STM32C5教程】(9)DAC 模拟量信号输出实验
stm32·单片机·嵌入式硬件·stm32c5·cubemx2