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

TypeBuilder.CreateType doesn't work on Windows in a trimmed app due to BuiltInComInterop being disabled #55600

Closed
eerhardt opened this issue Jul 13, 2021 · 4 comments · Fixed by #55756
Assignees
Labels
area-Interop-coreclr linkable-framework Issues associated with delivering a linker friendly framework os-windows
Milestone

Comments

@eerhardt
Copy link
Member

Description

When trimming an app that uses Ref.Emit to generate a Type, it fails by default on Windows due to BuiltInComInterop being disabled.

Using a recent .NET 6 SDK, dotnet publish the following app:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <RuntimeIdentifier>win-x64</RuntimeIdentifier>
    <PublishTrimmed>true</PublishTrimmed>
  </PropertyGroup>
</Project>
using System;
using System.Reflection;
using System.Reflection.Emit;

AssemblyBuilder assembly = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("GeneratedAssembly"), AssemblyBuilderAccess.Run);
ModuleBuilder module = assembly.DefineDynamicModule("GeneratedModule");
TypeBuilder genericType = module.DefineType("GeneratedType");
genericType.DefineField("_int", typeof(int), FieldAttributes.Private);
genericType.DefineProperty("Prop", PropertyAttributes.None, typeof(string), null);

Type generatedType = genericType.CreateType();
Console.WriteLine(generatedType);
❯ .\bin\Debug\net6.0\win-x64\publish\HelloWorld.exe
Unhandled exception. System.TypeLoadException: Could not load type 'System.Runtime.InteropServices.DispatchWrapper' from assembly 'System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e'.
   at System.Reflection.Emit.TypeBuilder.SetMethodIL(QCallModule , Int32 , Boolean , Byte[] , Int32 , Byte[] , Int32 , Int32 , ExceptionHandler[] , Int32 , Int32[] , Int32 )
   at System.Reflection.Emit.TypeBuilder.CreateTypeNoLock() in System.Private.CoreLib.dll:token 0x60025e7+0x37f
   at System.Reflection.Emit.TypeBuilder.CreateType() in System.Private.CoreLib.dll:token 0x60025e6+0x11
   at <Program>$.<Main>$(String[] ) in C:\DotNetTest\HelloWorld\Program.cs:line 11

Configuration

  • Which version of .NET is the code running on? .NET 6.0.0-preview5+
  • What OS and version, and what distro if applicable? Windows
  • What is the architecture (x64, x86, ARM, ARM64)? x64
  • Do you know whether it is specific to that configuration? yes

Regression?

Yes, this worked before 6.0.0-preview5 because BuiltInComInterop wasn't disabled by default. We disable BuiltInComInterop by default starting in 6.0.0-preview5.

cc @LakshanF @agocke @vitek-karas @sbomer

@eerhardt eerhardt added this to the 6.0.0 milestone Jul 13, 2021
@dotnet-issue-labeler dotnet-issue-labeler bot added the untriaged New issue has not been triaged by the area owner label Jul 13, 2021
@jkoritzinsky jkoritzinsky added linkable-framework Issues associated with delivering a linker friendly framework and removed untriaged New issue has not been triaged by the area owner labels Jul 13, 2021
@ghost
Copy link

ghost commented Jul 13, 2021

Tagging subscribers to 'linkable-framework': @eerhardt, @vitek-karas, @LakshanF, @sbomer, @joperezr
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

When trimming an app that uses Ref.Emit to generate a Type, it fails by default on Windows due to BuiltInComInterop being disabled.

Using a recent .NET 6 SDK, dotnet publish the following app:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <RuntimeIdentifier>win-x64</RuntimeIdentifier>
    <PublishTrimmed>true</PublishTrimmed>
  </PropertyGroup>
</Project>
using System;
using System.Reflection;
using System.Reflection.Emit;

AssemblyBuilder assembly = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("GeneratedAssembly"), AssemblyBuilderAccess.Run);
ModuleBuilder module = assembly.DefineDynamicModule("GeneratedModule");
TypeBuilder genericType = module.DefineType("GeneratedType");
genericType.DefineField("_int", typeof(int), FieldAttributes.Private);
genericType.DefineProperty("Prop", PropertyAttributes.None, typeof(string), null);

