那些该死的bug

那些该死的bug,上周,我基本上整整修了一周的bug。其实,这些年一直在做移植,所以总是碰到很多很多的bug,然后年复一年,日复一日的修复。现在,我已经不想懒的解释这些bug是如何产生,因何产生的了,事故发生之后,互相指责显然是于事无补的,首先的是,如何解决这些该死的bug。

我想说的是,不会修bug的程序员不是好的程序员。在遇到bug的时候,第一要做的事是停止工作,修复bug,而不要因为工期紧张拖着不解决。如果你像我一样,碰到的不是自己的程序,这个更是首要前提,往往一个bug会引出很多莫名其妙的问题,所以,在引起更大的轰动之前,先将它消灭掉。

不要惧怕bug的数量或等级。上周,在指定的最后一天的最后一个下午,我的项目依然出现了几个被标定为A(最高等级)的bug。想一想,在最后的两个小时内,依然存有这些bug,将会意味着什么。这个时候千万别慌。分析下bug的状况,仔细的观察,越仔细越好,以我的项目为例,检测部门给我的报告是在某种操作的情况下,可能会出现内存不足黑屏。我按照他们的提示操作了一遍,没有出来,两遍,没有出来,后来将程序产生的记录删除掉,重现了bug。然后重复操作,100%确定,但我认为,记录不会产生任何问题。然后添加调试代码,看看屏幕上显示的当前状态是什么。然后,发现状态不对了,跳转到我的一个未处理的状态中了,整个代码搜索,修复。

从上述的例子也可以看到,看到的,感觉到的也可能是表现给你的一些迷惑。但要相信一点,计算机是不会出错的,程序计算的结果永远是对的,错的是你的程序,你的代码。但从另一个角度来说,种什么瓜,得什么果,你要想得到想要的果,就要种对瓜。幸运的是,程序可以测试,bug总是可以重现。还是上面的例子,在上周四的样子,大概报了我N个bug,ABCD几乎应有尽有,别人觉得这个项目要悬了,这么些个bug啊。我首先简单的将这些bug进行了分类,确定修复的优先级,当然,其中一些明显的问题,但可能优先级并不高的内容,但却又容易修改的问题(比如文字错误之类),在查看的过程中,就顺便修复了。然后去按照优先级,排个时间表去调查,比如某某bug为A,某某为B,怀疑原因为内存问题,这两个一并查,需要时间最多为半小时,就这样一一安排。但在执行的时候,可能并不能按照计划完全执行,可能有些需要的时间长了,有些需要的时间则短了,长了的问题必须设定一个上限,最长时间。在我的项目中,发现程序所需的内存不足。但从哪儿可以找到临时不用的内存呢?图像,不可能,数据,也不可能,图像格式,时间需要的较多,效率可能不好,修改也可能较麻烦,扩展接口?自己不熟悉,而且,最占用内存的是图像,这部分能否如期进行还是问题。然后我总结了一下,列了几个方案,回家睡觉去了。

是的,我回家睡觉去了,有些内容需要额外的时间,谁也没有办法的事情,在目前的安排之中,不管如何就是没有办法如期进行,我所做的就是,为延期做准备,为延期负责,但在我回家的路上,听着地铁里面烦杂的声音,声音,我为什么没有想到声音数据呢?刚开始的时候,为了防止声音的切换出现中断,我将所有的声音数据全部扔到了内存中。然后,第二天,我将声音数据只有在使用的时候才加载到内存中,然后不用的时候再卸载掉,内存问题解决了。

因此,在我们繁忙的时候,在我们盯着一个点使劲的钻牛角尖的时候,也应该稍稍中断一下,回忆下美好的细节,看是否能有其他的出路,上述时间的安排上也可以为了这点考虑。

但实际上,在很多的时候,项目中的问题大都可以采取更好的检测的方法,并不像上面提到的类似心理分析的方法。在某年,同事碰到的一个问题,项目在运行大约半个小时的样子,会出现错误,陷入死循环,但什么地方出现问题就是查不出来。我查看了代码,里面有几个数组,从java代码转换过来的,看了下数组的使用方法,非常整齐规矩,只有几个地方有些不太一样,然后,将代码改为C++代码,顺便一说,C代码改为C++代码非常的简单,就是改下文件的后缀名而已,然后,将代码中的数组用数组模板替换(之前的java数组模拟的代码),然后,实现重载[]的函数,添加调试信息,在异常的判断中下个断点,然后就开着,等待bug的重现。接下来就简单多了,很简单的就找到了数组下标越界的地方,然后修复,整个过程几个小时之内搞定。

上述的方法适用于数组越界,一个经常看到的问题,要说更容易出的问题,可能要数内存泄漏或者内存非法访问吧,内存非法访问基本上就不用多说了,很多情况下都是直接爆掉的,然后停在爆掉的地方。内存泄漏是个麻烦的事情,但如果你在这个网站往前查看的话,会看到内存监视的代码,所有未释放的内存都会被监视出来,然后就是找在什么地方new或malloc了。因此,在合理的地方使用合理的工具也是很重要的。

还有就是要重视别人的提示,我上周的项目有一个问题就是这样的解决掉的。测试人员发现在某个地方有一张图片显示不正常了,也不是每次都出来,但每次将记录文件被清除掉的时候,基本上肯定可以出来。但那个地方应该不需要额外的图像,我告诉她说,如果能告诉我那个地方应该显示什么,告诉我点线索,这样修复就比较简单了,否则,全代码的查看,非常的费时,费力,更容易引起别的错误。然后她说,在原始的版本中,有一个提示,在我的版本中,没有发现什么提示,会不会因为这个错误。我回忆说,我发现那些提示的图像确实使用了,但我不知道在何种情况下使用,但我可以查看一下。然后我就发现在加载的时候,我使用了错误的图像,错误的尺寸。然后问题就修复了。

以上基本上就是我这些年制作项目所获得的经验,之所以一直拿最近的项目做例子,一个是因为记忆比较清晰,另外一个是这个项目经过了十多个人的努力,每个人又都自以为是的增加,强制的修改,也由此引发了各种各样的问题。虽然最好的解决办法是在开始,是项目管理,但你不能指望你所遇到的主管都可以像你那么熟悉这些技能。好的项目从好的构思开始,坏的项目则从错误的尝试中盲目前行。

发表评论

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据