bug已经成为程序员工作中的一部分,作为从事嵌入式软件开发已有三年的我,经手的bug也不少了。先说说自己对于bug的心态变化吧,刚开始工作的时候,自己还是很喜欢bug的。那时,自己是负责维护别人的代码,如果发现了bug,说明自己工作有成绩;后来,自己开始码代码,这个时候测试人员告诉我有bug,自己就有些心烦,尤其是当领导知道了这个bug以后,就会感到很大压力;再后来,经手的bug变多了,也变得淡定多了,而且还逐渐建立自己分析bug的工具箱和分析流程;现在,经过几年的工作,积累了一些经验,开始在设计和编码阶段,就尽量考虑周全,以减少bug的产生。

下面就说说自己分析bug的一些心得:

1. 建立一套分析bug用的工具箱

  正所谓,“工欲善其事,必先利其器”,分析bug有一套得心应手的工具很重要。我的工具箱里就有:网络抓包工具(用来分析网络相关问题的),读取、解析日志的工具、获取设备运行状态的工具,另外,还配有解压工具、UltraEditor等等小程序的安装程序(因为有些测试用的电脑上没有安装这些软件)。我将这些工具放到一个文件中,并将其放在U盘中,一旦测试人员告知有bug存在,我就揣着U盘过去。这个“窍门”的来历缘于自己一段痛苦的经历,自己有段时间膝盖疼,特别讨厌爬楼梯,但是当时测试人员在开发人员的楼下,因此,常因为测试人员的电脑上没有自己想要的工具,自己不得已只能爬上爬下地用U盘拷贝工具。痛苦之下,就想出了上面的那个办法,呵呵。

2. 建立一套分析bug的流程或步骤

  bug产生后,测试人员告诉开发人员的都是现象,而开发人员要根据测试人员的现象描述去推测。我同事说,查bug就像是在“查案”,一层一层抽丝剥茧地在分析“案情”,不能放过任何蛛丝马迹。分析bug有的时候就好比在黑暗中行走一样,常常觉得完全无从下手。经过几次痛苦经历后,我逐渐建立一套分析bug的流程或步骤:

  • 获取当前测试的版本信息;让测试人员通过版本检测工具读取当前测试的版本信息,然后截图。此举,可立即确定是否由于版本不正确导致的问题;
  • 读取设备的运行日志;让测试人员读取设备的操作日志和运行日志,交由开发人员解析;
  • 通过设备运行监控工具,获取设备当前的运行状态,然后截图;
  • 通过抓包工具,抓包并且将结果交由开发人员解析;(可选,只针对网络相关的问题)
  • 将获得的所有信息,放到一个文件夹中,以bug现象和测试人员姓名命名该文件夹;

  这样的步骤或流程一个最大的好处就是,不会遗漏可用的信息。因此,除非是那种一眼就能定位原因的bug以外,对于所有bug我基本上都会按照上述去做的,其实其目的也很简单,在还不清楚问题具体情况的状况下,先尽可能地获得系统的可以获得的所有信息,这些信息会为后续分析提供了可参考的信息。这样做只是麻烦一些,但是绝对没有坏处。曾经就有几个很难复现的bug,就是由于缺少对应的日志信息,给我们分析问题原因带来了极大的麻烦。当时,对于没有及时获取更多的信息,非常之懊悔。

  将所有信息都放到一个文件夹中,是一个非常好的习惯,这样所有与之相关的信息就非常好找,更不会出现混乱。另外,上述步骤中,我通常都会要截图,一方面是自己不太相信测试人员的口述,另外一方面留下足够的证据,因为有的时候真是口说无凭啊。

