有趣 | 最近遇到一个狡猾的bug,复盘分享
时间:2021-08-19 16:35:15
手机看文章
扫描二维码
随时随地手机看文章
[导读]关注「嵌入式大杂烩」,星标公众号,一起进步!最近遇到一个看似青铜、实则王者的bug。事情是这样的,某个进程有数据解析处理、算法融合。数据来源是gps模块,我负责这个程序的开发维护、与算法对接。下面看看从这个bug的定位、分析、解决过程,一波三折~机器之前一直正常在跑,但近两天做了...
关注「嵌入式大杂烩」,星标公众号,一起进步!最近遇到一个看似青铜、实则王者的bug。
事情是这样的,某个进程有数据解析处理、算法融合。数据来源是gps模块,我负责这个程序的开发维护、与算法对接。下面看看从这个bug的定位、分析、解决过程,一波三折~机器之前一直正常在跑,但近两天做了一些特殊测试,发现机器走到某个位置之后基本上必会出现段错误,因为与位置相关的就是数据了,所以刚开始的时候我怀疑可能是数据解析出问题了。但是之前解析有长时间测试过,没什么问题,特殊位置也有测过没什么问题。暂时排除了数据解析的问题。
事情是这样的,某个进程有数据解析处理、算法融合。数据来源是gps模块,我负责这个程序的开发维护、与算法对接。下面看看从这个bug的定位、分析、解决过程,一波三折~机器之前一直正常在跑,但近两天做了一些特殊测试,发现机器走到某个位置之后基本上必会出现段错误,因为与位置相关的就是数据了,所以刚开始的时候我怀疑可能是数据解析出问题了。但是之前解析有长时间测试过,没什么问题,特殊位置也有测过没什么问题。暂时排除了数据解析的问题。
定位问题
遇到死机问题,当然得先定位问题,才能去分析、解决问题。定位段错误的方法有很多:1、log打印定位
可以把所有打印调试信息打开,一些段错误问题可以通过打印的方法就可以大致定位到某一块代码出现问题。打印方式只是定位段错误的一个小尝试而已,不要对其结果抱有太大希望。有时候确实可以很快就定位到问题的根源,但针对本次的bug,通过打印的方式定位出的结果反而给我们带来了一些迷惑。本次的bug通过打印的方式也锁定到了出问题的代码,在某个算法函数里的某两个个三角函数的算式。问题就是屏蔽掉这个算式,程序就没出现段错误,打开这两句代码就必出现段错误,这让我的注意力集中在了这个地方。但反反复复看了好多次没发现这两个算式有什么不妥的地方,而且看了前后两层函数,也没发现有什么不妥。最后定位出了问题,这里确实不是问题的根源,但却在这浪费了很多时间。应该有很多小伙伴跟我有同样的习惯,喜欢通过打印法来查找bug,打印法基本能定位到大多数问题。但对于一些藏得很深的bug,通过打印法有时候只看到了表象,而我们有时候会被这表象给迷惑了。所以在分析问题的时候,尽量头脑清醒些,分析遇到不太合理的地方,要不断的推敲,不断地推翻不合理地分析。当然,有好的定位问题的方法也很重要,下面看第二种定位段错误的方法:2、远程调试
远程GDB是一种适合嵌入式系统的调试手段。它使用目标机端的gdbserver和主机端的gdb调试器协同进行调试,再搭配vscode可以很方便地进行调试。vscode gdb gdbserver远程调试的教程见:干货 | 远程gdb调试 远程GDB的原理是:❝有一小段驻留在目标机上的代码,它被称为调试桩,也称为调试代理。调试代理负责目标机上实现由主机上的调试器发送过来的调试命令,例如:读写内存、读写寄存器、设置断点及运行被调试程序等。调试代理还要向主机调试器报告目标机上的异常事件。❞启动远程调试,全速运行,当程序出现段错误时可以很快知道出现段错误的代码行号。本次的这个bug也是使用这种方法来快速定位出来的。除此之外还有其它很多方法来定位段错误,如使用strace工具跟踪、gdb调试core文件等方法,后续有机会再写使用分享。
分析、解决问题
通过远程调试的方法可以快速定位到本次的段错误出现在一个串口读函数里的下面这一句代码:FD_SET(fd,