dotnet / linker

388 stars 127 forks source link

IL Trimmer: Unhandled exception. System.NotImplementedException: Unhandled intrinsic #3072

Closed Saalvage closed 1 year ago

Saalvage commented 1 year ago

When trying to use MoonSharp in a Blazor WASM app the following stack trace presents itself on attempted publishing:

ILLink(0,0): Error IL1012: IL Trimmer has encountered an unexpected error. Please report the issue at https://github.com/dotnet/linker/issues
Fatal error in IL Linker
Unhandled exception. System.NotImplementedException: Unhandled intrinsic
   at Mono.Linker.Dataflow.ReflectionMethodBodyScanner.HandleCall(Instruction operation, MethodReference calledMethod, ValueSet`1 instanceValue, ImmutableArray`1 argumentValues, DiagnosticContext diagnosticContext, ReflectionMarker reflectionMarker, LinkContext context, MarkStep markStep, ValueSet`1& methodReturnValue)
   at Mono.Linker.Dataflow.ReflectionMethodBodyScanner.HandleCall(MethodBody callingMethodBody, MethodReference calledMethod, Instruction operation, ValueNodeList methodParams, ValueSet`1& methodReturnValue)
   at Mono.Linker.Dataflow.MethodBodyScanner.HandleCall(MethodBody callingMethodBody, Instruction operation, Stack`1 currentStack, Dictionary`2 locals, InterproceduralState& interproceduralState, Int32 curBasicBlock)
   at Mono.Linker.Dataflow.MethodBodyScanner.Scan(MethodBody methodBody, InterproceduralState& interproceduralState)
   at Mono.Linker.Dataflow.ReflectionMethodBodyScanner.Scan(MethodBody methodBody, InterproceduralState& interproceduralState)
   at Mono.Linker.Dataflow.MethodBodyScanner.InterproceduralScan(MethodBody startingMethodBody)
   at Mono.Linker.Dataflow.ReflectionMethodBodyScanner.InterproceduralScan(MethodBody methodBody)
   at Mono.Linker.Steps.MarkStep.MarkReflectionLikeDependencies(MethodBody body, Boolean requiresReflectionMethodBodyScanner)
   at Mono.Linker.Steps.MarkStep.MarkMethodBody(MethodBody body)
   at Mono.Linker.Steps.MarkStep.ProcessMethod(MethodDefinition method, DependencyInfo& reason, MessageOrigin& origin)
   at Mono.Linker.Steps.MarkStep.ProcessQueue()
   at Mono.Linker.Steps.MarkStep.ProcessPrimaryQueue()
   at Mono.Linker.Steps.MarkStep.Process()
   at Mono.Linker.Steps.MarkStep.Process(LinkContext context)
   at Mono.Linker.Pipeline.ProcessStep(LinkContext context, IStep step)
   at Mono.Linker.Pipeline.Process(LinkContext context)
   at Mono.Linker.Driver.Run(ILogger customLogger)
   at Mono.Linker.Driver.Main(String[] args)

If any further info is needed please ask!

marek-safar commented 1 year ago

What version are you using ?

/cc @vitek-karas

vitek-karas commented 1 year ago

I think this is 7.0, because I can't find code which would throw such exception in 6.

If you have a repro project, that would help a lot.

vitek-karas commented 1 year ago

