Roslyn: Debugger cannot break before a "using var" goes out of scope

Created on 27 Jun 2020  路  4Comments  路  Source: dotnet/roslyn

    [TestMethod]
    public void ScopeBug()
    {
        {
            using var fileStream = new FileStream(Path.GetTempFileName(), FileMode.Create);
        } //Breakpoint here
    }

Try setting a breakpoint at the indicated position.

Expected: fileStream is still usable.

Actual: fileStream has been disposed as if the closing curly brace had been executed already.

This makes it harder to debug because it is not possible to execute the entire block but not execute the Dispose call.

Tested on .NET Core 3.1, Visual Studio 16.6.0.

Area-Compilers Bug

Most helpful comment

@gafter This is a suggestion for an improvement that I believe we should implement. The reason why we emit a sequence point on } is precisely so that one can stop and inspect variables defined in the scope of the block before they go out of scope. Disposing them before this sequence point is hit defeats the purpose of the sequence point. Note that in case of using statement (e.g. using (var x = expr) { }) the declared variable is also not disposed until } is stepped over.

All 4 comments

@gafter The sequence point is probably after the Dispose call.

The curly brace is never "executed" per se, as it is not a statement. I'm not sure if this is actually a bug or just a suggestion that the feature that we implemented isn't as useful to this user as a possible different way we might have done it.

Some users might want to have the debugger stop before disposal. Some might want it to stop after disposal. Do we have a feel which is more likely or useful? This issue is a suggestion that we made the wrong decision here. But in either case, there is no way to get the other choice.

/cc @tmat @mikadumont for your thoughts on what we should do here.

@gafter This is a suggestion for an improvement that I believe we should implement. The reason why we emit a sequence point on } is precisely so that one can stop and inspect variables defined in the scope of the block before they go out of scope. Disposing them before this sequence point is hit defeats the purpose of the sequence point. Note that in case of using statement (e.g. using (var x = expr) { }) the declared variable is also not disposed until } is stepped over.

Being consistent with using ( ) { } is a very good point that has def swayed me toward Tomas' position.

Was this page helpful?
0 / 5 - 0 ratings