Repository navigation
System.BadImageFormatException when reflecting on BCL shipped with Mono #17278
Copy link
Copy link
Closed
Description
Mono throws exception when methods in the BCL are queried for custom attributes.
Steps to Reproduce
- Run test case below
using System;
using System.Reflection;
using System.Linq;
using System.IO;
internal class Program
{
public static int Main(string[] args)
{
foreach (Type type in typeof(System.Linq.Enumerable).Assembly.GetTypes())
{
foreach (MemberInfo method in type.GetMembers(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
{
try
{
method.GetCustomAttributes<DummyAttribute>();
}
catch (BadImageFormatException)
{
Console.WriteLine($"BadImageFormatException {type}:{method}");
throw;
}
}
}
return 0;
}
}
class DummyAttribute : Attribute
{
}
Current Behavior
System.Linq.Parallel.GroupJoinQueryOperator`4[TLeftInput,TRightInput,TKey,TOutput]:System.Linq.Parallel.QueryResults`1[TOutput] Open(System.Linq.Parallel.QuerySettings, Boolean)
Unhandled Exception:
System.BadImageFormatException: VAR 3 (TOutput) cannot be expanded in this context with 3 instantiations
at (wrapper managed-to-native) System.Reflection.RuntimeMethodInfo.get_base_method(System.Reflection.RuntimeMethodInfo,bool)
at System.Reflection.RuntimeMethodInfo.GetBaseMethod () [0x00000] in <b814b509d4ad406fb40c6c93e38929e7>:0
at System.MonoCustomAttrs.GetBase (System.Reflection.ICustomAttributeProvider obj) [0x000ad] in <b814b509d4ad406fb40c6c93e38929e7>:0
at System.MonoCustomAttrs.GetCustomAttributes (System.Reflection.ICustomAttributeProvider obj, System.Type attributeType, System.Boolean inherit) [0x000b5] in <b814b509d4ad406fb40c6c93e38929e7>:0
at System.Reflection.RuntimeMethodInfo.GetCustomAttributes (System.Type attributeType, System.Boolean inherit) [0x00000] in <b814b509d4ad406fb40c6c93e38929e7>:0
at System.Attribute.GetCustomAttributes (System.Reflection.MemberInfo element, System.Type type, System.Boolean inherit) [0x00088] in <b814b509d4ad406fb40c6c93e38929e7>:0
at System.Attribute.GetCustomAttributes (System.Reflection.MemberInfo element, System.Type type) [0x00000] in <b814b509d4ad406fb40c6c93e38929e7>:0
at System.Reflection.CustomAttributeExtensions.GetCustomAttributes (System.Reflection.MemberInfo element, System.Type attributeType) [0x00000] in <b814b509d4ad406fb40c6c93e38929e7>:0
at System.Reflection.CustomAttributeExtensions.GetCustomAttributes[T] (System.Reflection.MemberInfo element) [0x00000] in <b814b509d4ad406fb40c6c93e38929e7>:0
at Program.Main (System.String[] args) [0x00057] in <a28b7bf7d0b34731b1ba0283bc2d394c>:0
[ERROR] FATAL UNHANDLED EXCEPTION: System.BadImageFormatException: VAR 3 (TOutput) cannot be expanded in this context with 3 instantiations
at (wrapper managed-to-native) System.Reflection.RuntimeMethodInfo.get_base_method(System.Reflection.RuntimeMethodInfo,bool)
at System.Reflection.RuntimeMethodInfo.GetBaseMethod () [0x00000] in <b814b509d4ad406fb40c6c93e38929e7>:0
at System.MonoCustomAttrs.GetBase (System.Reflection.ICustomAttributeProvider obj) [0x000ad] in <b814b509d4ad406fb40c6c93e38929e7>:0
at System.MonoCustomAttrs.GetCustomAttributes (System.Reflection.ICustomAttributeProvider obj, System.Type attributeType, System.Boolean inherit) [0x000b5] in <b814b509d4ad406fb40c6c93e38929e7>:0
at System.Reflection.RuntimeMethodInfo.GetCustomAttributes (System.Type attributeType, System.Boolean inherit) [0x00000] in <b814b509d4ad406fb40c6c93e38929e7>:0
at System.Attribute.GetCustomAttributes (System.Reflection.MemberInfo element, System.Type type, System.Boolean inherit) [0x00088] in <b814b509d4ad406fb40c6c93e38929e7>:0
at System.Attribute.GetCustomAttributes (System.Reflection.MemberInfo element, System.Type type) [0x00000] in <b814b509d4ad406fb40c6c93e38929e7>:0
at System.Reflection.CustomAttributeExtensions.GetCustomAttributes (System.Reflection.MemberInfo element, System.Type attributeType) [0x00000] in <b814b509d4ad406fb40c6c93e38929e7>:0
at System.Reflection.CustomAttributeExtensions.GetCustomAttributes[T] (System.Reflection.MemberInfo element) [0x00000] in <b814b509d4ad406fb40c6c93e38929e7>:0
at Program.Main (System.String[] args) [0x00057] in <a28b7bf7d0b34731b1ba0283bc2d394c>:0
Expected Behavior
No Exception
On which platforms did you notice this
[X ] macOS
[ ] Linux
[ X] Windows
Version Used:
Mono JIT compiler version 6.4.0.198 (2019-06/fe64a4765e6 Wed Sep 18 14:14:51 EDT 2019)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
TLS:
SIGSEGV: altstack
Notification: kqueue
Architecture: amd64
Disabled: none
Misc: softdebug
Interpreter: yes
LLVM: yes(610)
Suspend: hybrid
GC: sgen (concurrent by default)
Corresponds to Unity Issue: https://issuetracker.unity3d.com/issues/badimageformatexception-is-thrown-when-calling-getcustomattributes-on-certain-memberinfo-instances
Reactions are currently unavailable
Activity
[-]System.BadImageFormatException when reflection on class libraries[/-][+]System.BadImageFormatException when reflecting on BCL shipped with Mono[/+]marek-safar commentedon Oct 10, 2019
/cc @lambdageek
QFSW commentedon Oct 11, 2019
Original reporter of the issue, wondering if it's possible for this exception to be thrown when inspecting user code or if it is safe to ignore
joncham commentedon Oct 11, 2019
@QFSW I think this is problem related to complex usage of generic parameters with inheritance, so I expect this could show up in any code but very unlikely.
QFSW commentedon Oct 11, 2019
Gotcha, in that case the chance of it popping up in user code AND being something I'm even remotely interested in are remotely small, thanks
baulig commentedon Oct 17, 2019
This seems to come from this block here:
mono/mono/metadata/class.c
Lines 726 to 738 in e5721bb
The
can_inflate_gparam_with()call this:mono/mono/metadata/class.c
Lines 625 to 637 in e5721bb
So it could be an unexpected type or too many generic argument / too complex of a generic instantiation for the code to handle it properly.
lambdageek commentedon Oct 21, 2019
Thanks Martin!
It's happening when we're looking at this method: https://github.com/dotnet/corefx/blob/b49a8a9be1d53cd9e50cb68fd8540be25c65d433/src/System.Linq.Parallel/src/System/Linq/Parallel/QueryOperators/Binary/GroupJoinQueryOperator.cs#L64 which is an override in a child class that has 4 generic type parameters of a method that comes from a base class that has 3 generic type parameters. So at some point we started looking at the wrong context.
lambdageek commentedon Oct 21, 2019
Standalone repro
lambdageek commentedon Oct 21, 2019
Broken since at least 5.12.0.311 (2018-02)
[reflection] mono_method_get_base_method on a GTD should use canonica…
[reflection] mono_method_get_base_method on a GTD should use canonica…
[reflection] mono_method_get_base_method on a GTD should use canonica…
lambdageek commentedon Oct 22, 2019
Keeping open until the 2019-10 backport lands
[2019-10] [reflection] mono_method_get_base_method on a GTD should us…
Bump to mono/mono@18920a83 (#3753)
Bump to mono/mono@18920a83 (#3753)
[reflection] mono_method_get_base_method on a GTD should use canonica…
Bump to mono/mono@2edccc52 (#3981)