Я столкнулся с действительно странной проблемой, над которой я застрял.
Я работаю над библиотекой классов, которая подключается к веб-сервисам. Библиотека используется настольными приложениями.
В коде у меня сейчас:
Int32 errorCode32 = errorCode;
Int32 errorTimeout = 300;
if (errorCode32.Equals(errorTimeout) == false)
{
System.Console.Out.WriteLine("aaa");
return;
}
где errorCode равен 300. Таким образом, на первый взгляд видно, что если errorCode == 300, то код внутри оператора if не должен выполняться, поскольку он определен для выполнения только тогда, когда errorCode не равен 300 .
До сих пор все ясно, но теперь начинается все веселье.
Приложение работает, и выполняется метод с приведенным выше фрагментом кода. errorCode равен 300, ожидаемый результат состоит в том, что приложение не выполнит никакого кода внутри оператора if, поскольку весь оператор ложен. Но на самом деле приложение идет внутрь «если» и сразу же переходит к оператору «возврат». 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: }