前段时间公司有客户反馈自己的设备有死机的问题,初步发送给到的视频显示确实是没有任何反应了,有个呼吸灯是中断实现的,如果程序死机了,呼吸灯就不会呼吸了,视频显示确实不会呼吸了,但询问客户做了什么操作,客户也回答不上来,反正就是正常使用然后就死机了中,万不得已只能重启后就好了。此问题一时间也无法找到问题,直到昨天我们同事复现了一次,但因为没有接日志打印,导致因为无法分析,询问同事做了什么操作,也只是常规的操作,无奈只能让同事接上日志继续复现问题,在同事不懈努力下,终于过了一天就复现出来了,分析日志后发现是死在了下发命令到设备后,设备接收到了,但就没有然后了,如下是定位到的问题点代码:
上面的第189行在日志上有打印,在第223行里面的函数也有打印,但是出问题的日志只打印了189行,所以问题锁定在红色的框中,但初步分析和仿真没有发现是100%复现,后面与另一个技术的同事一起来分析有没有内存溢出等问题,也只是发现
1 redata指针没有初始化,
2 bufdata的数组长度有可能不够,
针对上面的1 来说,只会读取此指针的值与bufdata的值来做比较,大不了就是进入if中,也不至于会死机。从2来说确实是有可能出现内存溢出的问题,但这种内存溢出应该是100%出现,而不是有几率出现才对。不过可以确定应该是下发命令调用此函数才会死机的,大方向就是需要不断的下发,看看会不会死机。果然通过另一个同事使用脚本来实现不断的下发指令的功能,成功复现了3次,都是在调用此函数后死机,但都只是抓取到日志,不知道最终为啥会死机,继续将一把锁链接调试环境,终于抓到了死机的时候,调用的是strcmp函数就死机了:
从上面的死机点看,是因为str1 的地址变成0xa5a5a5a5导致读取此地址的值出现异常死机,往前看是因为rdata未初始化导致的,修改方案即是初始化此指针,并顺便修改bufdata的长度(此地方做了试验显示系统会自动对齐4字节,也就是定义的14字节会按照16字节来做,所以此处似乎不会有问题,但为了严谨也一并修改成15以保证不会超出)。
学到的点:认为未定义的指针只是读取,应该不会出错,但不知道MCU读取的是异常的地址也会死机。