您的位置:首页 > 其它

一个“狡猾”的bug

2015-04-23 01:22 127 查看


问题代码重现:



上面代码中,我们不(hen)难发现,在GetByte时我们需要将原来32位的DWORD先右移8的倍数位(由于32/8 = 4,我们有四种选择,所以移位可以写成(3 - off)*8 ),然后再与上0xff就好了。

好了,这个函数是OK的。重点来了,我们发现下面这个GetWord函数,在移位时,由于32位取高16位或者低16位,只有两种选择,所以这里正确写法应该是(1 - off)*16,不过我们这里竟然也是(3 - off)。

问题来了,这样的后果是什么,off肯定是0或1的,由于写成了3 - off,我们最终移的是48或者32位。

问题分析:

咦,上面不是已经分析完了吗?

No,这么简单还能叫做狡猾吗?

说它狡猾就是因为这个接口我们经常用,而且快一年了,从没发现任何问题,是不是好神(dou)奇(bi)。

不信是不?

你们可以自己试试,将一个32位数右移48或者32位,看看结果,会颠覆三观的。

到这里,可能有些同学又要提问了,既然都没问题,为啥还叫Bug?

别急,这里让你三观再次颠覆的事情发生了,它真的就这样发生了。

换成 release模式你再试试(我默认大家平时调程序都是在debug下进行的),是不是发现结果变成了0了?

好吧不卖关子了,为了抓住这只狡猾的Bug,我们的攻城狮们浴血奋战,终于在汇编层发现了一些蹊跷。

在debug模式下:我们发现原来移48位和32位分别变成移16位和0位;

而在release模式下,这行代码直接被优化掉了。

查询手册探究问题根源:

为了验证我们的猜想,特意去查了选相关文档。

Intel手册中关于SHR指令的说明:



C++(11)标准:



到这里终于真相大白了,对于这个Bug,表示根本没辙啊,单元测试一般也是在Debug下运行的。所以我们在做白盒测试时,代码的静态检查一定要做好,对于这种问题,我们仍要去努(ting)力(tian)发(you)现(ming)。





原文链接

如需转载该篇文章,请注明来自“搜狗测试”
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息