Skip to content

Generic virtual method pointer lookup failure in .NET 7 Native AOT #78882

@neuecc

Description

@neuecc

Description

Following reproduction code crashes after publishing and running the AOT executable.
Code includes static abstract members, generics.

Reproduction Steps

create .NET 7 ConsoleApp project

csproj

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net7.0</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>

        <PublishAot>true</PublishAot>
        <SelfContained>true</SelfContained>
        <IlcOptimizationPreference>Speed</IlcOptimizationPreference>
        <IlcOptimizationPreference>Size</IlcOptimizationPreference>
        <IlcFoldIdenticalMethodBodies>true</IlcFoldIdenticalMethodBodies>
    </PropertyGroup>

</Project>

Program.cs

using System.Buffers;

// require this unused line for reproduce error?
var bufferWriter = new ArrayBufferWriter<byte>();

var mc = new MemPackObject();

var formatter = new MemoryPackableFormatter2<MemPackObject>();
formatter.Serialize<ArrayBufferWriter<byte>>(ref mc);


public interface IMemoryPackable2<T>
{
    static abstract void Serialize<TBufferWriter>(scoped ref T? value)
        where TBufferWriter : IBufferWriter<byte>;
}

public interface IMemoryPackFormatter2<T>
{
    void Serialize<TBufferWriter>(scoped ref T? value)
        where TBufferWriter : IBufferWriter<byte>;
}

public abstract class MemoryPackFormatter2<T> : IMemoryPackFormatter2<T>
{
    public abstract void Serialize<TBufferWriter>(scoped ref T? value)
        where TBufferWriter : IBufferWriter<byte>;
}

public sealed class MemoryPackableFormatter2<T> : MemoryPackFormatter2<T>
    where T : IMemoryPackable2<T>
{
    public override void Serialize<TBufferWriter>(scoped ref T? value)
    {
        Console.WriteLine("Before");
        T.Serialize<TBufferWriter>(ref value);
        Console.WriteLine("After");
    }
}

public class MemPackObject : IMemoryPackable2<MemPackObject>
{
    public static void Serialize<TBufferWriter>(scoped ref MemPackObject? value)
          where TBufferWriter : IBufferWriter<byte>
    {
        Console.WriteLine("OK");
    }
}

command

dotnet publish
execute published .exe

Expected behavior

Run successfully, console logged "OK".

Actual behavior

Process terminated. Generic virtual method pointer lookup failure.

Declaring type handle: MethodTable:0x00007FF76B94D6C8
Target type handle: MethodTable:0x00007FF76B94D720
Method name: Serialize
Instantiation:
  Argument 00000000: MethodTable:0x00007FF76B956030

image

Regression?

No response

Known Workarounds

No response

Configuration

  • .NET 7.0.100
  • Windows 10 Pro
  • x64 CPU(AMD Ryzen 5950X)

Other information

Originally, I've received from my library's issue.
Cysharp/MemoryPack#75

I've found other Generic virtual method pointer lookup failure issue in bug-report.
Therefore, I am reporting this because I think this may be a bug in native-aot.
#70878

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions