Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
214 views
in Technique[技术] by (71.8m points)

c# - Debugger stepping into if() block where condition is false

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...