排错感悟

2006/10/30:这篇文章5个月前写的了,一直没机会发表(一直留在公司的电脑里),今天终于拷了回来,所以贴出来供大家参考,是我总结的一些经验。

硬件本身错误:我还没有遇到过,但有个众所周知的例子,1994年Intel推出的Pentium处理器后来被发现存在浮点运算错误的bug,实在太严重了。除非实在没有了其它一切可能,否则不要轻易怀疑这个,尤其是使用主流硬件的情况下。

硬件故障:一定是硬件损坏引起吗?未必,比如声卡如果安装不牢靠,一调用播放声音程序,恐怕机器就要莫名其妙彻底死机,还包括驱动程序兼容性问题,姑且把它也当作硬件故障类问题吧。

多线程程序:访问共享资源的时候特别特别容易出错,还有多进程程序也是,尽管我没怎么用过多进程编程,但据说如此。

逆推+自我描述:从现象出发,自己把错误好好从头到尾描述一次,这样一来,一半的错误原因都会出来了。

版本追溯:从某个版本开始发现这个问题,这时候的版本管理就体现出优势了,如果没有版本管理的话只能从出现问题的时间开始估算究竟是修改了哪些程序才会出现这种问题。程序版本管理,修改日志,very important。(哎,我发现我真啰嗦,会不会被一些技术很牛的人看扁啊?)

表里不一:有时候问题十分离奇古怪,简单的程序,简单逻辑,出现最不可能的问题,而且屡屡检查不出,就自己抓狂。其实静心下来,问题不像表面上的那样古怪,仔细看看程序,是不是漏写了“&”符号,或者在子程序中多定义了某个变量。

更古怪的问题:网络消息重发,或者发送的消息字节丢失,开始怀疑是函数库的问题,但实际上多半还是程序逻辑的问题,仔细检查相关的逻辑,难道真不能发现一些没考虑到的死角吗?

辞旧迎新:这里是贬义,改正了旧的错误,却因为这个粗心的改动,导致了新的错误,经常会有的了,所以就算是看起来再简单不过的程序,多个心眼也是好的。

不轻易怀疑MFC:嗯,如题,微软的家伙一个个都很强,起码我跟他们根本不是同一档次的。

不过分相信down来的库:和上面的“不轻易怀疑”相对应,因为可能开发过程中确实需要修理一下那些桀骜不驯的库。

基础不牢固:有次我很担忧Linux C的一个库函数,这个函数返回一个指针,指向一个结构体,我很担心,因为我的程序反复调用这个函数,我担心每调一次它就malloc一次,而没有free,内存泄露啊,其实,担心是没有必要的,只要指针指向的结构体是static类型就可以了,搞程序这么长时间我还是too simple,自以为发现了一个大bug;基础不够扎实,就容易做出些低级的错误,比如返回子函数局部变量的指针,或者企图改变字符串常量的指针等,除了苦练基本功加上认真,没什么更好的办法。

释放、释放、释放:过去老爸经常骂我做事情有头没尾,到现在这个天生的坏习惯还没全改过。有时候并非我真的不想释放,而是程序诸多分支可能跳过了释放的环节。释放不光是内存,还包括文件,套接字,数据库链接等等,一旦资源耗光,就出现“非法操作”,而这往往是在长时间的运行(比如正式运营)之后出现,实在不好对付。

释放也可能出错:释放是好事,但也会出错,比如要释放一个链表,先delete p,然后p = p->next,再delete p,Wrong!释放前检查指针有效性不失为一种好办法。

记录出错参数:空难之后除了救援幸存者(不过现在看来通常都是表面文章)就是打捞黑匣子,因为我们要查找原因,所以要找到它。一次成功的测试是发现了存在的问题,我能否补充一下?一次成功的测试是发现了问题并正确描述了出现问题的环境(条件)。

充分利用断点:为什么开发Windows程序比开发Linux程序容易?一来是博大精深的MSDN,二来是五彩缤纷的IDE,我喜欢IDE,排错多方便。

充分利用TRACE和log:需要更真实观察程序运行的时候不能用断点,MFC提供了TRACE,好用的东西,但不用MFC怎么用“TRACE”,用OutputDebugString吧,谢谢陈海东同学教了我这招,太有用了,但记得别放在Release版中;log也是好东西,但得使用得合理才能产生效率。

不可重现的错误:这类错误最为凶险,排除测试人员失误的情况,应尽量思考如何去创造这种错误出现的环境。

总结经验:有些错误恐怕必须凭着经验才能改正,而且经验能如此高效帮助你改正错误,何乐而不为。

防患于未然:这永远是最高心法。

over!

20060530 by 蒋国纲
 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值