如何处理Bug

Table of Contents

1 确认Bug准确位置

  • 在关键地方插入assert,如函数参数断言、逻辑断言;
  • 跟踪调用语句,例如:Common Lisp有trace函数;
  • 注意异常或返回值;
  • 查看日志;
  • 列出可能出现问题的地方,逐个排除。

找到问题后,最终目标是修复该问题,如果你不是开发者,就去Google搜索下是否其他人也遇到过、Bug反馈列表是否有人反馈过;如果有人反馈Bug了,并且这个Bug对你影响很大,你可跟踪Bug的处理情况,或者给开源社区提交patch。

1.1 举个例子

某天用Wifi上网(平时都用有线上网),Wifi频繁掉线,其他电脑和设备均正常,路由后台管理也未发现异常情况,那问题多半是在操作系统上。

这种情况问题一般出在NetworkManager服务和网卡驱动上。在掉线后,我restart了NetworkManager服务,问题仍旧,所以问题应该不出在NetworkManager服务上。怀疑是内核问题,重启系统在Grub上用老版本的内核(Fedora默认保存3个版本内核)去引导系统,系统工作了一段时间并没有出问题,那就确定是新版本的内核驱动导致的。

回到有问题的内核,用lsmod找到Wifi的驱动:

$ lsmod | fgrep wifi
rtlwifi                73728  3 rtl_pci,rtl8192ce,rtl8192c_common
mac80211              749568  3 rtl_pci,rtl8192ce,rtlwifi
cfg80211              589824  2 mac80211,rtlwifi

挨个尝试rmmod(卸载模块)后发现问题出现在rtl8192ce模块——只要重新modprobe(加载模块),网络便可恢复正常。

然后去Fedora的Bug列表(https://bugzilla.redhat.com)搜索下rtl8192ce最近有不有人反馈Bug:

search_result.png

第一条搜索结果“Wi-fi randomly not working”,和我遇到的问题一样,根据Bug详情来看:

1、已经分配给Kernel团队处理;

2、等到内核更新后升级;

3、先切换到老版本的内核使用着。

2 报告Bug

如果你发现了新Bug,那么需要将详细的错误信息收集起来,提供给开发者有助于修复。

一般来说,好的Bug报告要包含很多关键信息,如:

  环境信息:软件版本、系统配置、操作系统(及版本)等;
  重现步骤:当在操作什么时会出发Bug;
  描述:触发Bug后会有什么反应、提示什么信息;
  附加信息:截图、测试脚本等;

以下是一个比较好的参考例子(来自:https://bugzilla.redhat.com/show_bug.cgi?id=1202858):

Version-Release number of selected component (if applicable):
squid.x86_64 7:3.1.23-4.el6

How reproducible:
100%

Steps to Reproduce:

1. Login to RHEL 6.7 host with squid installed
2. Start squid using "service squid start"
3. Restart squid using "service squid restart"

Actual results:
All files are deleted on the machine.

Expected results: Squid is restarted.

然后将Bug报告发送给开发者,一般的项目都有自己的Bug反馈地方,比如Github的Issue、Bugzilla等。

建议你也读读这篇文章:《如何有效地报告Bug》

2.1 举个例子

某日刚升级到Fedora 25,打开Gnome的软件管理(gnome-software),在还没有刷新完软件列表时点“软件源”,然后软件管理崩溃。

Fedora使用了ABRT作为崩溃报告工具,当发生崩溃时,以运行崩溃软件的运行身份运行gnome-abrt(比如我是用root运行gnome-software的,就用root来运行gnome-abrt),然后可以看到最近的崩溃记录。

然后点“报告”,会自动把系统信息、崩溃信息上传到Redhat的bug跟踪列表中。如果当前Bug已经被人报告,ABRT会有所提示:

1.png

若是该Bug被人报告,你也可以用Bugzilla帐号登录上去跟踪该Bug的修复情况——如果你认为对你很重要、需要跟踪修复进度的话。点开链接后可以看到处理情况:

2.png

从图中可以看出是个新Bug,还未修复,我只需等待系统更新。

3 如果我是开发者

1、根据Bug报告成功触发Bug;

2、用调试器检测行为;

3、修复Bug,找出其他地方还有不有类似Bug;

4、增加测试用例。

5、从中学习,避免以后犯同样错误:

  • 错误是如何产生的、为什么会产生?
  • 以后如何预防类似的错误?
  • 其他地方还有这样的错误吗?
  • 如何更早地检测到这个错误?
  • 有不有可以自动地检测到这个错误的方法?

6、养成良好的编程习惯:

  • 编写可测的代码,代码要满足:简单性、耦合性、单一原则;
  • 防御性编程:为无法不言自明的断言写注释;
  • 单元测试。