0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

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

嵌入式情报局 来源:最后一个bug 2023-11-30 09:31 次阅读

1情景

售后 : X工,现场出大事了,今天升级的程序跑着跑着就挂了!现在整个产线都等着这个设备恢复,能安排个人过来支援下吗?

bug菌 : my god !别慌,我问一下负责的A工。

bug菌 : 喂,A工,昨天升级的程序有问题,程序卡死,售后在现场你联系一下,支援他一波,顺便把程序发送给我一份,一起看看!

A工 : 啊,还有这种事,程序没改什么呀,行,我跟售后联系一下。

经过一番折腾,发现由于程序测试不到位,导致了一个强制类型转化引发的进入异常,这里就分享给大家。

2bug演示

这是一个老项目,采用stm32F4芯片为主控,由于硬件限制而客户又不愿意花大价钱改造,所以程序架构等等都没有再大动作,由于通信上的传输和解析都是字节流,一些小的需求都只是在原来的通信架构上把4个字节拆成2个字节来用,然而这一次实在没办法没改接收数据类型,然后把一个double类型拆成了4个uint16来使用,没想到出问题了。

所以这里简单的模拟演示了一下:

wKgZomVn56OAAs5LAADmeanYIhM305.png

wKgZomVn56OADaDMAACfMRZs60g097.png

A工用一个double类型取地址,然后把地址强制转为uint64_t类型,以此类型指针取内容,当这段代码执行完程序就跳到了异常中断,导致死机。

其实这段代码对于经验丰富的人来说,一看就觉得很变扭,但是无论如何也不至于死机呀,毕竟强制类型转化大部分人拿来都是随便用。

3bug解读

当看到A工写的这一套代码,bug菌其实隐隐约约就感觉这块有些问题,但是没敢确定,毕竟整套代码也是前人留下的,全是逻辑没什么精华也没有过细研究,最后看这段代码的汇编才知道问题所在。

在之前bug菌也曾比较详细的出过一篇分析此类问题的文章,可能这一块并没有吸引到你,不过还是一句话:"出来混都是要还的!"。

