dotnet / corert

This repo contains CoreRT, an experimental .NET Core runtime optimized for AOT (ahead of time compilation) scenarios, with the accompanying compiler toolchain.
http://dot.net
MIT License
2.91k stars 511 forks source link

Not able to compile to native executable Grps sample #8187

Open alrod opened 4 years ago

alrod commented 4 years ago

Repro steps:

  1. Clone AspNetCore.Docs
  2. Open the sample project in folder
  3. Add nuget reference to Microsoft.DotNet.ILCompiler. I used 1.0.0-alpha-28928-02 version.
  4. Add <RuntimeIdentifier>win10-x64</RuntimeIdentifier> in GrpcGreeter.csproj
  5. Publish with dotnet publish and try to run GrpcGreeter\bin\Debug\netcoreapp3.1\win10-x64\publish\GrpcGreeter.exe
  6. Error:
    
    C:\Users\alrod\Downloads\AspNetCore.Docs-master\AspNetCore.Docs-master\aspnetcore\tutorials\grpc\grpc-start\sample\GrpcGreeter\bin\Debug\netcoreapp3.1\win10-x64\publish>GrpcGreeter.exe
    Generic virtual method pointer lookup failure.

Declaring type handle: EEType:0x00007FF61F8BF670 Target type handle: EEType:0x00000130162BD198 Method name: AddMethod Instantiation: Argument 00000000: EEType:0x00007FF61F893AA0 Argument 00000001: EEType:0x00007FF61F8953F0


The exception stack trace from dump:
`C:\Tools\Procdump>procdump.exe -e 1 -f "" -x C:\Temp\dump C:\Users\alrod\Downloads\AspNetCore.Docs-master\AspNetCore.Docs-master\aspnetcore\tutorials\grpc\grpc-start\sample\GrpcGreeter\bin\Debug\netcoreapp3.1\win10-x64\publish\GrpcGreeter.exe`

KERNELBASE!RaiseFailFastException+af