3. 针对不同类型的bug,适当区别对待

  开发人员有时候可能同时在分析好几个bug,这就要对这些bug分轻重缓急了。我通常将bug按照复现难度分优先级。越容易复现的bug优先级越低,即使该bug的严重等级很高。因为能复现的bug,只要花时间总能够分析出原因的,但是很难复现的bug就难说了。其实,bug分析和解决有50%取决于该bug能否复现。因此,每当测试人员告诉一个新bug时,我收集了所有信息,并且分析以后有个初步结论以后,我才会让测试人员破坏环境,让他复现一下(复现bug可能会导致现象消失,但是不去复现也没什么可做的了,毕竟所有的信息都收集完了)。如果这个bug很难复现的话,那么我会先推掉其他事情,专心分析这个bug,否则拖得时间越久,越难找到原因。

  生命不息,bug不止。面对bug,我们须保持良好的心态,因为它们毕竟已经成为我们工作生活的一部分了,以积极良好的心态面对它们的时候,我们也许就能找到比较好的方法解决它们了,^_^

【后记】

  对于模块很多,功能比较复杂的产品,一旦发生bug,一般很难确定bug的原因。这个时候除了尽可能地收集现场信息以外,还一个分析方法。这个方法很简单:首先列出会产生这个bug的所有原因,无论列出的原因听起来,多么不可能,也要列出来,然后逐个去验证和排除,可以先从可能性最大或者最容易验证(或排除)的入手。这个方法背后的逻辑是:

  1. 面对一个很复杂的bug的时候,我们实际上面对的是一团漆黑,面对的是巨大的不确定性;
  2. 人在面对不确定性的时候,会本能地焦虑和慌张;
  3. “列出会产生bug的所有原因”,实际上是给我们提供了一个“落脚点”,让我们在面对不确定性的时候,觉得有事情可做,觉得有“可以入手”的地方,这样我们在心理上就不会那么焦虑和慌张了;
  4. “无论列出的原因听起来,多么不可能,也要列出来”,目的是不去限制大家的思维,让大家可以自由地思考和分析;
  5. “逐个去验证和排除每个原因”,目的是尽可能地缩小问题原因的范围;
  6. “先从可能性最大或者最容易验证或排除的入手”,这一点符合人类的行为习惯——先易后难。

  这个方法不能百分之百地保证能够找到bug的原因,但是它给分析bug提供了一个方向,指引我们的思维和行为,为解决bug提供了一个“落脚点”。本人用这个方法帮助公司解决很多棘手的bug,却发现了一个有趣的现象:产生bug的最终原因通常不是最开始列出来的那些,^_^。

  这个方法的灵感来自于美剧《豪斯医生》。豪斯医生在面对每一个疑难杂症的时候,都会集合助手,一一列出任何可能的病因,然后逐个验证和排除。而且我发现的那个现象,这个美剧中也有,就是最终的病因通常不是他们最开始列出来的,这也许是编剧故意制造的戏剧化效果吧,哈哈。

【参考文献】:

1. 美剧《豪斯医生》

说说分析bug的一些心得的更多相关文章

  1. 结合程序崩溃后的core文件分析bug

    引言     在<I/O的效率比较>中,我们在修改图1程序的BUF_SIZE为8388608时,运行程序出现崩溃,如下图1:          图1. 段错误     一般而言,导致程序段 ...

  2. 分析bug是前端还是后端的

    如何分析一个bug是前端还是后端的? 平常提bug的时候,前端开发和后端开发总是扯皮,不承认是对方的bug 这种情况很容易判断,先抓包看请求报文,对着接口文档,看请求报文有没问题,有问题就是前端发的数 ...

  3. 《ODAY安全:软件漏洞分析技术》学习心得-----shellcode的一点小小的思考

    I will Make Impossible To I'm possible -----------LittleHann 看了2个多星期.终于把0DAY这本书给看完了,自己动手将书上的实验一个一个实现 ...

  4. 关于bug分析与异常处理的一些思考

    前言:工作三年了,工作内容主要是嵌入式软件开发和维护,用的语言是C,毕业后先在一家工业自动化控制公司工作两年半,目前在一家医疗仪器公司担任嵌入式软件开发工作.软件开发中,难免不产生bug:产品交付客户 ...

  5. 从BUG工具redmine上获取数据后借助python模块pycha 画出BUG分析类报表

    整体代码比较冗长,但是很好读.写的方法全是按照BUG分类去写的.所以写死了,凑合看吧,画出饼图,树状图和生成对应的数据excel,希望大家举一反三能帮助自己分析BUG #__author__ = 'x ...

  6. 测试对bug如何分析和定位

    如何去区分一个功能测试工程师的水平高和低? 可以从很多个方面去检查,比如测试的思路, 比如测试用例的覆盖度?,比如测试出bug是否能够定位到根因? 上面说的各个方面都很合理,那我们平常如何如更深的定位 ...

  7. 电梯系列——OO Unit2分析和总结

    一.摘要 本文是BUAA OO课程Unit2在课程讲授.三次作业完成.自测和互测时发现的问题,以及倾听别人的思路分享所引起个人的一些思考的总结性博客.主要包含设计策略.代码度量.BUG测试和心得体会等 ...

  8. JML规格编程系列——OO Unit3分析和总结

    本文是BUAA OO课程Unit3在课程讲授.三次作业完成.自测和互测时发现的问题,以及倾听别人的思路分享所引起个人的一些思考的总结性博客.主要包含JML相关梳理.SMT Solver验证.JML单元 ...

  9. [BUAA2021软工助教]案例分析作业总结

    目录 一.作业链接 二.优秀作业推荐 A+作业推荐 A作业推荐 三.总结 所有案例分析总结 特色与优点 问题与建议 不同类产品案例分析Bug汇总 CSDN问答社区.Stack Overflow.Seg ...

