stm32一个强制类型转换死机bug解读

1情景
售后 : x工,现场出大事了,今天升级的程序跑着跑着就挂了!现在整个产线都等着这个设备恢复,能安排个人过来支援下吗?
bug菌 : my god !别慌,我问一下负责的a工。
bug菌 : 喂,a工,昨天升级的程序有问题,程序卡死,售后在现场你联系一下,支援他一波,顺便把程序发送给我一份,一起看看!
a工 : 啊,还有这种事,程序没改什么呀,行,我跟售后联系一下。
经过一番折腾,发现由于程序测试不到位,导致了一个强制类型转化引发的进入异常,这里就分享给大家。
2bug演示
这是一个老项目,采用stm32f4芯片为主控,由于硬件限制而客户又不愿意花大价钱改造,所以程序架构等等都没有再大动作,由于通信上的传输和解析都是字节流,一些小的需求都只是在原来的通信架构上把4个字节拆成2个字节来用,然而这一次实在没办法没改接收数据类型,然后把一个double类型拆成了4个uint16来使用,没想到出问题了。
所以这里简单的模拟演示了一下:
a工用一个double类型取地址,然后把地址强制转为uint64_t类型,以此类型指针取内容,当这段代码执行完程序就跳到了异常中断,导致死机。
其实这段代码对于经验丰富的人来说,一看就觉得很变扭,但是无论如何也不至于死机呀,毕竟强制类型转化大部分人拿来都是随便用。
3bug解读
当看到a工写的这一套代码,bug菌其实隐隐约约就感觉这块有些问题,但是没敢确定,毕竟整套代码也是前人留下的,全是逻辑没什么精华也没有过细研究,最后看这段代码的汇编才知道问题所在。
在之前bug菌也曾比较详细的出过一篇分析此类问题的文章,可能这一块并没有吸引到你,不过还是一句话:出来混都是要还的!。
其实问题就出在ldrd这个arm汇编指令上,ldrd指令表示从指定内存地址取double word,上面图片代码中的ldrd r0,r1,[r2,#0x2ec],可以分解为下面两个ldr步骤 :
在arm汇编指令集中ldrd和strd是一对加载和提取指令,一般都需要使用__align(8)修饰来保证数据对象进行8直接对齐,而使用#pragma pack(8)是来指定结构体成员变量相对于第一个变量的地址的偏移量的对齐方式。
__align指示编译器在 n 字节边界上对齐变量,是一个存储类修饰符,当然也可以以让2字节的对象进行4字节对齐其与8字节对齐是等价的,一定要记得是存储的起始地址为8的整数倍。
对齐可以在一定程度上提高数据提取的效率,一旦起始地址没有对齐会导致对齐错误,所以上面的double浮点类型的结构体变量没有8字节地址对齐,当进行强制类型转化并使用ldrd指令就导致未对齐故障。
3更专业点
当然对于跳转到硬件异常的故障是非常好排查的,下面这篇文章教你如何迅速的定位故障位置和故障信息 :
对于非对齐指令的执行会导致指令用法上的故障,那么cortex芯片中相应的故障寄存器标志位会置位。
以上来自于cortex技术文档,文档中也写得非常的详细。
当cpu尝试做一个未对齐的内存访问,然后就会发生此错误。特别是对于未对齐的ldm/stm/ldrd/strd指令,所以进入异常中断以后查询芯片内部故障寄存器也是可以找到问题所在的,对于使用仿真器排查是再简单不过了,如果是离线排查就需要进行上篇文章那样打印相关日志来定位问题。
  本文来源:公众号:最后一个bug 


剖析离子色谱法如何测定印制电路板表面三种弱有机酸
关于无人驾驶的全新应用分析介绍
土壤水分检测仪的作用是什么,它的功能有哪些
我国增材制造技术发展趋势及应用
智能物流已成为5G率先覆盖的又一商业场景
stm32一个强制类型转换死机bug解读
阿里巴巴淘工厂宣布联手阿里云通过部署IOT设备数字化改造服装厂
电梯五方通话有什么作用
ADI启动ADI Catalyst项目_霍尼韦尔携手东华能源打造航空燃料生产基地
凸轮控制器工作原理_凸轮控制器调整方式
我国电力行业网络安全技术水平在不断提升
人工智能时代 访客登记不仅记证还记脸
C语言中的dummy函数
中国人眼中的科技:屈辱与荣光
绝缘电阻测试必须清楚的事项
魔方大模型在智能汽车领域的应用实践与探索
2018波兰电子消费品市场分析报告
2006日本国际电子元器件展
中航锂电研究基地二期项目封顶成 建设仅用4个月
虹科方案 | 实现KPI分析和预测性维护远比想象中简单!