runtime: Debugger does not correctly handle bytes without a backing field.
NOTE: Relevant bits copied from https://github.com/dotnet/coreclr/issues/15694 Related Bugs: https://github.com/dotnet/coreclr/issues/10148
Any byte which is not explicitly covered by a field is not visible to the debugger. This includes padding bytes, additional bytes allocated by an explicitly sized struct, etc.
This is true when looking at the values via the locals window, watch windows, or immediate windows.
Ex 1:
struct Data
{
byte _0;
// implicit padding byte
// implicit padding byte
// implicit padding byte
int _4;
}
The three implicit padding bytes are always 0 in the debugger. That is, when accessing via ((byte*)&data)[1]
in the watch/immediate. There is no expectation for these bytes to be visible in the locals window.
Ex 2:
[StructLayout(LayoutKind.Sequential, Size = 16)]
struct Vector128<T> where T : struct { }
All of the 16-bytes in Vector128<T>
are implicit (no field exists that maps directly to those bytes), so all 16-bytes are always 0. Likewise, if viewing the raw bits via aliasing (((byte*)&data)[1]
). There is no expectation for these bytes to be visible in the locals window.
Ex 3:
struct Vector<T>
{
private Register register;
}
[StructLayout(LayoutKind.Explicit)]
struct Register
{
[FieldOffset(0)]
internal Double double_0;
[FieldOffset(8)]
internal Double double_1;
// Other overlapping fields
}
On an AVX machine, Vector<T>
is explicitly sized to 32, so the latter 16 bytes (which are not directly mapped to a field) are not accessible. This is expected to work in the immediate, watch, and locals window
Ex 4:
internal unsafe struct MyBuffer
{
public fixed char fixedBuffer[128];
}
The full set of 128 values are expected to be visible in the locals window, much like an actual array would allow. They should likewise be visible via evaluation in the immediate or watch window, such as via myBuffer.fixedBuffer[5]
.
About this issue
- Original URL
- State: open
- Created 6 years ago
- Reactions: 12
- Comments: 21 (19 by maintainers)
Had another user hit this and ping me on Twitter.
@tommcdon, Given this issue has been present for over 4 years, has had a plethora of duplicate issues, and gets at least a couple new hits/asks per release, can we please look at reprioritizing it?
Thanks for the feedback @tannergooding . We will evaluate this request for .NET 8
Please fix this, I just spent a significant amount of time convinced that I did not really understand how to create a Vector<long> from a Span<long> because of this bug.
@tommcdon, is this something that you could point me to the sources for and I could take a look at getting a small fix in for?
The more general fix is likely more complex, but handling
Vector<T>
itself could likely just be a simple special-case.@tannergooding thanks! I have changed the milestone from Future to 5.0, so this item is on our 5.0 backlog.
Tested on .NET 8 locally and it looks to also be resolved for fixed sized buffers.
I just re-tested this and my conclusion is that it reproduces if you target .NET 6.0, but it does NOT reproduce if you target .NET 7.0.
So perhaps something changed in .NET 7.0 that fixed this?
For the record, my repro for this was the following:
On VS 2022 17.5.0, I am seeing the correct values
Just ran into this (2nd time may be) and trying to think what is happening until @tannergooding pointed me to this issue.
@rickbrew Thank you for the feedback. We apologize for the long wait implementing a fix for this issue. Ideally we would like to fix every issue and implement every idea people submit. Realistically, we cannot address every item. We will continue to re-evaluate this issue against our other priorities and update it once it is committed for the release.
I have just encountered this while debugging some code that uses Vector<T>.
This is quite a visible problem for those of us writing code using Vector<T> on a CPU with 256 bit vector registers (i.e. pretty much all modern CPUs). Any chance this could be moved back to the 5.0 milestone? It’s already been kicked down the road several times - for at least three years (see #7626)
That said, it seems to me that this a a Visual Studio bug, not a dotnet core/sdk bug - is that so? and if so can the bug be fixed in a VS update? So perhaps it doesn’t have to be tied to a dotnet milestone?
For the record, here’s my demo program for recreating the problem on a machine with 256bit SIMD registers:
The output of the program is correct, but the debugger shows zeros in the last 4 elements of vec, which is certainly confusing!
@davmason, @tommcdon.
Has there been any progress or prioritization here. There seems to have been at least 4 total issues on CoreFX and at least 3 total internal issues filed on this so far (there may be more but tracking them all is a bit difficult).
@tmat and I just went through and closed several as dupes against this; it seems fairly prevalent; especially as more people are writing vectorized code.