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

.NET 7 Native AOT error: Generic virtual method pointer lookup failure #75

Closed
littlehoneybunnytuttifruttipumpkinpie opened this issue Nov 26, 2022 · 5 comments

Comments

@littlehoneybunnytuttifruttipumpkinpie
Copy link

First, thanks for updating MemoryPack to work with .NET 7 and AOT.
Unfortunately my native AOT test program (latest .NET 7) is crashing with the error below:
image

(it works OK in debug and release mode in Visual Studio, but crashes only after publishing and running the AOT executable)

Here is the full test code:

using MemoryPack;

namespace Tests
{
    [MemoryPackable]
    public partial class MemPackObject
    {
        public string TestString { get; set; }
    }

    class MemPackTest
    {
        static void Main(string[] args)
        {
            MemPackObject test_object = new MemPackObject();
            test_object.TestString = "ABC";
            Console.WriteLine("Initial value before serializing: " + test_object.TestString);

            byte[] serialized_object = MemoryPackSerializer.Serialize(test_object);
            MemPackObject? deserialized_object = MemoryPackSerializer.Deserialize<MemPackObject>(serialized_object);

            if (deserialized_object != null)
            {
                Console.WriteLine("Final value after deserializing: " + deserialized_object.TestString);
            }

            Console.WriteLine("Test completed. Press any key to exit");
            Console.ReadKey();
        }

    }
}
@neuecc
Copy link
Member

neuecc commented Nov 27, 2022

Thanks.
I suspect it is a bug in the Native AOT compiler, as I reproduced it even with minimized code.
Reported at dotnet/runtime#78882

@MitchRazga
Copy link

MitchRazga commented Nov 28, 2022

I'm also experiencing this issue.

Edit: Unmanaged types seem to be serializing and deserializing with Native AOT correctly.

@neuecc
Copy link
Member

neuecc commented Nov 28, 2022

I received a response.
It seems to be a bug and will not be resolved until .NET 8.

The workaround is to tell the compiler manually that the target needs to be generated. It is not pretty. Pull request dotnet/runtime#78904 adds support for at least telling what needs to be pregenerated and I'm hoping we can service that part in January for 7.0.

It's likely the root cause of the problem will only be fixed in 8.0. Sorry, it's a very risky fix.

I have noted this in the ReadMe.

@neuecc neuecc closed this as completed Dec 18, 2022
@GerardSmit
Copy link

This has been fixed in dotnet/runtime#80601

It's possible to use the daily build of Microsoft.DotNet.ILCompiler in .NET 7.0.
Note that this is a daily build so it's possible there are other bugs.

  1. Create nuget.config in your solution (where the .sln-file is located) with the following content:
    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <packageSources>
        <add key="dotnet8" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet8/nuget/v3/index.json" />
      </packageSources>
    </configuration>
  2. Add the following to your .csproj (change win-x64 if you're not using Windows):
    <PackageReference Include="Microsoft.DotNet.ILCompiler; runtime.win-x64.Microsoft.DotNet.ILCompiler" Version="8.0.0-alpha.1.23067.11" />

After that you can build the project with AOT (e.g. dotnet publish -r win-x64 -c Release -p PublishAot=True). If you run the application it should give the expected result:

Initial value before serializing: ABC
Final value after deserializing: ABC
Test completed. Press any key to exit

@dest-all
Copy link

dest-all commented Jun 12, 2023

This has been fixed in dotnet/runtime#80601

It's possible to use the daily build of Microsoft.DotNet.ILCompiler in .NET 7.0. Note that this is a daily build so it's possible there are other bugs.

  1. Create nuget.config in your solution (where the .sln-file is located) with the following content:
    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <packageSources>
        <add key="dotnet8" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet8/nuget/v3/index.json" />
      </packageSources>
    </configuration>
    
  2. Add the following to your .csproj (change win-x64 if you're not using Windows):
    <PackageReference Include="Microsoft.DotNet.ILCompiler; runtime.win-x64.Microsoft.DotNet.ILCompiler" Version="8.0.0-alpha.1.23067.11" />
    

After that you can build the project with AOT (e.g. dotnet publish -r win-x64 -c Release -p PublishAot=True). If you run the application it should give the expected result:

Initial value before serializing: ABC
Final value after deserializing: ABC
Test completed. Press any key to exit

The solution worked for me for a custom class serialization/deserialization.
But trying to serialize List, for example, still fails.

System.Collections.Generic.List`1[[System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]] is failed in provider at creating formatter.

This happens to every generic I try.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants