Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>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.</p> <p>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</p> <p>Second: when debugging I found following situation:</p> <pre><code>1 if (someVariable) 2 { 3 someCode(); 4 someOtherCode(); 5 throw someExceptionPassedFromTheThirdPartyLibrary; 6 } 7 somethingElse(); </code></pre> <p>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.</p> <p>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.</p> <p>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.</p> <p>Ok I think that after some additional background it is time to explain what really happened in my code.</p> <p>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.</p> <pre><code> 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: } </code></pre> <p>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.</p> <p>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:</p> <pre><code>1 if (someVariable) 2 { 3 someCode(); 4 someOtherCode(); 5 throw someExceptionPassedFromTheThirdPartyLibrary; 6 } 7 somethingElse(); </code></pre> <p>breakpoint at 1, F10 current line indicator at 5, press F10 current line indicator at 7, press F10... and so on.</p> <p>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.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload