关于解Bug的总结

发表于:2012-2-28 10:48

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:hitlion2008    来源:51Testing软件测试网采编

  1、与其他应用交互的Bug

  背景:

  一个手机音乐播放器,多媒体通常存放在手机外部存储卡上(SDcard上)。所以只有当SD卡Mount到手机上时,才可以播放媒体。音乐播放器就会监听SD卡状态,当SD卡从手上卸载或弹出时,播放器会保存现场并停止播放;当SD卡重新Mount回手机时,再恢复现场和继续播放。也即当播放器收到“SD卡Eject”消息时,停止,当收到“SD卡Mount”时继续播放。播放器可以在后台播放媒体。

  一个文件管理器是另外一个应用程序,可以用来编辑(如删除)SD卡上的文件。文件发生变化后,这个第三方应用会发出”SD卡Mount“这样的消息,以便告知其他应用和系统,文件发生了变化。

  问题:

  当播放器在后台播放媒体的时候,起动文件管理器,然后随便删除一个文件(也可以是正在播放的媒体文件),这时候,播放器停止播放媒体,并且当打开播放器时,发现播放器是处于播放状态的,但是却没有声音。

  分析: 播放器不会没有理由的去停止正在播放的媒体。查找发现,播放器停止播放的原因有几个:用户请求停止,切换媒体时,SD卡Eject,SD卡Mount时。经过调试和跟踪日志信息,发现前面三种情况都未发生。那么问题的原因就是SD卡Mount时,进行了恢复现场的操作,导致媒体停止了。那为什么会进行恢复现场的操作呢,因为SD卡并未被Eject和Mount。进一步调试和跟踪日志发现,当文件管理器删除文件后会发出“SD卡Mount”的消息,以便告知其他应用文件发生了变化。

  解决方案:

  当分析出了问题出现的原因,解决起来就容易了,只需要让播放器在做恢复现场的动作前多一些检测来保证,先前SD卡有Eject过,现在确实是SD卡Mount回来。否则,应该忽略这个消息。

  教训:

  这应该是软件缺陷引起的Bug,音乐播放器本应该做这样的条件检查。音乐播放器本身的策略是没有错的,当没有其他应用程序发出这样的消息时,它是完全可以正常工作的。这是一个典型的与其他应用或模块交互时产生的Bug。

  对于这类Bug,最重要的线索就是,当与其他应用一起操作时会出现问题。这个Bug比较简单,因为很明确是与文件管理器有关。但在有些关系复杂的系统中,当出现了问题,很难搞清是表现问题的模块出了问题,还是其他模块出了问题。这就需要调试跟踪日志,以缩小范围。在调试的时候要一个一个模块的试验和排除,以缩小范围和进一点的深入调查。

  2、原因与问题离的很远的Bug

  背景:

  一个模块专门负责处理SD卡上的多媒体文件,解析这些文件,获取它们的元信息,并存入到媒体数据库中。它是由Java和C++以JNI方式组合来实现的。Java进行上层流程控制和写入数据库操作;C++负责解析文件获取文件元信息。它们之间通过JNI来通信。

  问题:

  当处理一个特殊的文件时候Java的JVM(虚拟机)会异常退出(JVM abort),并打印出一条错误信息:“JNI Warning: illegal start byte 0xb1”.

  分析:

  这是一个很严重的错误,因为它会导致JVM崩溃,进程也会被内核杀掉。唯一的线索就是JVM崩溃时打印出的一条信息“JNI Warning: illegal start byte 0xb1”.通过搜索这条消息(幸亏有所有的源代码),发现它是由JVM内部的CheckJNI.c文件打印出来的。这个文件是JVM中比较重要的一个文件,它负责对JNI的所有参数进行合法性检查。特别是字串。因为Java中用的是Modified UTF-8编码格式,所以CheckJNI.c文件就会对所传进来的字串进行编码检查,如果字串不是一个合法的Modified UTF-8格式,就会发出警告并停止JVM。这里找到了问题所在,是因为JVM检查到了不合法的字串才导致JVM崩溃的。那么不合法的字串是从哪里来的呢?又是出现在哪个模块呢?因为系统中有无数地方在用到JNI,所以不能盲目的去查找。又由于这是在媒体扫描器扫描某个媒体时候出现的,因此主要目标锁定在媒体扫描器的JNI部分。媒体扫描器的C++部分解析多媒体文件,然后把所得到的结果(通常为字串)通过JNI传回给Java层。问题就很有可能出在这里,因为多媒体文件的信息有多种编码格式,其中元信息就有可能是非法的Modified UTF-8编码格式。经过调试跟踪,发现,确实是这里出现了问题。

  解决方案:

  这个问题的解决方案仍不是很好,一种方法是对其进行编码转换,但这要知道字串原来的编码方式。另一咱简单的方法就是在传给JNI之前做一次编码合法性检查,以过滤到不合法的字串。最后,采用了后一方式解决了这个问题。

  教训:

  首先,系统崩溃时所给出的信息和出错时给出的信息是第一重要的线索,虽然它们可能不是问题真正的原因,但是从它们出发就可以追踪到原因。其次,错误信息,是由代码打印出来的,所以当你不知道是哪个模块出错时,可以用错误信息对源码进行局搜索,就可以定位出模块和源码位置。最后,如果是一系列的原因导致了一问题,那么可以在最源头解,也可以其中的某一个环节来解,只要不会导致程序崩溃即可。

31/3123>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号