I was able to repro this. The problem is with calls to methods like TypeInfo.GetConstructors. The GetInstrinsicIsForMethod operates on MethodDefinition which in this case points to System.Type.GetConstructors and it recognizes it as intrinsic (since we're look for System.Type.GetConstructors). But the switch in ReflectionMethodBodyScanner uses MethodReference and its DeclaringType which is TypeInfo and thus we don't recognize it as intrinsic.. and fail.

This is fixed in main as a side effect of https://github.com/dotnet/linker/pull/3060, but that is not in 7.0.

This reproes in 6.0 as well, so at least it's not a 7.0 regression.

I can't think of a workaround to this unfortunately (other than changing the implementation of MoonSharp, which is obviously not really workable).

vitek-karas commented 1 year ago

@agocke @sbomer

For now I put this into 7.0 milestone - we might want to consider this for servicing? It's not a regression, but if this is encountered there's no good workaround.

Saalvage commented 1 year ago

I'm sorry for failing to provide the version and a repro project originally but I'm glad that it's been figured out and had even already been fixed! :) Regarding workarounds, I am looking into using a fork of MoonSharp anyways, which is why modifying it might not be a dealbreaker. If possible I'd appreciate a rough summary of what would have to be done to MoonSharp to remedy this, but of course I'd understand if this would be considered too off-topic or time-consuming!

agocke commented 1 year ago

Yup, let's take this for servicing. Unfortunately our servicing schedule for 7.0 is going to be a bit late (month or two after shipping) but it's still better to have it fixed.

nheath99 commented 1 year ago

I just upgraded from .net6 to 7 and dotnet publish is now throwing this error. This is a Blazor WASM hosted project. Could it be one of the nuget packages I'm referencing? If so how could I tell?

nheath99 commented 1 year ago

Ok so it turns out I was using a deprecated nuget package: Microsoft.Azure.Cosmos.Table Replacing this with the suggested Azure.Data.Tables resolved this issue for me.

vitek-karas commented 1 year ago

@nheath99 - as far as I can tell the only way to repro this is if your app uses a component which was built against netstandard1.2 (I think, not sure about the exact version - but something old, netstandard2.0 doesn't have this problem) and uses one of the reflection methods mentioned above. So updating to a newer package is likely to fix the problem - in fact even the exact same code if rebuilt against netstandard2.0 would fix the problem as well.

Anyway - glad you were able to get it to work.

I'm working on backporting the fix to 6 - the tricky part is to build a test which reproes the problem (building something against old netstandard in our build system seems to be tricky)

baskren commented 1 year ago

@Saalvage : I don't know if you were ever able to work around this issue - but I had the same issue today with building a net6.0-ios for deployment to an iPhone (not simulator).

I was able to work around it by:

  1. Adding the MoonSharp repo as a submodule to my repo

  2. Making the following edits to the src/MoonSharp.Interpreter/_Projects/MoonSharp.Interpreter.portable.40/MoonSharp.Interpreter.portable.40.csproj file:

    • Change Project tag attributes from:
      <Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />

      to:

      <Project Sdk="Microsoft.NET.Sdk">
    • Deleting the following lines in the <PropertyGroup>:
      <ProjectGuid>{49F32476-FCA0-45FD-8F89-0C7C0D15E409}</ProjectGuid>
      <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
      <TargetFrameworkProfile>Profile328</TargetFrameworkProfile>
      <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
      <SignAssembly>true</SignAssembly>
      <AssemblyOriginatorKeyFile>..\..\..\keypair.snk</AssemblyOriginatorKeyFile>
    • Adding the following to the <PropertyGroup>:
      <TargetFrameworks>net6.0</TargetFrameworks>
    • Deleting the following line near the end of the file:
      <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
  3. Commenting out the contents of src/MoonSharp.Interpreter/_Projects/MoonSharp.Interpreter.portable40/Properties/AssemblyInfo.cs

  4. Adding the following line to src/MoonSharp.Interpreter/Interop/StandardDescriptors/ReflectionMemberDescriptors/EventMemberDescriptor.cs:

    using ReferenceEqualityComparer = MoonSharp.Interpreter.DataStructs.ReferenceEqualityComparer;
  5. Adding src/MoonSharp.Interpreter/_Projects/MoonSharp.Interpreter.portable.40/MoonSharp.Interpreter.portable.40.csproj as a reference to my project that targets net6.0-ios (it also targets a number of other frameworks as well).

  6. Success!

baskren commented 1 year ago

OK, for your convenience, here is a repo with the changes to MoonSharp to enable a successful build : https://github.com/baskren/moonsharp/tree/net6.0-ios

agocke commented 1 year ago

This should be fixed and available in the latest 7.0 patches.