以我的观点来看:做出一个业务功能是件很简单的事,做好则有难度,高效的做好则是难上加难。抛开前期的架构设计、技术方案的制定不谈,单单是写好代码这一阶段就给我们每个人带来了不同程度的挑战。之前还写过一篇关于代码编写阶段的文章《提高工作效率的工具“类”》,下面我就主要从代码debug的角度来谈谈我的看法。


  • 尽量写代码时避免bug,减少调试
    对于任何问题,先以预防为主。在团队中常常可以遇见这样的同事,代码写的非常快,可是天马行空的代码之后却让自己陷入了无尽debug的沼泽。我会给这样的同事建议:多花点时间做好代码结构的设计,写代码时经常进行review,另外就是老生常谈的细心。

  • 利用好IDE和工具
    常常听到这样的看法,用vim,emacs的看不起用IDE的,觉得vim..就是银弹,不管什么语言,什么平台只要你问他什么IDE最好,他一定回答你vim..。当然不排除有能把vim..用的出神入化的人,其他的大多数是在装X吧。你要记住,你的目标是完成工作,不是显示自己多高端,多牛X。gdb同理。合适的IDE有很多好处:错误提示、代码补全、丰富的替换查找、各种关联跳转,当然如果你不嫌麻烦,不怕不准确也可以对vim进行配置来实现相同的效果,但请先看看这篇文章再做决定《编辑器与IDE》,以上几个IDE带来的好处不正好对我们上面提的“尽量避免bug”有很正面的意义嘛。另外,IDE集成的debug界面友好也强大(用过gdb的朋友肯定知道),断点,step over,step into,内存变量,调用堆栈...简直就是debug神器,至少我写程序读程序的标准步骤就是依靠这几步。(说点夸张的,但是我还确实遇到了不少人包括一些很多年工作经验的工程师竟然从没有用过断点调试,完全靠着printf行走江湖,我的“惊讶”如滔滔江水啊...),在调试中其他工具的使用也可以使debug事半功倍,比如内存泄露的检测工具,还有进行网络编程时的各种工具(wirshark,netcat,tcpdump...)

  • 程序输出日志
    我认为日志系统也应该是一个程序的标准组成部分。其最大用处就是帮助我们来梳理程序行为,准确定位bug。有些朋友要问了,我可以用IDE来调试观察啊,问题是很多bug并不是在你写代码测试时发现的,是在发布之后的用户那里,傻眼了吧?还有很重要的一点,多线程问题、还有一些依赖于具体系统环境或时间环境的问题是很难复现的,这次抓不住你就等着一直提心吊胆吧。我在工作中一直使用Apache的log4X系列,又一个强大的神器。但在有些环境下用不了log4X,比如在有些对程序所占空间大小很敏感的的嵌入式环境(log4cxx的动态库较大),你完全可以自己利用标准输出封装相应的日志系统,然后运行时做好定向输出工作就好。

  • 崩溃转储
    崩溃这种fatal级的大bug最让我们头疼,在C/C++中十有八九是内存违例(段错误)造成的。这种bug和多线程问题一样也是最难找的,所以我们一定要尽可能的准确定位抓住它,最有效的办法就是利用内存转储文件。在linux平台下开启这个选项后利用gdb core就可以进行定位分析。windows平台下较麻烦,得自己实现内存转储功能,推荐大家一个工具类mini_dump,一旦程序崩溃就会产生dump文件,之后使用windbg调试即可。

  • google
    很多bug自己想了各种办法也定位不了或者无法fix,这时你就得请教google大神了。尽量别用百度,如果中文搜索条目很少或没有,换成英文搜索,也许会有更多的收获。


  • 我给我的团队成员提了这么一个建议:如果一个问题你自己尝试了,也google了,但是无法解决。一旦超过一个小时耗在这个问题上请大胆的寻求外部帮助吧,问团队中经验较丰富的成员,也许他曾经遇到过,也许他会给你提供好的建议或者思路。

  • 深入学习
    其实这点排在最前面比较合适,先去深入学习再去做相应的工作。但是我们实际工作中恰恰相反,往往是遇到了问题再去深入学习,我觉得很多bug的形成是我们对知识的一知半解甚至一无所知造成的,我们要尽量抛弃那种临时抱佛脚式的学习,而是要在自己的职业生涯中持续不断学习,深入学习。

以上就是我对提高debug能力的一些看法和实践。