其实问题就出在LDRD这个ARM汇编指令上,LDRD指令表示从指定内存地址取double word,上面图片代码中的LDRD R0,R1,[R2,#0x2EC],可以分解为下面两个ldr步骤 :

wKgaomVn56OAUv0xAAApXkusAO4757.png

在ARM汇编指令集中LDRD和STRD是一对加载和提取指令,一般都需要使用__align(8)修饰来保证数据对象进行8直接对齐,而使用#pragma pack(8)是来指定结构体成员变量相对于第一个变量的地址的偏移量的对齐方式。

__align指示编译器在 n 字节边界上对齐变量,是一个存储类修饰符,当然也可以以让2字节的对象进行4字节对齐其与8字节对齐是等价的,一定要记得是存储的起始地址为8的整数倍。

对齐可以在一定程度上提高数据提取的效率,一旦起始地址没有对齐会导致对齐错误,所以上面的double浮点类型的结构体变量没有8字节地址对齐,当进行强制类型转化并使用LDRD指令就导致未对齐故障。

3更专业点

当然对于跳转到硬件异常的故障是非常好排查的,下面这篇文章教你如何迅速的定位故障位置和故障信息 :

对于非对齐指令的执行会导致指令用法上的故障,那么Cortex芯片中相应的故障寄存器标志位会置位。

wKgZomVn56OAXsjIAAD6gtbDfa0001.png

wKgaomVn56OAFxOyAAEE4KKaqeA008.png

以上来自于Cortex技术文档,文档中也写得非常的详细。

CPU尝试做一个未对齐的内存访问,然后就会发生此错误。特别是对于未对齐的LDM/STM/LDRD/STRD指令,所以进入异常中断以后查询芯片内部故障寄存器也是可以找到问题所在的,对于使用仿真器排查是再简单不过了,如果是离线排查就需要进行上篇文章那样打印相关日志来定位问题。

本文来源:公众号:最后一个bug


审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • STM32
    +关注

    关注

    2240

    文章

    10675

    浏览量

    348868
  • 代码
    +关注

    关注

    30

    文章

    4557

    浏览量

    66820
  • BUG
    BUG
    +关注

    关注

    0

    文章

    154

    浏览量

    15581

原文标题:stm32一个强制类型转换死机,让我付出了惨痛的代价~

文章出处:【微信号:嵌入式情报局,微信公众号:嵌入式情报局】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    C语言中强制类型转化

    为何要在这里提强制类型转换呢,测试代码可以看到编译器会报很多警告,意思是告诉程序员数据类型不匹配,虽然并不影响程序的正确运行,但是很多警告总会让人感到难受。因此为了告诉编译器代码这里没
    的头像 发表于 09-09 08:58 2138次阅读
    C语言中<b class='flag-5'>强制</b><b class='flag-5'>类型</b>转化

    TCP中强制类型转换

    这是完整程序第一个和第二强制类型转换都有什么用啊我加了显示控件,但是显示乱码求指点~~~
    发表于 04-15 19:42

    新手求问:强制类型转换的三端口分别应该连接什么

    1.强制类型转换的三端口分别应该连接什么2.error簇有什么作用,应该怎么使用3.VISA怎么使用4.XY图有什么作用
    发表于 08-25 09:32

    laview中强制类型转换控件使用的些心得

    Labview中有控件叫“强制类型转换”,以前直没弄明白怎么使用它,今天仔细研究了下,发现
    发表于 01-19 20:26

    强制类型转换问题

    本帖最后由 applevs 于 2017-5-24 23:03 编辑 char*强制转换为short*后,每两个字节组成新的short类型
    发表于 05-24 22:44

    奇怪的现象,增加结构节点后,影响强制类型转换的速度

    今天做了实验,发现了很奇怪的现象,图中的程序运行非常的快,图二中显示了程序运行10秒时的循环次数。然后在强制类型转换外面加了
    发表于 06-08 16:07

    请问使用强制数据类型转换函数的时候,数据类型type端该如何设置,才能使数据成功转换类型

    本帖最后由 只耳朵怪 于 2018-6-26 08:51 编辑 使用强制数据类型转换函数的时候,数据类型type端该如何设置,才能使
    发表于 06-25 20:33

    这算是STM32BUG吗?

    死机后串口就直发送同一个数据,从仿真看是死在中断函数里面。 猜想:STM32的其他外设也有同样问题。未测试。
    发表于 08-27 10:30

    基础:stateflow中变量的强制类型转换

    使用:例:我定义了变量speed作为输出,某时刻指定speed=0,当我把speed改为uint8类型,就报错误,找了阵没找到方法,就放弃了。今天在看别的帖子是发现了
    发表于 10-29 10:42

    C语言指针必须要进行强制类型转换

    进行后续的数据访问,那么为什么不直接把右值指针的地址给左值指针,(正如我第句所说的,都是四字节不会丢失数据)而要进行强制类型转换呢?而且疑问处的代码去掉(char *),在VC++6
    发表于 03-06 04:14

    C语言中int型强制类型转换成short型的溢出问题怎么解决?

    如何判断STM32编码器模式中电机的正反转?C语言中int型强制类型转换成short型的溢出问题怎么解决?
    发表于 10-19 06:59

    清除labview的强制类型转换的缓存

    请问如何将labview的强制类型转换的缓存如何清除?我在使用Picture to IMAQ image 官方vi时,如果运行时间过久,视频流中的图片过多,还原像素图.vi就会造成内存不足,
    发表于 02-15 20:36

    强制类型转换是把变量从一种类型转换为另一种数据类型

    类型转换可以是隐式的,由编译器自动执行,也可以是显式的,通过使用强制类型转换运算符来指定。在编程时,有需要
    的头像 发表于 11-12 14:59 9424次阅读

    C++之类型转换函数详解

    一、转换构造函数的学习:1、回忆数据类型转换:在平时写代码的时候,最怕的就是那种隐式数据类型转换了,一不小心,软件就
    的头像 发表于 12-24 15:31 669次阅读

    C语言如何掌握强制类型转换的精髓

    强制类型转换是把变量从一种类型转换为另一种数据类型。例如,如果您想存储一个 long
    的头像 发表于 02-26 11:00 199次阅读
    C语言如何掌握<b class='flag-5'>强制</b><b class='flag-5'>类型</b><b class='flag-5'>转换</b>的精髓