UPDATE TO THE UPDATE (Because this is just getting lost in bizarro world)
OK, I’m now totally blow away. I noticed in my update, I was missing the period after {b}
on line 7. So, being a sticker for accuracy, I added it in.
!!!Now Line 7 also fails when you step into it!!!
What in the world????
So, now Program.cs
with more crazy results…
try
{
var a = "a";
var b = "b";
var r1 = "r";
var r1x = $"r2x1={a}.{b}.{r1}"; // < Line 6 - F10 here will give you an exception
var r1y = $"r2x1={a}.{b}" + r1; // < Line 7 - F10 here will execute just fine!
var r1z = $"r2x1={a}.{b}." + r1; // < Line 8 - F10 here will give you the exception!!!
var r1a = $"r2x1={a}.{b}{r1}"; // < Line 9 - F10 here will give you an exception
Console.WriteLine(r1x);
}
catch (NullReferenceException e)
{
Console.WriteLine(e);
}
Update
I messed around some more with this, and the issue seems to be directly related to the string interpolation. In the updated Program.cs
directly below, adding a breakpoint on Line 6 (var r1x = ...
) will create an exception if you F10
over it, will happily run if you F5
it. However also having a breakpoint on line 7 (var r1y = ...
) will happily allow you to F10
past it!
try
{
var a = "a";
var b = "b";
var r1 = "r";
var r1x = $"r2x1={a}.{b}.{r1}"; // < Line 6 - F10 here will give you an exception
var r1y = $"r2x1={a}.{b}" + r1; // < Line 7 - F10 here will execute just fine!
Console.WriteLine(r1x);
}
catch (NullReferenceException e)
{
Console.WriteLine(e);
}
Original question below
Program.cs:
try
{
var a = "a";
var b = "b";
var r1 = "r";
var r2 = "r";
r1 = $"r1={a}.{b}.{r1}";
r2 = $"r2={a}.{b}.{r2}";
Console.WriteLine(r1);
Console.WriteLine(r2);
}
catch (NullReferenceException e)
{
Console.WriteLine(e.StackTrace);
}
This silly bit of code will run just fine – if you’re not doing line by line step-through with the debugger.
However placing a breakpoint on line 8 (r2 = ...
) will drop you into the catch
with a NullReferenceException
and
System.NullReferenceException: Object reference not set to an instance of an object.
at System.Buffer.Memmove(Byte& dest, Byte& src, UIntPtr len)
at System.Runtime.CompilerServices.DefaultInterpolatedStringHandler.AppendStringDirect(String value)
at Program.<Main>$(String[] args) in /Users/rambler/tmp/Four Weeks/why/ConsoleApp1/Program.cs:line 8
Equally doing a breakpoint and line 7 will yield the same exception. Not having a breakpoint on either line will however result in an exception free execution.
I’ve tried several variations of the r1 = ...
and r2 = ...
, some which use string interpolation with r1
(or r2
respectively) and I get hard to pin down results.
All times though the code runs if I don’t try to debug that particular line.
So far this has been on my Mac using both Rider and Visual Studio Code. Going to fire up Windows later on to see if I can replicate it there as well.
This issue came to light on a much much bigger app I’m writing – and I’ve been finally able to limit it down to just this.
.net 7.0.203
2
Answers
This has been confirmed by others:
https://github.com/dotnet/runtime/issues/78991
Computed properties/values are a challenge for a debugger, for the debugger is asking a variable to compute and show a value in a time/state that the value is not meant to be accessed, or it’s in the middle of a complex operation and that is a failure caught by the debugger.
The debugger is in a type of race condition with the interpolation since the code works just fine in an application operation; there is some point where a null reference is being written or overwritten and being propagated by the debugger.
Hence one could say there is an issue with the debugger, but one codes for a real-world scenario and not a debugging scenario.
I see this all the time with classes that have properties which compute something. In the debugger it shows an
exception
for a property that is only seen during debugging.