GrpcGreeter!S_P_CoreLib_Interop_mincoreRaiseFailFastException_0+56 GrpcGreeter!S_P_CoreLib_Interop_mincoreRaiseFailFastException+ff GrpcGreeter!S_P_CoreLib_System_RuntimeExceptionHelpersFailFast_1+1a9 GrpcGreeter!S_P_CoreLib_System_RuntimeExceptionHelpersFailFast+26 GrpcGreeter!S_P_CoreLib_System_EnvironmentFailFast+17 GrpcGreeter!S_P_TypeLoader_Internal_Runtime_TypeLoader_TypeLoaderEnvironmentResolveGenericVirtualMethodTarget_Static+757 GrpcGreeter!S_P_TypeLoader_Internal_Runtime_TypeLoader_TypeLoaderEnvironmentResolveGenericVirtualMethodTarget+5f GrpcGreeter!S_P_TypeLoader_Internal_Runtime_TypeLoader_TypeLoaderEnvironmentTryGetGenericVirtualTargetForTypeAndSlot+174 GrpcGreeter!S_P_TypeLoader_Internal_Runtime_TypeLoader_CallbacksTryGetGenericVirtualTargetForTypeAndSlot+6d GrpcGreeter!S_P_CoreLib_Internal_Runtime_CompilerServices_GenericVirtualMethodSupportGVMLookupForSlotWorker+10b GrpcGreeter!S_P_CoreLib_Internal_Runtime_CompilerServices_GenericVirtualMethodSupportGVMLookupForSlot+7d GrpcGreeter!S_P_CoreLib_System_RuntimeTypeLoaderExportsc_GVMLookupForSlot_b16_0+4d GrpcGreeter!S_P_CoreLib_System_Runtime_TypeLoaderExportsCacheMiss_0+128 GrpcGreeter!S_P_CoreLib_System_Runtime_TypeLoaderExportsGVMLookupForSlot+13c GrpcGreeter!GrpcGreeter_GrpcGreeter_GreeterBindService_0+b5 GrpcGreeter!Internal_CompilerGeneratedModuleInvokeRetVII<SystemCanonSystem___Canon>+10a GrpcGreeter!S_P_CoreLib_System_InvokeUtils_CalliIntrinsicsCall_1+4b GrpcGreeter!S_P_CoreLib_System_InvokeUtilsCallDynamicInvokeMethod+251 GrpcGreeter!S_P_CoreLib_Internal_Runtime_Augments_RuntimeAugmentsCallDynamicInvokeMethod+7b GrpcGreeter!S_P_Reflection_Execution_Internal_Reflection_Execution_MethodInvokers_StaticMethodInvokerInvoke+10c GrpcGreeter!S_P_Reflection_Core_Internal_Reflection_Core_Execution_MethodInvokerInvoke+83 GrpcGreeter!S_P_Reflection_Core_System_Reflection_Runtime_MethodInfos_RuntimeMethodInfoInvoke+86 GrpcGreeter!S_P_CoreLib_System_Reflection_MethodBaseInvoke+4d GrpcGreeter!Grpc_AspNetCore_Server_Grpc_AspNetCore_Server_Model_Internal_BinderServiceMethodProvider1<SystemCanon>OnServiceMethodDiscovery+19d GrpcGreeter!Grpc_AspNetCore_Server_Grpc_AspNetCore_Server_Model_Internal_ServiceRouteBuilder1<SystemCanon>Build+167 GrpcGreeter!Grpc_AspNetCore_Server_Microsoft_AspNetCore_Builder_GrpcEndpointRouteBuilderExtensionsMapGrpcService<System_Canon>+bd GrpcGreeter!GrpcGreeter_GrpcGreeter_StartupcConfigure_b1_0+29 GrpcGreeter!Microsoft_AspNetCore_Routing_Microsoft_AspNetCore_Builder_EndpointRoutingApplicationBuilderExtensionsUseEndpoints+dc GrpcGreeter!GrpcGreeter_GrpcGreeter_StartupConfigure+e1 GrpcGreeter!Internal_CompilerGeneratedModuleInvokeRetVII<SystemCanonSystem___Canon>+c2 GrpcGreeter!S_P_CoreLib_System_InvokeUtils_CalliIntrinsicsCall_1+4b GrpcGreeter!S_P_CoreLib_System_InvokeUtilsCallDynamicInvokeMethod+251 GrpcGreeter!S_P_CoreLib_Internal_Runtime_Augments_RuntimeAugmentsCallDynamicInvokeMethod+7b GrpcGreeter!S_P_Reflection_Execution_Internal_Reflection_Execution_MethodInvokers_InstanceMethodInvokerInvoke+121 GrpcGreeter!S_P_Reflection_Core_Internal_Reflection_Core_Execution_MethodInvokerInvoke+83 GrpcGreeter!S_P_Reflection_Core_System_Reflection_Runtime_MethodInfos_RuntimeMethodInfoInvoke+86 GrpcGreeter!Microsoft_AspNetCore_Hosting_Microsoft_AspNetCore_Hosting_MethodInfoExtensionsInvokeWithoutWrappingExceptions+50 GrpcGreeter!Microsoft_AspNetCore_Hosting_Microsoft_AspNetCore_Hosting_ConfigureBuilderInvoke+235 GrpcGreeter!Microsoft_AspNetCore_Hosting_Microsoft_AspNetCore_Hosting_ConfigureBuilder_cDisplayClass4_0___Build_b0+2b GrpcGreeter!Microsoft_AspNetCore_Hosting_Microsoft_AspNetCore_Hosting_GenericWebHostBuilder_cDisplayClass130UseStartup_b2+90 GrpcGreeter!Microsoft_AspNetCore_Microsoft_AspNetCore_HostFilteringStartupFilter_cDisplayClass00Configure_b0+49 GrpcGreeter!Microsoft_AspNetCore_Hosting_Microsoft_AspNetCore_Hosting_GenericWebHostServiceStartAsync_d31MoveNext+573 GrpcGreeter!S_P_CoreLib_System_Runtime_CompilerServices_AsyncMethodBuilderCoreStart<Microsoft_AspNetCore_Hosting_Microsoft_AspNetCore_Hosting_GenericWebHostServiceStartAsync_d31>+80 GrpcGreeter!S_P_CoreLib_System_Runtime_CompilerServices_AsyncTaskMethodBuilderStart<Microsoft_AspNetCore_Hosting_Microsoft_AspNetCore_Hosting_GenericWebHostServiceStartAsync_d31>+1b GrpcGreeter!Microsoft_AspNetCore_Hosting_Microsoft_AspNetCore_Hosting_GenericWebHostServiceStartAsync+89 GrpcGreeter!Microsoft_Extensions_Hosting_Microsoft_Extensions_Hosting_Internal_HostStartAsync_d9MoveNext+2b7 GrpcGreeter!S_P_CoreLib_System_Runtime_CompilerServices_AsyncMethodBuilderCore__Start<Microsoft_Extensions_Hosting_Microsoft_Extensions_Hosting_Internal_HostStartAsync_d9>+80 GrpcGreeter!S_P_CoreLib_System_Runtime_CompilerServices_AsyncTaskMethodBuilderStart+1b GrpcGreeter!Microsoft_Extensions_Hosting_Microsoft_Extensions_Hosting_Internal_HostStartAsync+9a GrpcGreeter!Microsoft_Extensions_Hosting_Abstractions_Microsoft_Extensions_Hosting_HostingAbstractionsHostExtensions__RunAsync_d4MoveNext+9e GrpcGreeter!S_P_CoreLib_System_Runtime_CompilerServices_AsyncMethodBuilderCoreStart+80 GrpcGreeter!S_P_CoreLib_System_Runtime_CompilerServices_AsyncTaskMethodBuilderStart<Microsoft_Extensions_Hosting_Abstractions_Microsoft_Extensions_Hosting_HostingAbstractionsHostExtensions__RunAsync_d4>+1b GrpcGreeter!Microsoft_Extensions_Hosting_Abstractions_Microsoft_Extensions_Hosting_HostingAbstractionsHostExtensionsRunAsync+96 GrpcGreeter!Microsoft_Extensions_Hosting_Abstractions_Microsoft_Extensions_Hosting_HostingAbstractionsHostExtensionsRun+2c GrpcGreeter!GrpcGreeter_GrpcGreeter_ProgramMain+44 GrpcGreeter!GrpcGreeter_ModuleMainMethodWrapper+17 GrpcGreeter!GrpcGreeter__Module_StartupCodeMain+80 GrpcGreeter!wmain+ae GrpcGreeter!scrt_common_main_seh+10c kernel32!BaseThreadInitThunk+14 ntdll!RtlUserThreadStart+21

