`
itjavagoodqq
  • 浏览: 37285 次
文章分类
社区版块
存档分类
最新评论

找bug记(2)

阅读更多


找bug记(2)

    这篇blog迟到了很久,本来是想写另一个跟网络相关bug的查找过程,偷偷懒,写下最近印象比较深刻的bug。这个bug是我的同事水寒最终定位到的。    前几个月同事报告称有一个线上MQ集群会同一时间抛出ArrayIndexOutOfBoundsException这个异常,也就是数组越界。查看源码,除去一些无关紧要的细节大概是这样子:public class ConnectionSelector{    private AtomicInteger sets=new AtomicInteger(0);   public void selectConnection(List<Connection> connList){          if(connList==null){                return null;           }          final int size = connList.size();            if (size == 0) {                return null;            }           return connList.get(sets.incrementAndGet() % size);}   }    很显然,这里的本意是实现一个轮询的连接选择器,返回一个选中的连接。使用AtomicInteger递增并对链表大小取模,返回结果索引位置的连接。异常抛出的位置就是我代码中标红的位置。    显然,这里有两种可能,一种情况下是说在执行那一行代码的时候,connList的大小缩小了(也就是说连接可能被其他线程移出),那么导致取模的结果越界。另一种可能是取模的结果本身确实超过了列表范围。    第一种情况是完全可能的,因为服务器的连接可能随时断开或者重连,但是这种情况相对非常少见,因此我们这里并没有对这个选择过程做同步,主要是从性能的角度出发,偶尔的失败可以接受。很遗憾的是,我被我的思维惯性误导了,从来没有怀疑过第二种情况,总是认为是不是真的连接恰巧断开导致这个异常,但是却无法解释这个异常发生后就一直错误下去,无法自行恢复。    为什么说思维惯性误导呢?这里的问题其实是负数取模的问题,对一个负数进行取模,结果会是正数还是负数?答案是结果因语言而异。    我很早以前在使用Ruby的时候做过测试,负数取模结果为正数,例如在irb里尝试下:>> -1000%3=> 2>> -2001%4=> 3    这个印象持续至今,在clojure里结果也是这样子:Clojure 1.2.1user=> (mod -1000 3)2user=> (mod -2001 4)3    可以再试试python:Python 2.7.1 (r271:86832, Jun 16 2011, 16:59:05) [GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwinType "help", "copyright", "credits" or "license" for more information.>>> -10000%32>>> -2001%43    这三种语言的结果完全一致,结果都为正数。这个惯性思维延续到java却不成立了,可惜我根本没做测试,让我们试下:   public static void main(final String[] args) {        System.out.println(-1000 % 3);        System.out.println(-2001 % 4);    }打印结果为:-1-1    果然,在java里负数取模的结果为负数,而不是我习惯性地认为是正数。因此最终的定位到的原因就是sets这个变量递增超过Integer.MAX_VALUE后越界变成负数了,取模的结果为负数,导致抛出数组越界的异常,这也解释了为什么同一个集群都在同一时间出问题,因为这个集群内的机器启动时间相邻并且调用这个方法次数相对平均。修正问题很简单,加个Math.abs就好。    Update:加个abs是不够的,因为Math.abs的javadoc提醒了:Note that if the argument is equal to the value of Integer.MIN_VALUE, the most negative representable int value, the result is that same value, which is negative.     也就是说对Integer.MIN_VALUE做abs结果仍然是负数。尽管在这个场景中失败一次可以接受,但是最好的办法还是回复中steven提到的抵消符号位的做法:(sets.incrementAndGet() &amp; 0x7FFFFFFF) % size        这个问题更详细的讨论后来我找到这篇博客,作者讨论几种语言和计算器的这个问题的结果,给出了一些结论。不过我觉的这个结论可能也不是那么可靠,特别是对c/c++来说,很大程度上应该还是依赖于实现,最可靠的办法还是强制结果为正。    这个bug的几个教训:1、首先是第一次出现的时候没有引起足够重视,重启解决问题后没有深究。有句玩笑话:99%的程序问题都可以通过重启解决。但是事实上问题仍然存在,该发生的终究还会发生。不管你信不信,它就是发生了,这是一个奇迹。2、注意大脑的思维惯性,经验主义和教条主义都不可取。最近在读一本好书《暗时间》,大脑误导我们的手段可是多种多样。3、最后就是这个负数取模的结果因语言而异,不要依赖于特定实现。  

posted on 2011-09-02 00:02 dennis 阅读(2535) 评论(5)  编辑  收藏  所属分类: java 、工作随笔

2
3
分享到:
评论
2 楼 jyjava 2011-12-05  
你debug调试,应该很快会定位到的
1 楼 xuehua1987 2011-12-05  
上面的方法返回值是void ,怎么可以返回你取到的连接????其实这个Bug是很好的定位的啊。

相关推荐

    BUG跟踪流程

    bug跟踪流程,以图表的形式详细说明了如何发现BUG,回归BUG

    捉虫历险记——常见C++Bug大围剿

    本书列举大量有BUG的程序,这些程序将有助于您从其他程序员的失误中吸取教训,从而减少自己程序中的BUG。...如果您在找错的过程中陷入困境,本书所提供的大量提示会帮助您找到问题之所在,而且最后还给出了答案。

    金融IC卡(PBOC2.0,EMV借贷记)终端系统v2.3.2.2 新版本 2011.12.14

    刚刚找出了几个BUG,更新了系统的版本!! 刚刚找出了几个BUG,更新了系统的版本,欢迎“举报”BUG!! 1、本系主要为从事金融IC及POS终端开发的人员或业务人员理解PBOC2.0 EMV等规范卡交易流程而开发,界面操作...

    Android开发中记一个SwipeMenuListView侧滑删除错乱的Bug

    但是在调试运行的滑动删除数据的时候,却出现了一个问题,删除位置错乱,删除的第一个数据,却删除了最后一个,于是找问题呗,我首先用listview试了下,数据是没有问题的,那么说明是删除的时候删除的控件对位置的...

    银行金融IC卡(PBOC2.0,EMV借贷记)终端系统v2.3.2.2.rar

    刚刚找出了几个BUG,更新了系统的版本,欢迎“举报”BUG!! 1、本系主要为从事金融IC及POS终端开发的人员或业务人员理解PBOC2.0 EMV等规范卡交易流程而开发,界面操作简单,有终端属性配置及日志,结果管理功能,...

    调试信息查看器v1.3.0.52

    帮助您找出bug。 &lt;br&gt;支持包含、不包含过滤,能去掉多作的调试信息,快速找到您好的调试信息。 支持调试信息文件存储操作。您可以通知客户记录好调试输出信息文件,分析软件中存在的缺陷。

    【错误记录】WarpGAN代码运行发现的bug以及解决方法

    1. 找不到align这个模块(moudle not found error) 这个应该经常见吧hhh 常见的原因是 import 别的文件夹的py文件或者其他什么文件写错了,因为以前改过这样子的。这次是因为import的路径有些问题,仔细核对一下就...

    TrueCrypt的国内延伸版本CnCrypt1.0

    BUG修改了安装至 启动设备驱动 时返回 系统找不到指定的文件 的BUG BUG对安装界面进行全汉化,去除捐款界面 BUG修改了消息弹窗会被其它子窗口覆盖的问题。 BUG如果用户选择文件夹做为加密卷,对提示错误信息进行修正...

    01_C提高讲义.doc

    尽量少回看视频,别对视频产生依赖,可以用2倍速度回看视频。 按时完成老师布置的练习,记录练习中遇到的BUG和解决方案,根据自己的理解总结学到的知识点。 初学者 应该抓住重点,不要钻牛角尖 遇到问题了,优先...

    WSTMart多用户商城系统 2.0.5.zip

    18.修复:修复当消息模板找不到对应的消息分类时报错的bug;19.修复:修复拍卖锁定为充值金额的bug;20.修复:修复微信H5支付,某些手机使用代理IP出现“网络环境未能通过安全验证,请稍后再试”的bug;21.修复:管理员...

    Eurekalog 6.0.24 日志记录利器企业版源码安装包

    可以帮助你快速找出所编程序中的Bug,同时生成一个log文件,通过email可以发送给你。这个是版本带有适用于Delphi和BCB(Borland C++ Builder)的全部源代码。 note:EurekaLog is the new add-in tool that gives to ...

    TrueCrypt的国内延伸版本CnCrypt V1.11(单一文件绿色版)

    BUG修改了安装至 启动设备驱动 时返回 系统找不到指定的文件 的BUG BUG对安装界面进行全汉化,去除捐款界面 BUG修改了消息弹窗会被其它子窗口覆盖的问题。 BUG如果用户选择文件夹做为加密卷,对提示错误信息进行修正...

    搜索资源用的!

    大家试试吧!应该有的资源都能过搜索到的!版本 v19.01.14 新增右键菜单:转二维码 新增手动检测到新版本资源库时的提示 ...修复资源名可能获取有误的BUG 修复资源搜索可能获取有误的BUG 精简大部分代码

    文章管理系统

    5.[纠正]纠正幻灯片下面的广告位和首页栏目广告位宽度少2像素BUG 6.修复其他小细节 2013年03月02日 V2.71更新包 ★更新方式:admin文件夹改成你后台目录名,然后补丁包里的所有文件覆盖进去。 1.关键字管理的地址...

    addon-test-bug:复制

    附加测试错误重现一个错误,在该错误中找不到在include()挂钩中导入的文件,然后通过postprocessTree()将其添加到测试树中。 这是在ember-cli master中发生的,但不是在1.13.8中发生的。 只需运行npm install然后...

    WSTShop B2C单店系统 v2.0.3

    10.修复:修改第三方登录绑定帐号找不到模板文件。 11.修复:修复支付回调,当开启给管理员发短信时报错bug。 12.修复:修复获取微信用户昵称为图标导致更新数据出错的bug。 13.修复:修复只有一条评论记录时,前台...

    StrongOD v0.2.6

    5,修复IAT中序号找不到函数名的BUG [2009.01.06 v0.2.1.262] 1,增加Attach窗口的鼠标滚轮支持 2,重写od处理模块的代码 [2008.12.30 v0.2.1.252] 1,修复驱动BUG [2008.12.25 v0.2.1.235] 1,修复一个利用PAGE_...

    测试培训教材

    2.安装成功后,打开编制好的文件,选中所有要导入的需求记录,注意:只选数据. Export To Quality 3.点击“工具” Center 4.输入QC的URL地址 5.输入项目管理员的名称和密码 6.选择要导入需求的域和项目 7.选择第一...

Global site tag (gtag.js) - Google Analytics