Type generatedType = genericType.CreateType();
Console.WriteLine(generatedType);
❯ .\bin\Debug\net6.0\win-x64\publish\HelloWorld.exe
Unhandled exception. System.TypeLoadException: Could not load type 'System.Runtime.InteropServices.DispatchWrapper' from assembly 'System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e'.
   at System.Reflection.Emit.TypeBuilder.SetMethodIL(QCallModule , Int32 , Boolean , Byte[] , Int32 , Byte[] , Int32 , Int32 , ExceptionHandler[] , Int32 , Int32[] , Int32 )
   at System.Reflection.Emit.TypeBuilder.CreateTypeNoLock() in System.Private.CoreLib.dll:token 0x60025e7+0x37f
   at System.Reflection.Emit.TypeBuilder.CreateType() in System.Private.CoreLib.dll:token 0x60025e6+0x11
   at <Program>$.<Main>$(String[] ) in C:\DotNetTest\HelloWorld\Program.cs:line 11

Configuration

  • Which version of .NET is the code running on? .NET 6.0.0-preview5+
  • What OS and version, and what distro if applicable? Windows
  • What is the architecture (x64, x86, ARM, ARM64)? x64
  • Do you know whether it is specific to that configuration? yes

Regression?

Yes, this worked before 6.0.0-preview5 because BuiltInComInterop wasn't disabled by default. We disable BuiltInComInterop by default starting in 6.0.0-preview5.

cc @LakshanF @agocke @vitek-karas @sbomer

Author: eerhardt
Assignees: LakshanF
Labels:

area-Interop-coreclr, linkable-framework

Milestone: 6.0.0

@LakshanF
Copy link
Member

It seems like this is failing when preparing the PInvoke call, SetMethodIL. Specifically trying to marshal some of the array parameters as the below call stack shows. OleVariant::GetVarTypeForTypeHandle has a check for DispatchWrapper under FEATURE_COMINTEROP. Non-Windows platforms bypass these checks to return VT_UNKNOWN that likely makes this scenario work in those platforms.

cc @elinor-fung, @jkoritzinsky