随机推荐

  1. sqoop job 踩过的坑

    sqoop 执行可以以job形式 也可以执行用命令执行,再用sqoopjob时,踩了几个坑,分享一下 1.服务器重启 由于服务器增加硬盘,需要重启后,发现sqoop job 无法执行,报连接数据库IO ...

  2. Docker私有仓库 Registry中的镜像管理

    这里主要介绍Registry v2的版本 查看Registry仓库中现有的镜像: # curl -XGET http://10.0.30.6:5000/v2/_catalog# curl -XGET ...

  3. 编程实践中C语言的一些常见细节

    对于C语言,不同的编译器采用了不同的实现,并且在不同平台上表现也不同.脱离具体环境探讨C的细节行为是没有意义的,以下是我所使用的环境,大部分内容都经过测试,且所有测试结果基于这个环境获得,为简化起见, ...

  4. MFC中控制COMBOBOX控件的下拉框高度

    这是使用Visual Stiduo的小技巧哦.今天上网找来的.在界面设计面板上,点击ComboBox的下拉箭头,会另外出现一个虚边框.可以调整其大小.这个就是实现运行的时候下拉边框的默认值啦.

  5. Mysql 与日期和时间相关的函数

    目录: 常用日期函数 时间加减函数 date_forma函数 1. 常用日期函数 now() current_timestamp() sysdate() 实例一: 从上图可以看出三个函数都是用来获取当 ...

  6. P1159岳麓山上打水

    P1159岳麓山上打水 https://vijos.org/p/1159 dfsID,第一次听说这东西,但是感觉不太靠谱啊. 一开始的时候,想到了排个序后,然后进行dp,如果要输出字典序最小其实还是可 ...

  7. Linux编程获取本地IP

    #include <stdio.h> #include <sys/types.h> #include <ifaddrs.h> #include <netine ...

  8. XML Xpath学习

    Xpath是一门在xml文档中查找信息的语言. Xpath可用来在xml文档中对元素和属性进行遍历. <1>路径表达式1: 斜杠(/)作为路径内部的分隔符 同一个路径有绝对路径和相对路径两 ...

  9. sqlserver中,查看某个函数的调用情况

    今天想在sqlserver中看看自己写的函数都被哪个函数或存储过程调用了,手工检查起来太慢了,于是在网上找一个快速的方法,分享一下. select * from sys.all_sql_modules ...

  10. 揭开HTTP网络协议神秘面纱系列(三)

    HTTP首部字段有四种类型:通用首部字段,请求首部字段,响应首部字段,实体首部字段. 通用首部字段: 首部字段 说明 Cache-Control 控制缓存的行为 Connection 逐跳首部.连接的 ...