-
-
[注意]Interlocked函数和编译器BUG产生的错误
-
发表于:
2015-6-10 08:49
4575
-
[注意]Interlocked函数和编译器BUG产生的错误
不确定是不是编译器BUG
调试Wrk的时候 出现了BUG, 模拟测试函数如下 调用了一下InterLockedOr
void TestFunc()
{
LONG TestFlag = 1;
if (!InterlockedOr(&TestFlag,1))
{
DbgPrint("Test Flag = 0\n");
}
else
{
DbgPrint("Test Flag = 1\n");
}
}
输出结果是错误的 Test Flag = 0
InterlockedOr返回值是原来的值 也就是TestFlag=1; !1=0;应该执行的是 else的语句
反汇编代码如下
808688d6 55 push ebp
808688d7 8bec mov ebp,esp
808688d9 51 push ecx
808688da 33c0 xor eax,eax
808688dc 40 inc eax
808688dd 56 push esi
808688de 8945fc mov dword ptr [ebp-4],eax
808688e1 8bc8 mov ecx,eax
808688e3 8d55fc lea edx,[ebp-4]
808688e6 8b02 mov eax,dword ptr [edx]
808688e8 8bf0 mov esi,eax
808688ea 0bf1 or esi,ecx
808688ec f00fb132 lock cmpxchg dword ptr [edx],esi
808688f0 75f6 jne nt!TestFunc+0x12 (808688e8)
808688f2 5e pop esi
808688f3 7507 jne nt!TestFunc+0x26 (808688fc)
808688f5 68b6888680 push offset nt!ObpIsUnsecureName+0x5a (808688b6) Test Flag=0;
808688fa eb05 jmp nt!TestFunc+0x2b (80868901)
808688fc 68c6888680 push offset nt!ObpIsUnsecureName+0x6a (808688c6) Test Flag=1;
80868901 e84a96ffff call nt!DbgPrint (80861f50)
80868906 59 pop ecx
80868907 c9 leave
80868908 c3 ret
808688f0
808688f3 两个JNE是同样的结果 POP ESI 不改变标志位。
[edx]=eax=ecx=esi=1;
or esi,ecx
esi=1
lock cmpxchg dword ptr [edx],esi esi=[edx]=1;
jne都不跳 也就输出了 Test Flag=0;
WRK内置的编译器cl是2003的版本
特意下了个VS2003 然后控制台测试并没有发现这个问题,不知道是哪里的问题。
GOOGLE一下
原来我不是第一个发现这个问题的
http://www.osronline.com/showThread.cfm?link=92466
注意注意,这个问题调试WRK搞了我一天。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课