06 000000e0`77d7ce00 00007ffb`7c1c7e00     coreclr!ClassLoader::LoadTypeHandleThrowIfFailed+0xf3c3d [D:\workspace\_work\1\s\src\coreclr\vm\clsload.cpp @ 490] 
07 000000e0`77d7ce40 00007ffb`7c1c7d7f     coreclr!ClassLoader::LoadTypeByNameThrowing+0x68 [D:\workspace\_work\1\s\src\coreclr\vm\clsload.cpp @ 435] 
08 000000e0`77d7ced0 00007ffb`7c2cda9f     coreclr!CoreLibBinder::LookupClassLocal+0x47 [D:\workspace\_work\1\s\src\coreclr\vm\binder.cpp @ 73] 
09 (Inline Function) --------`--------     coreclr!CoreLibBinder::GetClass+0x1f [D:\workspace\_work\1\s\src\coreclr\vm\binder.h @ 354] 
0a (Inline Function) --------`--------     coreclr!CoreLibBinder::IsClass+0xc50f1 [D:\workspace\_work\1\s\src\coreclr\vm\binder.h @ 157] 
0b 000000e0`77d7cf20 00007ffb`7c2088be     coreclr!OleVariant::GetVarTypeForTypeHandle+0xc51c3 [D:\workspace\_work\1\s\src\coreclr\vm\olevariant.cpp @ 332]
0c 000000e0`77d7cf70 00007ffb`7c241bbe     coreclr!ArrayMarshalInfo::InitElementInfo+0x1d6 [D:\workspace\_work\1\s\src\coreclr\vm\mlinfo.cpp @ 3864] 
0d (Inline Function) --------`--------     coreclr!ArrayMarshalInfo::IsValid+0x17 [D:\workspace\_work\1\s\src\coreclr\vm\mlinfo.h @ 634] 
0e 000000e0`77d7cfd0 00007ffb`7c162dba     coreclr!MarshalInfo::HandleArrayElemType+0xba [D:\workspace\_work\1\s\src\coreclr\vm\mlinfo.cpp @ 2540] 
0f 000000e0`77d7d050 00007ffb`7c163ffe     coreclr!MarshalInfo::MarshalInfo+0x996 [D:\workspace\_work\1\s\src\coreclr\vm\mlinfo.cpp @ 2288] 
10 000000e0`77d7d300 00007ffb`7c169696     coreclr!CreateNDirectStubWorker+0x252 [D:\workspace\_work\1\s\src\coreclr\vm\dllimport.cpp @ 3757] 
11 000000e0`77d7d500 00007ffb`7c16929e     coreclr!`anonymous namespace'::CreateInteropILStub+0x306 [D:\workspace\_work\1\s\src\coreclr\vm\dllimport.cpp @ 5107] 
12 000000e0`77d7db30 00007ffb`7c168f7b     coreclr!NDirect::CreateCLRToNativeILStub+0x162 [D:\workspace\_work\1\s\src\coreclr\vm\dllimport.cpp @ 5228] 
13 000000e0`77d7dc20 00007ffb`7c168d43     coreclr!NDirect::CreateCLRToNativeILStub+0x9f [D:\workspace\_work\1\s\src\coreclr\vm\dllimport.cpp @ 5459] 
14 000000e0`77d7dcd0 00007ffb`7c168a3d     coreclr!NDirect::GetILStubMethodDesc+0x3b [D:\workspace\_work\1\s\src\coreclr\vm\dllimport.cpp @ 5479] 
15 000000e0`77d7dd00 00007ffb`7c168db6     coreclr!NDirect::GetStubForILStub+0x41 [D:\workspace\_work\1\s\src\coreclr\vm\dllimport.cpp @ 5675] 
16 000000e0`77d7dd50 00007ffb`7c12e9da     coreclr!GetStubForInteropMethod+0x5e [D:\workspace\_work\1\s\src\coreclr\vm\dllimport.cpp @ 5868] 
17 000000e0`77d7dd90 00007ffb`7c12e4eb     coreclr!MethodDesc::DoPrestub+0x3ba [D:\workspace\_work\1\s\src\coreclr\vm\prestub.cpp @ 2266] 
18 000000e0`77d7dec0 00007ffb`7c252055     coreclr!PreStubWorker+0x21b [D:\workspace\_work\1\s\src\coreclr\vm\prestub.cpp @ 2033] 
19 000000e0`77d7e050 00007ffb`1c67806e     coreclr!ThePreStub+0x55
1a 000000e0`77d7e100 00007ffb`1c677604     System_Private_CoreLib!System.Reflection.Emit.TypeBuilder.CreateTypeNoLock()+0x5ee

@jkoritzinsky
Copy link
Member

I think we should wrap that block in a check for if built-in COM is enabled.

@elinor-fung
Copy link
Member

Yeah. Probably also worth doing a search for all those wrapper classes / other similar checks in the runtime and seeing if they are already blocked or they need to be blocked.

jkoritzinsky added a commit to jkoritzinsky/runtime that referenced this issue Jul 15, 2021
@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Jul 15, 2021
eerhardt added a commit that referenced this issue Jul 18, 2021
…in COM is disabled. (#55756)

* Disable array support for the COM variant wrapper classes when built-in COM is disabled.

Fixes #55600

* Fix config call.

* Fix one more location of wrapper class usage.

* Fix method name.

* Add trimming test.

* Fix AV in IsArrayOfWrappers

* Fix trimming test

* Apply suggestions from code review

Co-authored-by: Eric Erhardt <eric.erhardt@microsoft.com>

* Set Trim=true

Co-authored-by: Elinor Fung <elfung@microsoft.com>
Co-authored-by: Eric Erhardt <eric.erhardt@microsoft.com>
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Jul 18, 2021
@ghost ghost locked as resolved and limited conversation to collaborators Aug 18, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-Interop-coreclr linkable-framework Issues associated with delivering a linker friendly framework os-windows
Projects
None yet
5 participants