MichalStrehovsky commented 4 years ago

That's a good bug, thanks for the repro!

To work around, add this to your main csproj file:


  <ItemGroup>
    <RdXmlFile Include="rd.xml" />
  </ItemGroup>

The contents for rd.xml should be:

<Directives>
    <Application>
        <Assembly Name="Grpc.AspNetCore.Server">
            <Type Name="Grpc.AspNetCore.Server.Model.Internal.ProviderServiceBinder`1[[System.Object, System.Runtime]]" Dynamic="Required All" />
        </Assembly>
    </Application>
</Directives>

Reduced repro for this is:

using System;

class Base<T>
{
    public virtual int Frob<U>() => 1;
}

class Derived<T> : Base<T>
{
    public override int Frob<U>() => 2;
}

internal class Program
{
    private static void Main(string[] args)
    {
        Type objType = typeof(object);
        Type instanceType = typeof(Derived<>).MakeGenericType(objType);
        var instance = (Base<object>)Activator.CreateInstance(instanceType);
        instance.Frob<string>();
    }
}

What's going on is that Derived was reflection-activated with a generic argument that the compiler didn't see at compile time. The compiler predicted that Derived might be needed, so it generated a canonical type for this that can be cloned at runtime, but analysis of generic virtual method doesn't run on top of canonical methods for some reason. So we don't actually have a callable method body in Derived.

The obvious fix seemed to be to add InterestingForDynamicDependencyAnalysis to canonical EEType node (that is a copy of the property from the constructed nodes), but that hit an assert in GVMDependenciesNode (Debug.Assert(!instantiatedMethod.IsCanonicalMethod(CanonicalFormKind.Any))). The obvious fix for that (deleting the assert and the subsequent call to context.MethodGenericDictionary(instantiatedMethod)) fixed this for the GRPC case, but broke tests.

I'll need to have a deeper look at why GVM analysis doesn't just run on top of the canonical instantiations. It feels like it should.