在一个项目中,出现了部分设备随机死机问题。对这个问题也是排查分析了很久,一把辛酸泪,做个记录,希望给遇到类似问题的朋友一些思路(涉及到项目相关的信息和截图就不呈现了,主要描述思路)。
具体有几种情况:1、黑屏死机(应用程序崩溃有core文件);2、亮屏死机(内核错误);3、自动重启。一开始肯定是根据现象具体问题具体分析,山穷水尽之后,只能列出故障树,一点一点排查分析。故障树主要从五个方面进行分析验证:应用、系统、内核、UBOOT、硬件。由于在某一个界面出现概率比较大,所以一般都是在此界面验证,该界面功能是通过MCU查询数据后定时刷新界面数据。
1 故障树验证及结果分析
1.1 应用
应用程序崩溃导致黑屏的可能原因:使用了未初始化的变量、数组或容器越界、解引用空指针或野指针、使用了无效的迭代器、栈溢出等。
1.1.1 分析core文件
core文件为内核转储文件,该文件保存问题发生时的状态。只要有问题发生时程序的可执行文件和内核转储,就可以知道进程当时的状态。
通过"./gdb 应用程序名称 core"命令进入调试后,bt命令显示栈帧,通过查看多台设备多次的core文件堆栈信息,发现每次的都很随机,有的死在应用程序相关函数,有的死在Qt库函数,有的死在系统内存相关库函数。刚开始的时候对这些情况都进行了对应的分析,死在应用程序相关函数和内存库函数的查看应用程序代码,死在Qt库的在Qt官网BUG库里搜索有没有相关库函数BUG,均未查到确定的原因。
通过info reg命令查看寄存器的值,pc为程序指针,sp为堆栈指针,x/i显示汇编指令,尝试通过汇编指令推导程序执行是否有问题也没有发现异常。
通过堆栈调用地址说明没有发生递归调用,也就不是递归调用导致的栈溢出。通过info files命令查看应用程序当时的内存映射,结合sp指针的地址说明没有发生栈溢出。并且编译应用程序和内核的时候也通过开启栈溢出检测证明了没有发生栈溢出。
从软件角度,通过以上分析说明core文件堆栈信息已不可信(但后续如果查到是硬件原因导致的死机,则core文件堆栈信息刚好证明了当时的随机状态)。
1.1.2 通过排除法排查线程和定时器
屏蔽一个线程或定时器就编译一个版本验证,如果还死机说明不是这个线程或定时器的原因。最后是排除了列出的所有线程和定时器。
1.1.3 编写Demo
单独编写一个只有前面说的死机概率比较大的界面的Demo应用程序,不通过MCU只用200ms定时器刷新八个编辑框的值也出现死机。
1.1.4 其他验证
1、替换Qt版本验证也还是会死机,Qt4.8.4替换为Qt4.8.7;
2、替换屏蔽setStyleSheet函数的Qt库后不死机(setStyleSheet功能为设置样式,屏蔽后界面为灰色原始控件);
3、不使用linuxfb的方式启动应用程序,并在PC端用VNC查看器远程连接,此时仪器端界面停留在开机界面,应用程序界面在PC端查看器显示(相关启动脚本内容为"./应用程序名称 -qws -display VNC:0:size=800*600 &"),不死机;
4、不启动应用程序,只用mplayer循环播放mp4视频,不死机;
5、延长验证界面通过MCU查询数据后定时刷新界面的时间,可以降低死机概率;
6、编译SVN上的历史版本验证,非常早的版本也会死机;
1.1.5 应用方面分析结果
根本原因不是应用程序代码导致的死机,可能跟显示方面及其用到的资源有关。
1.2 系统
1.2.1 系统资源监控
使用atop工具监控系统资源情况未发现异常。
1.2.2 内存验证
使用内存测试工具memtester测试内存是否有问题。先用命令free -m查看设备剩余内存,假设剩余300多MB,再输入命令 memtester 300M后一直循环测试内存,有内存错误汇报failure。拿多台死机的设备测试多天未出现错误。
1.3 内核
1.3.1 分析内核错误Oops信息
Oops信息是内核中发生致命错误时输出的内核信息。Oops信息中大致包含了错误概况、加载的模块、寄存器信息、栈跟踪信息等。
跟core文件堆栈信息一样,Oops的堆栈信息也随机,所有也判断为不可信,也就不能协助定位具体原因。
1.3.2 WIFI驱动
WIFI模块为内核新加入的模块,跟供应商了解有新的驱动版本并修改了一些BUG。更新WIFI驱动版本测试还是会出现死机。卸载WIFI驱动测试也还是会死机。
1.3.3 LCD驱动
1、更新匹配的更高版本SDK的LCD驱动测试,死机;
2、LCD驱动增加打印中断状态寄存器日志测试,死机的时候显示未触发LCD中断;
3、CPU芯片参考手册上有说明双缓冲可以支持更高的带宽并提高传输效率和同步能力,开启双缓冲测试,死机;
4、LCD时钟频率由30MHz改为40MHz测试,死机但是可以降低死机频率;
1.4 UBOOT
1.4.1 DDR3时序配置
1.2.2内存验证没有报错说明DDR3时序配置没有问题。
1.4.2 CPU主频配置
AM3358数据手册上查到主频支持600MHz、800MHz、1000MHz,目前配置的是800MHz。配置1000MHz主频测试,死机。配置600MHz主频测试,不死机。
1.5 硬件
DDR3内存及走线通过1.2.2证明没问题。WIFI模块通过1.3.2证明没问题。
其他验证及现象:
1、参考“AM335x 电源问题汇总----板卡的稳定性问题的杀手”和AM3358数据手册,升压之后还是会死机,监控VDD_CORE未低于手册要求最低值;
2、VDD_MPU在界面切换和验证界面定时器刷新界面时候存在波动,在TI官方论坛询问后,TI硬件工程师给的回复说明这部分电路存在不太良好的设计;
3、更换了一些板卡元器件后一台经常死机的设备不死机了;
4、前一个硬件版本的设备未发现死机现象;
5、给容易死机的设备换了芯片还是会死机(第一次换了新的AM3358,第二天跟没死机过的前一个硬件版本的设备对换了AM3358+DDR3);
6、查看CPU芯片及电源管理芯片的数据手册及勘误手册;
2 总结
通过以上故障树五方面的验证及分析,说明根本原因不是应用程序代码导致的死机,可能是硬件方面导致的(电源部分),需要从硬件方面继续分析验证确定导致死机问题的根本原因。目前可以通过UBOOT修改CPU主频为600MHz解决死机问题。
3 其他
上半年历经几个月的艰辛,死机问题总算告一段落了,整理资料的同时顺便补一下这篇博客。回顾整个过程,在百度、谷歌、Stack Overflow、Qt官网、TI论坛搜了个遍,书签都存了一大堆,过程是痛并快乐着,收获也不少,感谢一起并肩作战的同事们!其实通过应用方面的分析、不同硬件版本的现象,可以合理怀疑是硬件原因,硬件早些介入分析可以节省不少时间。碰到瓶颈时需要寻找理论支撑,技术方面讲究实事求是有理有据,过程中看完的这本书(《Debug Hacks中文版——深入调试的技术和工具》)给了很多支持和信心。不知经历了多少遍的希望到破灭再找到希望,一点点排查验证直到找到解决方案。也许有的事情坚持下去才能看到希望。渔夫出海前,并不知道鱼在哪里。可他们还是选择了出发,因为他们相信,自己一定会满载而归。人生很多时候,是因为选择了才有机会,相信了才有可能。永远相信美好的事情即将发生!
4 附录
过程中查找的部分书籍和资料(链接失效的话百度对应文章名称应该都可以再找到):
#、《Debug Hacks中文版——深入调试的技术和工具》 吉冈弘隆
#、Qt官网查询已知BUG
Issue Navigator - Qt Bug Tracker
#、Qt内存泄漏总结(包括检测工具)
Qt内存泄漏总结(包括检测工具)_qq_42100881的博客-CSDN博客
#、linux c开发必备程序异常分析指南
#、linux进程内存布局--randomize_va_space
linux进程内存布局--randomize_va_space_bluenet13的博客-CSDN博客
#、gcc-stack-protector机制
gcc-stack-protector机制_奔跑的码仔的博客-CSDN博客_gcc stack
#、Segmentation Fault (SIGSEGV) vs Bus Error (SIGBUS)
Segmentation Fault (SIGSEGV) vs Bus Error (SIGBUS) - GeeksforGeeks
#、What is a bus error? Is it different from a segmentation fault?
c - What is a bus error? Is it different from a segmentation fault? - Stack Overflow
#、Cannot access memory at address error
c++ - Cannot access memory at address error - Stack Overflow
#、atop工具检测linux硬件异常
atop工具检测linux硬件异常 - 过去都是浮云 - 博客园
#、GCC优化引发的一场血案
GCC优化引发的一场血案_David.li的博客-CSDN博客
#、QT界面刷新崩溃 人也快崩溃了...
https://bbs.csdn.net/topics/390830998
#、Linux的LCD硬件实现原理和FrameBuffer简介
Linux的LCD硬件实现原理和FrameBuffer简介_平仄散人的博客-CSDN博客
#、FrameBuffer 架构
linux-kernel - FrameBuffer 架构_个人文章 - SegmentFault 思否
#、The Frame Buffer Device
https://www.kernel.org/doc/Documentation/fb/framebuffer.txt
#、TI中英文设计支持论坛
#、AM3358: Qt应用程序刷新界面时,VDD_MPU波动问题
AM3358: Qt应用程序刷新界面时,VDD_MPU波动问题 - 处理器论坛 - 处理器 - E2E™ 设计支持
#、AM3358: change on VDD_MPU pin
AM3358: change on VDD_MPU pin - Processors forum - Processors - TI E2E support forums
#、AM3352: Thermal issue
AM3352: Thermal issue - Processors forum - Processors - TI E2E support forums
#、AM335x 电源问题汇总----板卡的稳定性问题的杀手
http://www.doczj.com/doc/975285483-6.html
#、linux下查看内存频率,内核函数,cpu频率
linux下查看内存频率,内核函数,cpu频率 - lvusyy - 博客园
#、am335x 内核频率 ddr3频率 电压调整
am335x 内核频率 ddr3频率 电压调整 - 嵌入式操作系统 - 博客园
#、TI AM335x CPUfreq子系统(Linux3.14)定制手册!
TI AM335x CPUfreq子系统(Linux3.14)定制手册! - ARM技术 -电子工程世界-论坛 -手机版