if 语句工作不正确 - 反汇编对我来说没有任何解释
我遇到了一个非常奇怪的问题,并且一直困扰着我。
我正在开发一些连接到网络服务的类库。该库由桌面应用程序使用。
在我现在的代码中:
Int32 errorCode32 = errorCode;
Int32 errorTimeout = 300;
if (errorCode32.Equals(errorTimeout) == false)
{
System.Console.Out.WriteLine("aaa");
return;
}
where errorCode equals to 300。所以乍一看,如果 errorCode == 300 则 if 语句内的代码不应该被执行,因为它被定义为仅当 errorCode 为时才执行不等于300。
到现在为止一切都清楚了,但现在整个乐趣开始了。
应用程序正在运行,并且执行具有上述代码片段的方法。 errorCode 等于 300,预期结果是应用程序不会执行 if 语句内的任何代码,因为整个语句为 false。但实际上应用程序进入“if”内部并立即跳到“return”语句。 System.Console.Out...永远不会执行。如果我将干净的“return”语句替换为“throw new SomeException()”,
Int32 errorCode32 = errorCode;
Int32 errorTimeout = 300;
if (errorCode32.Equals(errorTimeout) == false)
{
System.Console.Out.WriteLine("aaa");
throw new SomeException();
}
我将得到相同的结果。应用程序进入 if 语句(注意:[errorCode32.Equals(errorTimeout) == false] 在我的情况下为 false),不执行 Console.Out... 但抛出 SomeException。
我多次重建了所有内容,删除了所有二进制文件,甚至从磁盘中删除了整个项目,然后再次从存储库将其检索到干净的文件夹。
我很困惑,以至于我什至反汇编了代码,看看会发生什么(即使我不是汇编专家)。但结果对我来说很奇怪。
反汇编代码如下:
50: Int32 errorCode32 = errorCode;
000000e5 mov eax,dword ptr [ebp-50h]
000000e8 mov dword ptr [ebp-54h],eax
51: Int32 errorTimeout = 300;
000000eb mov dword ptr [ebp-58h],12Ch
52:
53: if (errorCode32.Equals(errorTimeout) == false)
000000f2 lea ecx,[ebp-54h]
000000f5 mov edx,dword ptr [ebp-58h]
000000f8 call 699EB198
000000fd mov dword ptr [ebp-68h],eax
00000100 movzx eax,byte ptr [ebp-68h]
00000104 mov dword ptr [ebp-48h],eax
00000107 cmp dword ptr [ebp-48h],0
0000010b jne 00000134
54: {
0000010d nop
55: System.Console.Out.WriteLine("aaa");
0000010e call 69538768
00000113 mov dword ptr [ebp+FFFFFF7Ch],eax
00000119 mov edx,dword ptr ds:[0302CE30h]
0000011f mov ecx,dword ptr [ebp+FFFFFF7Ch]
00000125 mov eax,dword ptr [ecx]
00000127 call dword ptr [eax+000000D8h]
0000012d nop
56: return;
0000012e nop
0000012f jmp 00000287
00000134 mov eax,dword ptr ds:[0302CE34h]
0000013a mov dword ptr [ebp-6Ch],eax
0000013d mov edx,5
00000142 mov ecx,6EDE3FBEh
00000147 call FA68D488
0000014c mov dword ptr [ebp-70h],eax
57: }
当我调试指令时,我可以理解发生了什么,直到行:
00000104 mov dword ptr [ebp-48h],eax
我期望存储在 eax 中的值将被复制到位置“dword ptr [ebp-48h]”并且应用程序将转到下一行(00000107)。但这并没有发生。当我尝试跨过第 00000104 行时,应用程序立即跳转到
00000134 mov eax,dword ptr ds:[0302CE34h]
我无法理解这里发生的情况的行。我尝试在互联网上搜索,但找不到任何有用的东西。有人对问题的原因或如何解决有任何建议吗?
编辑
我忘记添加我正在使用 Visual Studio 2008 并编译成 .NET 3.5 的信息。 所有更新均已安装。
在 C# 中编辑
整个方法
private void nativeDocumentServiceWrapper_PostInvokeEvents(object sender, WebServiceInvokeEventArgs e)
{
Exception exception = e.Exception;
if (exception == null)
{
_invokeRetries = 0;
return;
}
string errorCodeString = ErrorHandler.GetErrorCodeString(exception);
int errorCode;
if (int.TryParse(errorCodeString, out errorCode))
{
e.Exception = new VaultException(errorCode, exception);
}
Int32 errorCode32 = errorCode;
Int32 errorTimeout = 300;
if (errorCode32.Equals(errorTimeout) == false)
{
System.Console.Out.WriteLine("aaa");
return;
}
Trace.TraceWarning("Invoke failed (count: {4}) {0}.{1} #{2} error '{3}'", _moduleName, e.MethodName, _id, errorCodeString, _invokeRetries + 1);
if (_invokeRetries > 0)
{
//int errorCode;
if (int.TryParse(errorCodeString, out errorCode))
{
//throw new VaultException(errorCode, exception);
e.Exception = new VaultException(errorCode, exception);
}
return;
}
e.Exception = null;
// we ran into error 300 or 319
// the solution is to log in again and re-run the command
tryReloginAndInvokeVaultMethodAgain(e);
}
并反汇编:
34: private void nativeDocumentServiceWrapper_PostInvokeEvents(object sender, WebServiceInvokeEventArgs e)
35: {
00000000 push ebp
00000001 mov ebp,esp
00000003 push edi
00000004 push esi
00000005 push ebx
00000006 sub esp,84h
0000000c mov esi,ecx
0000000e lea edi,[ebp-54h]
00000011 mov ecx,12h
00000016 xor eax,eax
00000018 rep stos dword ptr es:[edi]
0000001a mov ecx,esi
0000001c xor eax,eax
0000001e mov dword ptr [ebp-1Ch],eax
00000021 mov dword ptr [ebp-3Ch],ecx
00000024 mov dword ptr [ebp-40h],edx
00000027 cmp dword ptr ds:[01AD2DD8h],0
0000002e je 00000035
00000030 call 6AB8A719
00000035 mov dword ptr [ebp-48h],0
0000003c xor edx,edx
0000003e mov dword ptr [ebp-5Ch],edx
00000041 xor edx,edx
00000043 mov dword ptr [ebp-44h],edx
00000046 xor edx,edx
00000048 mov dword ptr [ebp-4Ch],edx
0000004b xor edx,edx
0000004d mov dword ptr [ebp-58h],edx
00000050 nop
36: Exception exception = e.Exception;
00000051 mov eax,dword ptr [ebp+8]
00000054 mov eax,dword ptr [eax+4]
00000057 mov dword ptr [ebp-44h],eax
37: if (exception == null)
0000005a cmp dword ptr [ebp-44h],0
0000005e setne al
00000061 movzx eax,al
00000064 mov dword ptr [ebp-48h],eax
00000067 cmp dword ptr [ebp-48h],0
0000006b jne 0000007F
38: {
0000006d nop
39: _invokeRetries = 0;
0000006e mov eax,dword ptr [ebp-3Ch]
00000071 xor edx,edx
00000073 mov dword ptr [eax+00000088h],edx
40: return;
00000079 nop
0000007a jmp 00000287
41: }
42:
43: string errorCodeString = ErrorHandler.GetErrorCodeString(exception);
0000007f mov ecx,dword ptr [ebp-44h]
00000082 call FF0827F0
00000087 mov dword ptr [ebp-60h],eax
0000008a mov eax,dword ptr [ebp-60h]
0000008d mov dword ptr [ebp-4Ch],eax
44: int errorCode;
45: if (int.TryParse(errorCodeString, out errorCode))
00000090 lea edx,[ebp-50h]
00000093 mov ecx,dword ptr [ebp-4Ch]
00000096 call 694B44A8
0000009b mov dword ptr [ebp-64h],eax
0000009e cmp dword ptr [ebp-64h],0
000000a2 sete al
000000a5 movzx eax,al
000000a8 mov dword ptr [ebp-48h],eax
000000ab cmp dword ptr [ebp-48h],0
000000af jne 000000E5
46: {
000000b1 nop
47: e.Exception = new VaultException(errorCode, exception);
000000b2 mov ecx,5482E0Ch
000000b7 call FA68D364
000000bc mov dword ptr [ebp+FFFFFF78h],eax
000000c2 push dword ptr [ebp-44h]
000000c5 mov edx,dword ptr [ebp-50h]
000000c8 mov ecx,dword ptr [ebp+FFFFFF78h]
000000ce call FF07FCB0
000000d3 mov edx,dword ptr [ebp+8]
000000d6 mov eax,dword ptr [ebp+FFFFFF78h]
000000dc lea edx,[edx+4]
000000df call 6A90E288
48: }
000000e4 nop
49:
50: Int32 errorCode32 = errorCode;
000000e5 mov eax,dword ptr [ebp-50h]
000000e8 mov dword ptr [ebp-54h],eax
51: Int32 errorTimeout = 300;
000000eb mov dword ptr [ebp-58h],12Ch
52:
53: if (errorCode32.Equals(errorTimeout) == false)
000000f2 lea ecx,[ebp-54h]
000000f5 mov edx,dword ptr [ebp-58h]
000000f8 call 699EB198
000000fd mov dword ptr [ebp-68h],eax
00000100 movzx eax,byte ptr [ebp-68h]
00000104 mov dword ptr [ebp-48h],eax
00000107 cmp dword ptr [ebp-48h],0
0000010b jne 00000134
54: {
0000010d nop
55: System.Console.Out.WriteLine("aaa");
0000010e call 69538768
00000113 mov dword ptr [ebp+FFFFFF7Ch],eax
00000119 mov edx,dword ptr ds:[0302CE30h]
0000011f mov ecx,dword ptr [ebp+FFFFFF7Ch]
00000125 mov eax,dword ptr [ecx]
00000127 call dword ptr [eax+000000D8h]
0000012d nop
56: return;
0000012e nop
0000012f jmp 00000287
00000134 mov eax,dword ptr ds:[0302CE34h]
0000013a mov dword ptr [ebp-6Ch],eax
0000013d mov edx,5
00000142 mov ecx,6EDE3FBEh
00000147 call FA68D488
0000014c mov dword ptr [ebp-70h],eax
57: }
58:
59: Trace.TraceWarning("Invoke failed (count: {4}) {0}.{1} #{2} error '{3}'", _moduleName, e.MethodName, _id, errorCodeString, _invokeRetries + 1);
0000014f mov eax,dword ptr [ebp-70h]
00000152 mov dword ptr [ebp-5Ch],eax
00000155 mov eax,dword ptr [ebp-3Ch]
00000158 push dword ptr [eax+00000080h]
0000015e mov ecx,dword ptr [ebp-5Ch]
00000161 xor edx,edx
00000163 call 6A914654
00000168 mov eax,dword ptr [ebp+8]
0000016b push dword ptr [eax+8]
0000016e mov ecx,dword ptr [ebp-5Ch]
00000171 mov edx,1
00000176 call 6A914654
0000017b mov ecx,6F052DA0h
00000180 call FA68D364
00000185 mov dword ptr [ebp-74h],eax
00000188 mov eax,dword ptr [ebp-5Ch]
0000018b mov dword ptr [ebp+FFFFFF74h],eax
00000191 mov eax,dword ptr [ebp-3Ch]
00000194 mov eax,dword ptr [eax+00000084h]
0000019a mov edx,dword ptr [ebp-74h]
0000019d mov dword ptr [edx+4],eax
000001a0 mov eax,dword ptr [ebp-74h]
000001a3 push eax
000001a4 mov ecx,dword ptr [ebp+FFFFFF74h]
000001aa mov edx,2
000001af call 6A914654
000001b4 push dword ptr [ebp-4Ch]
000001b7 mov ecx,dword ptr [ebp-5Ch]
000001ba mov edx,3
000001bf call 6A914654
000001c4 mov ecx,6F052DA0h
000001c9 call FA68D364
000001ce mov dword ptr [ebp-78h],eax
000001d1 mov eax,dword ptr [ebp-5Ch]
000001d4 mov dword ptr [ebp+FFFFFF70h],eax
000001da mov eax,dword ptr [ebp-3Ch]
000001dd mov eax,dword ptr [eax+00000088h]
000001e3 inc eax
000001e4 mov edx,dword ptr [ebp-78h]
000001e7 mov dword ptr [edx+4],eax
000001ea mov eax,dword ptr [ebp-78h]
000001ed push eax
000001ee mov ecx,dword ptr [ebp+FFFFFF70h]
000001f4 mov edx,4
000001f9 call 6A914654
000001fe mov edx,dword ptr [ebp-5Ch]
00000201 mov ecx,dword ptr [ebp-6Ch]
00000204 call 69039D88
00000209 nop
60:
61: if (_invokeRetries > 0)
0000020a mov eax,dword ptr [ebp-3Ch]
0000020d cmp dword ptr [eax+00000088h],0
00000214 setle al
00000217 movzx eax,al
0000021a mov dword ptr [ebp-48h],eax
0000021d cmp dword ptr [ebp-48h],0
00000221 jne 00000273
62: {
00000223 nop
63: //int errorCode;
64: if (int.TryParse(errorCodeString, out errorCode))
00000224 lea edx,[ebp-50h]
00000227 mov ecx,dword ptr [ebp-4Ch]
0000022a call 694B44A8
0000022f mov dword ptr [ebp-7Ch],eax
00000232 cmp dword ptr [ebp-7Ch],0
00000236 sete al
00000239 movzx eax,al
0000023c mov dword ptr [ebp-48h],eax
0000023f cmp dword ptr [ebp-48h],0
00000243 jne 00000270
65: {
00000245 nop
66: //throw new VaultException(errorCode, exception);
67: e.Exception = new VaultException(errorCode, exception);
00000246 mov ecx,5482E0Ch
0000024b call FA68D364
00000250 mov dword ptr [ebp-80h],eax
00000253 push dword ptr [ebp-44h]
00000256 mov edx,dword ptr [ebp-50h]
00000259 mov ecx,dword ptr [ebp-80h]
0000025c call FF07FCB0
00000261 mov edx,dword ptr [ebp+8]
00000264 mov eax,dword ptr [ebp-80h]
00000267 lea edx,[edx+4]
0000026a call 6A90E288
68: }
0000026f nop
69: return;
00000270 nop
00000271 jmp 00000287
70: }
71:
72: e.Exception = null;
00000273 mov eax,dword ptr [ebp+8]
00000276 xor edx,edx
00000278 mov dword ptr [eax+4],edx
73:
74: // we ran into error 300 or 319
75: // the solution is to log in again and re-run the command
76:
77: tryReloginAndInvokeVaultMethodAgain(e);
0000027b mov edx,dword ptr [ebp+8]
0000027e mov ecx,dword ptr [ebp-3Ch]
00000281 call FF0876C0
00000286 nop
78: }
I encounter really weird problem on which I stuck.
I am working on some class library which connects to webservices. The library is used by desktop applications.
In the code I have now:
Int32 errorCode32 = errorCode;
Int32 errorTimeout = 300;
if (errorCode32.Equals(errorTimeout) == false)
{
System.Console.Out.WriteLine("aaa");
return;
}
where errorCode equals to 300. So at the first glance it is visible, that if errorCode == 300 than the code inside the if statement should not be executed because it is defined to be executed only when errorCode is not equal to 300.
Until now everything is clear, but now the whole fun starts.
Application is working and the method with above code snippet is executed. errorCode is equal to 300, that is expected result is that the application will not execute any code inside if statement because whole statement is false. But in reality application goes inside "if" and immediately skips to the "return" statement. System.Console.Out... is never executed. If I will replace clean "return" statement with "throw new SomeException()"
Int32 errorCode32 = errorCode;
Int32 errorTimeout = 300;
if (errorCode32.Equals(errorTimeout) == false)
{
System.Console.Out.WriteLine("aaa");
throw new SomeException();
}
I will get the same result. Application goes into if statement (note: [errorCode32.Equals(errorTimeout) == false] is false in my case), don't execute Console.Out... but throws SomeException.
I rebuilded everything several times, deleted all binaries, I even deleted whole project from disk and retrieved it again from repository to clean folder.
I was so confused that I even disassembled the code to see what happens (even if I am not an expert in assembler). But results are strange for me.
Disassembled code follows:
50: Int32 errorCode32 = errorCode;
000000e5 mov eax,dword ptr [ebp-50h]
000000e8 mov dword ptr [ebp-54h],eax
51: Int32 errorTimeout = 300;
000000eb mov dword ptr [ebp-58h],12Ch
52:
53: if (errorCode32.Equals(errorTimeout) == false)
000000f2 lea ecx,[ebp-54h]
000000f5 mov edx,dword ptr [ebp-58h]
000000f8 call 699EB198
000000fd mov dword ptr [ebp-68h],eax
00000100 movzx eax,byte ptr [ebp-68h]
00000104 mov dword ptr [ebp-48h],eax
00000107 cmp dword ptr [ebp-48h],0
0000010b jne 00000134
54: {
0000010d nop
55: System.Console.Out.WriteLine("aaa");
0000010e call 69538768
00000113 mov dword ptr [ebp+FFFFFF7Ch],eax
00000119 mov edx,dword ptr ds:[0302CE30h]
0000011f mov ecx,dword ptr [ebp+FFFFFF7Ch]
00000125 mov eax,dword ptr [ecx]
00000127 call dword ptr [eax+000000D8h]
0000012d nop
56: return;
0000012e nop
0000012f jmp 00000287
00000134 mov eax,dword ptr ds:[0302CE34h]
0000013a mov dword ptr [ebp-6Ch],eax
0000013d mov edx,5
00000142 mov ecx,6EDE3FBEh
00000147 call FA68D488
0000014c mov dword ptr [ebp-70h],eax
57: }
when I am debugging instructions I can understand what happens until the line:
00000104 mov dword ptr [ebp-48h],eax
I expect that value stored in eax will be copied to location "dword ptr [ebp-48h]" and application wiil go to next line (00000107). But this doesn't happen. When I am trying to step over line 00000104, application immediately jumps to line
00000134 mov eax,dword ptr ds:[0302CE34h]
I cannot understand what happens here. I tried to search over internet but I couldn't find anything useful. Does anybody have any suggestions what could be the reason of the problem or how to solve that?
Edit
I forgot to put information that I am using Visual Studio 2008 and compiling into .NET 3.5.
All updates are installed.
Edit
Entire method in C#
private void nativeDocumentServiceWrapper_PostInvokeEvents(object sender, WebServiceInvokeEventArgs e)
{
Exception exception = e.Exception;
if (exception == null)
{
_invokeRetries = 0;
return;
}
string errorCodeString = ErrorHandler.GetErrorCodeString(exception);
int errorCode;
if (int.TryParse(errorCodeString, out errorCode))
{
e.Exception = new VaultException(errorCode, exception);
}
Int32 errorCode32 = errorCode;
Int32 errorTimeout = 300;
if (errorCode32.Equals(errorTimeout) == false)
{
System.Console.Out.WriteLine("aaa");
return;
}
Trace.TraceWarning("Invoke failed (count: {4}) {0}.{1} #{2} error '{3}'", _moduleName, e.MethodName, _id, errorCodeString, _invokeRetries + 1);
if (_invokeRetries > 0)
{
//int errorCode;
if (int.TryParse(errorCodeString, out errorCode))
{
//throw new VaultException(errorCode, exception);
e.Exception = new VaultException(errorCode, exception);
}
return;
}
e.Exception = null;
// we ran into error 300 or 319
// the solution is to log in again and re-run the command
tryReloginAndInvokeVaultMethodAgain(e);
}
and disassembled:
34: private void nativeDocumentServiceWrapper_PostInvokeEvents(object sender, WebServiceInvokeEventArgs e)
35: {
00000000 push ebp
00000001 mov ebp,esp
00000003 push edi
00000004 push esi
00000005 push ebx
00000006 sub esp,84h
0000000c mov esi,ecx
0000000e lea edi,[ebp-54h]
00000011 mov ecx,12h
00000016 xor eax,eax
00000018 rep stos dword ptr es:[edi]
0000001a mov ecx,esi
0000001c xor eax,eax
0000001e mov dword ptr [ebp-1Ch],eax
00000021 mov dword ptr [ebp-3Ch],ecx
00000024 mov dword ptr [ebp-40h],edx
00000027 cmp dword ptr ds:[01AD2DD8h],0
0000002e je 00000035
00000030 call 6AB8A719
00000035 mov dword ptr [ebp-48h],0
0000003c xor edx,edx
0000003e mov dword ptr [ebp-5Ch],edx
00000041 xor edx,edx
00000043 mov dword ptr [ebp-44h],edx
00000046 xor edx,edx
00000048 mov dword ptr [ebp-4Ch],edx
0000004b xor edx,edx
0000004d mov dword ptr [ebp-58h],edx
00000050 nop
36: Exception exception = e.Exception;
00000051 mov eax,dword ptr [ebp+8]
00000054 mov eax,dword ptr [eax+4]
00000057 mov dword ptr [ebp-44h],eax
37: if (exception == null)
0000005a cmp dword ptr [ebp-44h],0
0000005e setne al
00000061 movzx eax,al
00000064 mov dword ptr [ebp-48h],eax
00000067 cmp dword ptr [ebp-48h],0
0000006b jne 0000007F
38: {
0000006d nop
39: _invokeRetries = 0;
0000006e mov eax,dword ptr [ebp-3Ch]
00000071 xor edx,edx
00000073 mov dword ptr [eax+00000088h],edx
40: return;
00000079 nop
0000007a jmp 00000287
41: }
42:
43: string errorCodeString = ErrorHandler.GetErrorCodeString(exception);
0000007f mov ecx,dword ptr [ebp-44h]
00000082 call FF0827F0
00000087 mov dword ptr [ebp-60h],eax
0000008a mov eax,dword ptr [ebp-60h]
0000008d mov dword ptr [ebp-4Ch],eax
44: int errorCode;
45: if (int.TryParse(errorCodeString, out errorCode))
00000090 lea edx,[ebp-50h]
00000093 mov ecx,dword ptr [ebp-4Ch]
00000096 call 694B44A8
0000009b mov dword ptr [ebp-64h],eax
0000009e cmp dword ptr [ebp-64h],0
000000a2 sete al
000000a5 movzx eax,al
000000a8 mov dword ptr [ebp-48h],eax
000000ab cmp dword ptr [ebp-48h],0
000000af jne 000000E5
46: {
000000b1 nop
47: e.Exception = new VaultException(errorCode, exception);
000000b2 mov ecx,5482E0Ch
000000b7 call FA68D364
000000bc mov dword ptr [ebp+FFFFFF78h],eax
000000c2 push dword ptr [ebp-44h]
000000c5 mov edx,dword ptr [ebp-50h]
000000c8 mov ecx,dword ptr [ebp+FFFFFF78h]
000000ce call FF07FCB0
000000d3 mov edx,dword ptr [ebp+8]
000000d6 mov eax,dword ptr [ebp+FFFFFF78h]
000000dc lea edx,[edx+4]
000000df call 6A90E288
48: }
000000e4 nop
49:
50: Int32 errorCode32 = errorCode;
000000e5 mov eax,dword ptr [ebp-50h]
000000e8 mov dword ptr [ebp-54h],eax
51: Int32 errorTimeout = 300;
000000eb mov dword ptr [ebp-58h],12Ch
52:
53: if (errorCode32.Equals(errorTimeout) == false)
000000f2 lea ecx,[ebp-54h]
000000f5 mov edx,dword ptr [ebp-58h]
000000f8 call 699EB198
000000fd mov dword ptr [ebp-68h],eax
00000100 movzx eax,byte ptr [ebp-68h]
00000104 mov dword ptr [ebp-48h],eax
00000107 cmp dword ptr [ebp-48h],0
0000010b jne 00000134
54: {
0000010d nop
55: System.Console.Out.WriteLine("aaa");
0000010e call 69538768
00000113 mov dword ptr [ebp+FFFFFF7Ch],eax
00000119 mov edx,dword ptr ds:[0302CE30h]
0000011f mov ecx,dword ptr [ebp+FFFFFF7Ch]
00000125 mov eax,dword ptr [ecx]
00000127 call dword ptr [eax+000000D8h]
0000012d nop
56: return;
0000012e nop
0000012f jmp 00000287
00000134 mov eax,dword ptr ds:[0302CE34h]
0000013a mov dword ptr [ebp-6Ch],eax
0000013d mov edx,5
00000142 mov ecx,6EDE3FBEh
00000147 call FA68D488
0000014c mov dword ptr [ebp-70h],eax
57: }
58:
59: Trace.TraceWarning("Invoke failed (count: {4}) {0}.{1} #{2} error '{3}'", _moduleName, e.MethodName, _id, errorCodeString, _invokeRetries + 1);
0000014f mov eax,dword ptr [ebp-70h]
00000152 mov dword ptr [ebp-5Ch],eax
00000155 mov eax,dword ptr [ebp-3Ch]
00000158 push dword ptr [eax+00000080h]
0000015e mov ecx,dword ptr [ebp-5Ch]
00000161 xor edx,edx
00000163 call 6A914654
00000168 mov eax,dword ptr [ebp+8]
0000016b push dword ptr [eax+8]
0000016e mov ecx,dword ptr [ebp-5Ch]
00000171 mov edx,1
00000176 call 6A914654
0000017b mov ecx,6F052DA0h
00000180 call FA68D364
00000185 mov dword ptr [ebp-74h],eax
00000188 mov eax,dword ptr [ebp-5Ch]
0000018b mov dword ptr [ebp+FFFFFF74h],eax
00000191 mov eax,dword ptr [ebp-3Ch]
00000194 mov eax,dword ptr [eax+00000084h]
0000019a mov edx,dword ptr [ebp-74h]
0000019d mov dword ptr [edx+4],eax
000001a0 mov eax,dword ptr [ebp-74h]
000001a3 push eax
000001a4 mov ecx,dword ptr [ebp+FFFFFF74h]
000001aa mov edx,2
000001af call 6A914654
000001b4 push dword ptr [ebp-4Ch]
000001b7 mov ecx,dword ptr [ebp-5Ch]
000001ba mov edx,3
000001bf call 6A914654
000001c4 mov ecx,6F052DA0h
000001c9 call FA68D364
000001ce mov dword ptr [ebp-78h],eax
000001d1 mov eax,dword ptr [ebp-5Ch]
000001d4 mov dword ptr [ebp+FFFFFF70h],eax
000001da mov eax,dword ptr [ebp-3Ch]
000001dd mov eax,dword ptr [eax+00000088h]
000001e3 inc eax
000001e4 mov edx,dword ptr [ebp-78h]
000001e7 mov dword ptr [edx+4],eax
000001ea mov eax,dword ptr [ebp-78h]
000001ed push eax
000001ee mov ecx,dword ptr [ebp+FFFFFF70h]
000001f4 mov edx,4
000001f9 call 6A914654
000001fe mov edx,dword ptr [ebp-5Ch]
00000201 mov ecx,dword ptr [ebp-6Ch]
00000204 call 69039D88
00000209 nop
60:
61: if (_invokeRetries > 0)
0000020a mov eax,dword ptr [ebp-3Ch]
0000020d cmp dword ptr [eax+00000088h],0
00000214 setle al
00000217 movzx eax,al
0000021a mov dword ptr [ebp-48h],eax
0000021d cmp dword ptr [ebp-48h],0
00000221 jne 00000273
62: {
00000223 nop
63: //int errorCode;
64: if (int.TryParse(errorCodeString, out errorCode))
00000224 lea edx,[ebp-50h]
00000227 mov ecx,dword ptr [ebp-4Ch]
0000022a call 694B44A8
0000022f mov dword ptr [ebp-7Ch],eax
00000232 cmp dword ptr [ebp-7Ch],0
00000236 sete al
00000239 movzx eax,al
0000023c mov dword ptr [ebp-48h],eax
0000023f cmp dword ptr [ebp-48h],0
00000243 jne 00000270
65: {
00000245 nop
66: //throw new VaultException(errorCode, exception);
67: e.Exception = new VaultException(errorCode, exception);
00000246 mov ecx,5482E0Ch
0000024b call FA68D364
00000250 mov dword ptr [ebp-80h],eax
00000253 push dword ptr [ebp-44h]
00000256 mov edx,dword ptr [ebp-50h]
00000259 mov ecx,dword ptr [ebp-80h]
0000025c call FF07FCB0
00000261 mov edx,dword ptr [ebp+8]
00000264 mov eax,dword ptr [ebp-80h]
00000267 lea edx,[edx+4]
0000026a call 6A90E288
68: }
0000026f nop
69: return;
00000270 nop
00000271 jmp 00000287
70: }
71:
72: e.Exception = null;
00000273 mov eax,dword ptr [ebp+8]
00000276 xor edx,edx
00000278 mov dword ptr [eax+4],edx
73:
74: // we ran into error 300 or 319
75: // the solution is to log in again and re-run the command
76:
77: tryReloginAndInvokeVaultMethodAgain(e);
0000027b mov edx,dword ptr [ebp+8]
0000027e mov ecx,dword ptr [ebp-3Ch]
00000281 call FF0876C0
00000286 nop
78: }
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您启用了优化,并且编译器将 if 语句内的 return 语句与函数末尾的语句组合在一起。两者具有相同的地址,调试器无法分辨要突出显示哪一行源代码,因为两者匹配。
没有任何问题。但如果您希望单步执行调试器正常工作,则必须禁用优化。
这只是优化器可以用来迷惑调试器的几件事之一。其他可能性是重新排序不具有数据依赖性的语句(以优化管道),甚至将语句分开并在其间放置另一个语句。
You have optimization enabled, and the compiler combined the return statement inside the
if
statement with the one at the end of the function. The two have the same address, the debugger can't tell which line of source code to highlight, because both match.There's nothing wrong whatsoever. But if you want stepping through the debugger to work normally, you have to disable optimization.
This is only one of several things the optimizer can do to confuse the debugger. Other possibilities are reordering statements that don't have a data dependency (to optimize the pipeline), even splitting statements apart and putting another statement in between.
我花了更多时间调查这个问题,并得出了一些结论,我想与大家分享,即使这意味着我必须承认我做出了一些错误的假设,并且我无法全面了解整个行为。
首先:我提供的代码旨在处理使用某些第三方库时的某些特定问题。这些库的未记录行为是,在某些情况下它会在某些条件下引发异常。最初的问题来自这样一个事实,即使我们“处理”错误情况,该库也会抛出异常
第二:调试时我发现以下情况:
调试器在第 1 行停止,someVariable 为 false,单步跳过,调试器在第 5 行等待。我做了第一个错误的假设 - 那就是我的异常是从这里抛出的。
第三:我开始尝试。 “someVariable”始终为 false,但有时调试器会从第 1 行跳到第 7 行,有时会从第 1 行跳到第 5 行。我决定使用反汇编程序。
第四:我无法理解反汇编代码的行为,它使我的想法固定下来,即 if 语句行为不正确。另外,我发现文章“http://stackoverflow.com/questions/6054987/if-statement-appears-to-be-evaluating-even-when-condition-evaluates-to-false”[确认的 JIT bug] 没有这次帮了我。
好吧,我认为在了解了一些额外的背景知识之后,是时候解释一下我的代码中到底发生了什么。
一般来说,在我的情况下,“if”语句的行为正确。当我更多地了解汇编器和现代处理器架构时,我明白了这一点。
偏移量 00000104-0000010b 处的指令执行已由处理器架构优化(可能发生跳转预测,或一些其他核心处理器优化)。因此,处理器不再调用三条指令,而是一步执行所有操作。因为 00000107 中应该比较的值不相等,所以处理器跳转到 00000134。此时我无法理解这里实际发生的情况,所以我假设它只是执行“return”指令。事实很简单 - “从 if 返回”指令并不像我那样位于 00000134,而是指令区域 - 在 0000012f,这只是简单的无条件跳转。
当我理解这一点时,我知道这段代码的行为是正确的。所以我再次转向C#,我发现了一些让我非常羞愧的东西。因为当我再次调试代码时,我发现它的行为是这样的:
断点在1,F10
当前行指示器位于 5,按 F10
当前行指示器位于 7,按 F10...,依此类推。
所以我知道调试器会执行最后一个“if”指令,但不会执行该指令。这是一个错误 - 但不在“if”处理中,而仅在 VS 调试器中。此外,该错误并不重要,因为它实际上只是演示,对调试的代码没有任何影响。
I spent more time investigating the problem and I have some conclusions which I would like to share, even if it means that I must to admit that I made several false assumptions and I was not able to get a big picture of whole behavior.
First: the code which I presented was intended to handle some particular problem when using some third party library. The undocumented behavior of those library was that in some situation it throws exception on some conditions. Original problem comes from the fact, that library throwed exception even if we "handled" error situation
Second: when debugging I found following situation:
debugger stopped at line 1, someVariable is false, step over, debugger is waiting at line 5. And here I made a first false assumption - that is that my exception is thrown from here.
Third: I started to experiment. "someVariable" was always false, but sometimes debugger skipped from line 1 to 7 and sometimes from 1 to 5. I decided to use disassembler.
Fourth: I couldn't understand behavior of disassembled code and it fixed my mind on idea, that if statement behaves incorrectly. Additionally I found article "http://stackoverflow.com/questions/6054987/if-statement-appears-to-be-evaluating-even-when-condition-evaluates-to-false" [confirmed JIT bug] which didn't helped me this time.
Ok I think that after some additional background it is time to explain what really happened in my code.
In general in my situation "if" statement behaved correctly. I understood that when I learned a little bit more regarding assembler and moder processor architecture.
Execution of instructions at offsets 00000104-0000010b was optimized by processor architecture (perhaps jump predicting takes place, or some other core processor optimizations). So instead of calling three instructions, processor executed everything in one step. Because values which should be compared in 00000107 were not equal, so processor jumped to 00000134. At this point I couldn't understand what actually happens here, so I assumed that it just executes "return" instruction. The truth is simple - "return from if" instruction is not at 00000134 as I though, but instruction arealier - at 0000012f and this is just simple unconditional jump.
When I understood this I knew that this code behaves corretly. So I moved again to C# and I found something which made me really ashamed. Because when I debugged the code once again I found that it behaves this way:
breakpoint at 1, F10
current line indicator at 5, press F10
current line indicator at 7, press F10... and so on.
So I understood that the debugger steps inside last "if" instruction, but doesn't execute that. It is a bug - but not in "if" handling, and only in VS debugger. Additionally the bug is not critical since it is actually just presentation and doesn't have any influence on the debugged code.