34

Given this gem of code:

class Program
{
    private static bool IsAdmin = true;

    static void  Main(string[] args)
    {
        if (!IsAdmin)
        {
            throw new Exception();
        }

        try
        {
            var x = 2342342;
            var y = 123132;
        }
        catch (Exception)
        {
            throw;
        }
    }
}

Given the this.IsAdmin yields true - I would expect the debugger to not enter that if statement. In reality it does - and it steps over the throw but does not actually throw!

Now this only happens when you have an exception inside an if statement followed by a try/catch block, on Visual Studio 2013, targeting .NET Framework 4, 64 bit, "Prefer 32 bit" unchecked.

I have confirmed this oddity with colleagues on different machines. Step though the following code and the debugger will seem to step into the if branch, but no exception is thrown:

enter image description here

I am in debug mode, I have tried compiling and cleaning the project multiple times.

Can anyone explain why this is happening?

mason
  • 31,774
  • 10
  • 77
  • 121
  • Nice find, the debuger does all sorts mad stuff to the IL, probably pre optimization variable reordering or something – BhavO Jul 15 '15 at 10:21

2 Answers2

29

This is a known problem caused by the x64 jitter, it occasionally generates bad debug line number info. It can fumble when a statement causes extra NOPs instructions to be generated, intended to align code. The first NOP becomes the line number, instead of the instruction after the NOPs. This bytes in a few places, like a throw statement after a simple if() test and usage of the ?? operator with simple scalar operands. These alignment NOPs are also the reason why it is so dangerous to abort threads, described in this post.

Simplest workaround is Project + Properties, Build tab, tick the "Prefer 32-bit" option if available, set the Platform target to x86 otherwise. Note how nothing actually goes wrong, while the debugger suggests that the throw statement is going to be executed your program doesn't actually throw an exception.

It is being worked on, the x64 jitter was drastically rewritten, a project named RyuJIT. It will ship in VS2015, currently in Preview.

Community
  • 1
  • 1
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
21

Check out this link. It's a known bug in some versions of visual studio and the .NET framework version. It's completely harmless and something you will just have to live with.

Nazim Kerimbekov
  • 4,712
  • 8
  • 34
  • 58
DanL
  • 1,974
  • 14
  • 13