这两天总是被各种该死的bug 所困扰,蛮简单一个事情混在一个不大不小的工程里面确实不好找。
所以看来做大系统的时候
规范和日志就显得十分重要。
这个bug足足折腾了两天时间, 哎.....
一开始的时候真是很诡异,我在windows上面的代码怎么改都没有问题,但是Linux系统上 加了几行
无关紧要的代码(如cout之类的)却导致最后算法的准确率不一样。但是只要代码不变,跑出来的结果却总是相同的。
到底哪里来随机性,如果真是是随机的话为什么代码不变结果就不变。一开始真是百思不得其解。。
后来通过回滚代码(git),排查问题。
(这一步很重要,不知道问题在哪里的时候首先要回到以前能正确执行的版本,从大的方向去排查,
然后在准确定位)终于把问题定位到了函数级别。
我把那个函数单独用一个小的project模拟出来了。那个函数大概做了这样的事情:
static
const
char
popCountTable[] =
{
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
};
int
i[10];
int
main()
{
char
a,b;
static
int
j[1];
cout<<j<<endl;
int
result = 0;
cout<<
"fuck this "
<<endl;
cout<<
"what's wrong"
<<endl;
for
(
int
i=0; i<255; i++)
{
a = i;
b = i+10;
result += popCountTable[a^b];
}
//fdjakljfkdl;ajl
cout<<result<<endl;
return
0;
}
|
做到这一步原因就比较明显了。 原因是 a^b会产生负数。从而导致下标越界。
现在想来加了无关的代码,测试结果变了也不奇怪了 。
可能是,因为数组下标为负,产生了数组越界。而我的数组又是全局变量。可能
正好读到代码段去了。这就解释了为什么每次跑出来错误的结果还都是一样的了。。
下面这个图也正好说明全局变量段正好是在代码段的上面,进一步验证了我的猜想。
感觉好多诡异的问题都是有内存非法访问导致的,以后遇到这种问题先往这方面想一想
先用工具排查一下(vld-windows)(
valgrind-linux
)