Skip to content

Stripping parameter names for members accessed by DAM.All #2160

@sbomer

Description

@sbomer

Marking types for DynamicallyAccessedMembers.All or NestedTypes is stripping metadata for the accessed members (the repro requires the assembly to be trimmed, for example with <TrimmerDefaultAction>link</TrimmerDefaultAction>):

using System;
using System.Diagnostics.CodeAnalysis;
using DAM = System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute;
using RUC = System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute;

public class Program {
	public static void Main() => RequireAll(typeof(Foo));

	static void RequireAll([DAM(DynamicallyAccessedMemberTypes.All)] Type t) {
		t.GetMethod("Method").Invoke (null, new object[] { "Hi" });
	}
}

public class Foo {
	public static void Method(string message) {
		throw new Exception(message);
	}
}

dotnet run (notice Foo.Method has the parameter name kept):

Unhandled exception. System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
 ---> System.Exception: Hi
   at Foo.Method(String message) in /home/sven/tmp/damt/th2/Program.cs:line 17
   --- End of inner exception stack trace ---
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Span`1& arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) in System.Private.CoreLib.dll:token 0x6004db0+0x23
   at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters) in System.Private.CoreLib.dll:token 0x6004cb4+0x0
   at Program.RequireAll(Type t) in /home/sven/tmp/damt/th2/Program.cs:line 10
   at Program.Main() in /home/sven/tmp/damt/th2/Program.cs:line 7

running a trimmed app (notice Foo.Method is missing the parameter name):

Unhandled exception. System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
 ---> System.Exception: Hi
   at Foo.Method(String ) in /home/sven/tmp/damt/th2/Program.cs:line 23
   --- End of inner exception stack trace ---
   at System.RuntimeMethodHandle.InvokeMethod(Object , Span`1& , Signature , Boolean , Boolean )
   at System.Reflection.RuntimeMethodInfo.Invoke(Object , BindingFlags , Binder , Object[] , CultureInfo ) in System.Private.CoreLib.dll:token 0x600201c+0x23
   at System.Reflection.MethodBase.Invoke(Object , Object[] ) in System.Private.CoreLib.dll:token 0x6001f64+0x0
   at Program.RequireAll(Type ) in /home/sven/tmp/damt/th2/Program.cs:line 16
   at Program.Test1() in /home/sven/tmp/damt/th2/Program.cs:line 12
   at Program.Main() in /home/sven/tmp/damt/th2/Program.cs:line 8
Aborted (core dumped)

This happens because we just call MarkEntireType which doesn't mark the members as reflection-accessed like we do elsewhere: https://github.com/mono/linker/blob/6eae01980dc694107bdee0bc723d75a0dd601f0e/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs#L2330

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions