数组溢出问题

问题描述:
前天在调试某个设备的时候,发现整个程序跑起来的时候,出现了及其诡异的现象。
因为这一套程序的底层驱动在之前的板子上面用到过,这次新板子,大部分东西都没动,只是应用层的逻辑做了一些调整。没想到系统运行起来后,采集的电流值应该为0,但实际读取到的电流值时大时小,而且能达到±100多A。。。且设备的配置参数也是一直在变,时不时就被某个不知道是什么的数给修改掉了。
因为设备没有显示屏,只是通过串口和上位机通信。上述的现象都是在上位机上面观察到的。程序的逻辑是:开机读取设备配置参数,保存到RAM里面。并实时读取电流值。如上位机询问,则将上位机要的信息发送过去。理论上配置参数在一个开机循环中不会有变化,出现上述现象,立时有点抓瞎。
问题分析:
刚开始分析的时候,觉得有两种可能性。一个是栈溢出了,造成数据混乱。另一个是数组有溢出,影响到了其他信息。先一个一个排查。
先看栈的问题,因为这个编译器,对栈的优化不太好,栈的位置正好紧挨着RAM的结尾。说实话栈溢出以前遇到过,所以这一次首先想到是不是栈又一次溢出了?先看map文件:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

保存存电流的结构体起始地址为0x1C4、保存设备参数的结构体起始地址为0x23C
栈起始低位为0x6AA
靠近栈位置的变量,反而没变。
从这个基本上就排除了栈溢出的可能性。

涉及到另外一个怀疑的可能性,这个就不好找了。有几个条件,更加制约了找到问题的根源:

  1. 程序不能debug,硬件有点问题,debug过程中,经常死机。
  2. 没法用beyond compare软件比较新版本和旧版本的区别,因为改动太多了,要是一点一点比较的话,太浪费时间,可能一天也弄不完。(计划如果实在找不到问题的原因,再一点一点比较。)
  3. 没法全局搜结构体、数组,一个一个看是否有溢出的。因为太多了。。。定义的结构体就有十多个,全局和局部的数组更多。。。搜了一下,好几千条,决定暂时先不看了。

好在这个现象每次都能复现,还好查一点。
先想办法把有问题的地方去掉,一点一点去功能,看看究竟问题出在哪里。
既然电流采集有问题,先去掉和电流相关的所有函数。
去掉后,发现好了!!!真是惊喜啊!!!没想到一下就找到问题点了。
然后又一点一点的添加/去除各项功能,最终发现是在电流的应用计算上面,出了问题。
有一个函数,是要每50ms记录一次电流值,每1秒计算一次平均电流值。使用的是一个静态变量:
在这里插入图片描述
问题就出在这里,数组是10个long型,而实际数据存储了20个long型。后面的10个long型数据,不知道存到哪里去了。这个是程序移植过程中,出现的问题。原来的程序100ms记录一次电流值,所以数组只需要10个即可。现在要50ms记录一次,数组大小没改。。。
把上面的定义改成:static signed long CurrData[20];就好了。

再深究一下,这个是怎么影响到电流值显示和设备参数结构体的呢?
还得看map表:
在这里插入图片描述

从表中可以看到:CurrData数组的地址为0x155,10个long型数据,长度到0x17C。再往后10个long型数据,长度到0x1A4。也就是说,地址为0x17D到0x1A4的数据,都被影响到了。
这些变量里面,Base_adc0和Base_adc1两个参数,是电流零漂参数,其直接影响到了电流数值的计算,所以电流值异常跳动。
这些变量里面,还有一个SOC_GetNum变量,尤其关键。
程序里面有这样的地方:
在这里插入图片描述
SOC_GetNum的变化,会影响到SOC_VolData变量存储地址后面的数据。
再看map表:
在这里插入图片描述
SOC_VolData后面,就会涉及到设备参数。也就是说,设备参数的改变,是因为CurrData数组的溢出,同时造成了SOC_VolData数组的溢出,造成了设备参数发生了改变。

整个过程折腾了1个多小时,总算弄通了。。。

总结:
说实话这种情况排查起来非常的费劲,因为你不知道问题出在哪里。程序一飞起来飞到天涯海角都有可能。写此文章引以为戒,以后在写代码的时候,针对指针和数组一定要慎之又慎,虽然很好用,但也要用对了才行。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值