-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bug regarding inheritance in classes with explicit layout #53542
Comments
1) Mimic CoreCLR runtime bug filed under dotnet#53542; 2) Fix pointer alignment for byref-like fields.
/cc @jkoritzinsky per JanK's comment in the PR discussion #53424 |
As an additional bit of fun, this logic is conditional on the following check referring to some bug I don't know where to find: runtime/src/coreclr/vm/methodtablebuilder.cpp Line 8563 in b1e20bf
It would be useful to understand what the original issue was, whether we can remove the conditional check, and whether it may be the case that the conditional check somehow compensates for the behavior tracked by this issue. |
/cc @jkotas - I have found the "Bug 849333" in our internal DevDiv bug database and the Discussion is as follows: Jan Kotas commented Dec 21, 2013 Changeset 1134780 broke layout of blittable types with explicit layout by accident. Could you please help shed light on this? |
Attaching a simple repro Jan and I created as part of the abovementioned PR discussion. using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Explicit)]
class A1
{
[FieldOffset(0)]
public byte x;
[FieldOffset(2)]
public char x2;
}
[StructLayout(LayoutKind.Explicit)]
class A2 : A1
{
[FieldOffset(0)]
public int y;
}
[StructLayout(LayoutKind.Explicit)]
class A3 : A2
{
[FieldOffset(0)]
public byte z;
}
class My
{
static unsafe void Main()
{
A3 a = new A3();
fixed (byte *px = &a.x)
fixed (byte *pz = &a.z)
{
Console.WriteLine(pz - px);
}
}
} With proper packing in place, there should be a [StructLayout(LayoutKind.Explicit)]
class A1
{
[FieldOffset(0)]
public int x;
} didn't hit this issue because it bailed out early in |
For the difference 24, the calculation of |
I do not see a problem with fixing this one in .NET 6 if we have time. |
There was a change made earlier that regressed the layout algorithm in observable way, bug 849333 was filled on it, and the bug was fixed. Note that .NET Framework 2.0 prints 19 for the repro at top of this issue as well, so this bug is very old (prior 2005). |
@jkotas - Hmm, so is the conditional statement still needed then? It looks like CoreCLR runtime currently has very fragile behavior where the check |
Sure, I would love this condition to be simplifed to something less fragile, but we gave up on that for .NET 6 as too complex. Also, simlifying this condition would be R2R breaking change. I see this issue as tracking just the double counting of the base offset with explicit non-blittable layout, nothing else. Fixing that should be much simpler and it won't be R2R breaking change (explicit layout for non-valuetypes is not part of the R2R contract). |
…backcompat. Fixes dotnet#54132 Fixes dotnet#53542
Awesome, thanks Jeremy for fixing this! |
Not fixing this for .NET 6 as we decided it's too risky to change runtime layouts now, it would also require bumping up the readytorun major version, but it's a bug nonetheless. For an explicit layout class with a base class, we place its fields as if the base class was twice its actual instance size. This is because we first take the base class instance size into account when calculating the layout itself in
runtime/src/coreclr/vm/classlayoutinfo.cpp
Line 138 in ffb095a
and we add the parent class size a second time in MethodTableBuilder::HandleExplicitLayout in
runtime/src/coreclr/vm/methodtablebuilder.cpp
Line 8579 in ffb095a
and
runtime/src/coreclr/vm/methodtablebuilder.cpp
Line 8631 in ffb095a
/cc @dotnet/crossgen-contrib, @dotnet/dotnet-coreclr
The text was updated successfully, but these errors were encountered: