Skip to content
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

Bad GC info generated for structures that contain Span field and small packing #11400

Open
jkotas opened this issue Nov 4, 2018 · 2 comments

Comments

@jkotas
Copy link
Member

jkotas commented Nov 4, 2018

Repro:

dotnet run -c Release
Actual result: Prints ERRORs or crashes during GC within seconds
Expected result: Runs forever without error

using System;
using System.Threading;
using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal ref struct NumberBuffer
{
    public bool Sign;
    public Span<char> Digits;
}

class Program
{
    static int MoreWork(ref NumberBuffer buffer)
    {
        for (int i = 0; i < buffer.Digits.Length; i++)
            buffer.Digits[i % buffer.Digits.Length] = (char)i;
        int sum = 0;
        for (int i = 0; i < buffer.Digits.Length; i++)
            sum += buffer.Digits[i];
        return sum;
    }

    static char[][] s = new char[1000][];

    static void Work()
    {
        Random r = new Random();
        for (;;)
        {
            NumberBuffer buffer = default;
            buffer.Digits = s[r.Next(s.Length)];
            if (buffer.Digits.Length == 0) continue;
            int sum = MoreWork(ref buffer);
            if (sum != 499500)
                Console.WriteLine("ERROR: " + sum);
        }
    }

    static void Main(string[] args)
    {
        new Thread(Work).Start();
        new Thread(Work).Start();
        new Thread(Work).Start();

        Random r = new Random();
        for (;;) { s[r.Next(s.Length)] = new char[1000]; GC.KeepAlive(new char[r.Next(1000)]); }
    }
}
@jkotas
Copy link
Member Author

jkotas commented Nov 4, 2018

Related to dotnet/corert#6512. I think the type loader should ignore the Pack directive and align byref fields as pointers; similar to what it does for regular objref fields.

@MichalStrehovsky MichalStrehovsky self-assigned this Jun 10, 2019
MichalStrehovsky referenced this issue in MichalStrehovsky/coreclr Jun 10, 2019
Seems to do the trick to get packing ignored on ref structs.

Fixes #20794.
@MichalStrehovsky
Copy link
Member

Moving this out to Future. This requires changes in type layout that look very risky. dotnet/coreclr#25056 (comment)

@msftgits msftgits transferred this issue from dotnet/coreclr Jan 31, 2020
@msftgits msftgits added this to the Future milestone Jan 31, 2020
@mangod9 mangod9 modified the milestones: Future, 6.0.0 Sep 17, 2020
@mangod9 mangod9 modified the milestones: 6.0.0, Future Jul 9, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants