背景:
这也是一个真实客户案例,但我不能透露代码及问题细节,只讲思想。
问题:
When performing the attached test case the xx.log becomes filled with these messages if using optimized executables:
pin : semaphore already held by holder=xxx
The messages do not happen with debug executables. One theory is a memory corruption situation.
客户说他们现场经常打印一句warning,我们对应源码查看了代码。伪代码如下:
void pin()
{
while (!flag){ sleep(1);}
if (hold > 0) {
printf("warning: holder already set\n");
exit(-1);
}
}
void unpin()
{
hold = -1; //没人持有
flag = 0; //无锁
}
pin 和unpin分数不同的进程,正如函数名所暗示分别用来上自旋锁和放自旋锁。这部分代码是不知名的前辈写的,开始只有flag的判断没有hold, 我猜测后来为了好查看自选锁到底被谁持有了才加了关于hold的代码,但是就是这暗藏BUG。
这个BUG隐藏的比较深
看到代码后我们过了好久才意识到可能有指令重排,而且是经过查看汇编代码才确认的。
主要是hold与flag的赋值的顺序在unpin中被