views:

51

answers:

3

When debugging the following console program:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(DoIt(false));

        Console.WriteLine(DoIt(true));
    }

    private static Boolean DoIt(Boolean abort)
    {
        try {
            throw new InvalidOperationException();
        } catch(Exception ex) {
            if (abort) {
                return true;
            }

            Console.WriteLine("Got here");
            return false;
        }
    }
}

Why does the IDE land on the second return statement during the second call to DoIt()? The results of the execution is correct but the debugging experience is misleading.

Is this a known issue?

Is the behavior in VS 2010 the same?

A: 

it doesn't do that in VS2010. The first call to DoIt prints the Got here and hits the second return statment. The second call hits the first return statement.

gbogumil
We just tested it in VS 2010 here and it does exactly the same thing. When abort is true it hits the `return true` and then the `return false`. As I stated in the initial post, the results of the execution are correct, it's the debugging experience that is misleading.
Hellfire
I did step through and allow it to run. I am on x86 though. Didn't know about the x64 bug.
gbogumil
A: 

If you're running an optimized build, it is possible that the optimizer decided to get rid of one of the returns. This is a fairly common optimization (I have no idea why, I learn most about optimizers from observing debuggers but what they do is magic as far as I want to know:)) When that happens, the debugger (or more accuratly whoever generates the metadata the debugger is using to figure out what line of code you're on) has to pick one of them, and in your example it has a fifty fifty chance of getting it wrong.

Although it is a misleading experience, it is just part of the experience of debugging optimized code. The only alternative would be not to optimize the code, which wouldn't be good.

Stewart
I think maybe my explanation of the behavior is unclear. When `abort == true` the debugger is landing on both of the return statements, one after the other, instead of just the first one. In a DEBUG build.
Hellfire
Ah - I didn't realise it was a debug build. That seems odd. In a retail build you can see how the optimizer might turn your code into if (!abort) WriteLine(...); return abort; I think that would be a perfectly legal optimization and probably worthwhile. That would explain what the debugger is showing.
Stewart
A: 

It's a flaw in the 64-bit version of the JIT compiler. It looks like it doesn't generate entirely correct machine code address-to-statement debug mapping data. It is only somewhat accurate, the "return true" statement does actually jump to the return statement at the end of the method. But it should have hit the closing brace, not the "return false" statement.

This bug is not present in the x86 version of the JIT compiler. You typically want to use that jitter during debugging, it supports Edit+Continue. Project + Properties, Build tab, Platform Target = x86. That is automatic in VS2010 for new projects.

You can report the bug at connect.microsoft.com

Hans Passant