Bug 29679 - Mono crashes with "Assertion at class.c:5748" when getting custom attributes from corefx contract assembly
Mono crashes with "Assertion at class.c:5748" when getting custom attributes ...
 Status: RESOLVED FIXED None Runtime Mono JIT () unspecified PC Windows Normal normal --- Zoltan Varga

 Reported: 2015-05-02 22:11 UTC by Alexander Köplinger 2015-07-28 23:07 UTC (History) 5 users (show) htl10 miguel mono-bugs+mono mono-bugs+runtime saper ---

Attachments
Repro code (51.19 KB, application/x-zip-compressed)
2015-05-02 22:11 UTC, Alexander Köplinger
Details

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on GitHub or Developer Community with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

 Status: RESOLVED resolved as  FIXED

 Alexander Köplinger 2015-05-02 22:11:52 UTC Created attachment 11033 [details] Repro code Unpack the attached zip and cd into the directory, then do "mcs test.cs" and run it with "mono test.exe". On Mono, this results in the following crash: > $mono test.exe > System.Console, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a > ReflectionOnlyAssemblyResolve: System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a > Can't find custom attr constructor image: /home/alexander/Desktop/System.Console.dll mtoken: 0x0a000003 > * Assertion at class.c:5748, condition !mono_loader_get_last_error ()' not met > > Stacktrace: > > * Assertion at class.c:5748, condition !mono_loader_get_last_error ()' not met > > Aborted (core dumped) Expected output from MS.NET > System.Console, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a > ReflectionOnlyAssemblyResolve: System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a > attr:[System.Reflection.AssemblyInformationalVersionAttribute("4.6.22809.00 built by: PROJECTK")] This is currently blocking the corefx build with the open-sourced MSBuild on Unix. Zoltan Varga 2015-05-26 18:04:06 UTC This happens because the 'DebuggingModes' type is encoded in IL as: class System.Diagnostics.DebuggableAttribute/DebuggingModes modes in the System.Runtime assembly, even through its an enum. It should be encoded as: valuetype System.Diagnostics.DebuggableAttribute/DebuggingModes modes The System.Console assembly encodes it correctly. Alexander Köplinger 2015-05-26 18:37:41 UTC @Zoltan: there's something scary going on here. I checked with ikdasm on Linux and it indeed confirms what you say: > .method public hidebysig specialname rtspecialname > instance void .ctor(class >System.Diagnostics.DebuggableAttribute/DebuggingModes modes) cil managed However, opening the assembly in ilasm, ILSpy and dotpeek on Windows results in this: > .method public hidebysig specialname rtspecialname > instance void .ctor(valuetype System.Diagnostics.DebuggableAttribute/DebuggingModes modes) cil managed Note that it reports **valuetype** as expected. So whom do we trust now? Zoltan Varga 2015-05-26 18:41:03 UTC ikdasm returns the actual metadata encoding, no idea what the windows tool return. Alexander Köplinger 2015-05-26 19:33:33 UTC I think ikdasm is wrong here, or at least it doesn't really reflect what is happening under the hood. This commit to ikvm looks related: https://github.com/gluck/ikvm/commit/842a86fb686640338d3c765adf1da56e5b8044c1 Alexander Köplinger 2015-05-26 19:43:20 UTC monodis seems to just crash: >$ monodis System.Runtime.dll >.assembly 'System.Runtime' >{ >Could not load signature of System.Diagnostics.DebuggableAttribute:.ctor due to: Could not parse type argument 0 on method signature >Segmentation fault (core dumped) I'm curious if there's really something wrong in the IL (in which case I'll open a bug at corefx) or if Mono just isn't handling this edge case? Zoltan Varga 2015-05-26 19:53:41 UTC So the problem seems to be that the mono runtime special cases corlib in a few places so it doesn't think that types inheriting System.Runtime's ValueType type are valuetypes. Zoltan Varga 2015-05-29 10:06:17 UTC So the problem is that System.Console.dll is linked against System.Runtime, and the runtime loads the System.Runtime.dll in the current directory, instead of the System.Runtime.dll from the mono installation. Where is that System.Runtime.dll coming from ? Zoltan Varga 2015-05-29 10:09:21 UTC So moving System.Runtime.dll into another dir, and using mono master 4183c9cbc51a869711f709b1cfef832e14ab4943 works. Marcin Cieślak 2015-06-13 14:52:24 UTC Where is this System.Runtime.dll coming from? When I use System.Runtime.dll from my mono master or from CoreCLR it works. Alexander Köplinger 2015-06-13 14:58:17 UTC @Marcin it's coming from the corefx packages, i.e. D:\Dev\corefx\packages\System.Runtime\4.0.20-beta-22927\ref\any\System.Runtime.dll on my machine. Note that I'm investigating another fix so that MSBuild uses Cecil to read the custom attribute instead of using reflection which would make this issue not being hit. Zoltan Varga 2015-06-13 15:38:26 UTC System.Runtime.dll should contain type forwarders to mscorlib etc, this version contain dummy type/method definitions instead. Miguel de Icaza [MSFT] 2015-06-13 21:16:38 UTC IKVM.Reflection is probably better than Mono.Cecil. If all you want is to read metadata, the API is almost identical (except for the initialization) to Reflection.Emit and is very light weight. Marcin Cieślak 2015-06-14 19:58:53 UTC https://github.com/mono/mono/pull/1874 should fix that problem. Marcin Cieślak 2015-06-14 20:05:39 UTC Constructor signature is encoded as: 0x06 0x20 0x01 0x01 0x11 0x84 0x50 ------------- one parameter --------------- return is void --------------- valuetype of -------- 0x114 DebuggingModes type But because valuetypes are kind of sub-classes, it might be possible that disassemblers treat them as classes. Actually the problem here is that DebuggingModes says it's a "class" and Mono is strict enough not to allow to put "class" where "valuetype" is required. Alexander Köplinger 2015-06-14 20:28:54 UTC @Marcin: Thanks for looking into it! I can confirm it fixes the runtime assert, though it doesn't fully work yet. The if clause for "a.AttributeType.Equals (typeof (AssemblyInformationalVersionAttribute)" doesn't appear to be hit. If I change it to "a.AttributeType.Name == "AssemblyInformationalVersionAttribute"" then it crashes with the following exception: >Unhandled Exception: >System.TypeLoadException: Could not load type 'System.Reflection.AssemblyInformationalVersionAttribute' from assembly 'System.Runtime, Version=4.0.20.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. > at (wrapper managed-to-native) System.Reflection.CustomAttributeData:ResolveArgumentsInternal (System.Reflection.ConstructorInfo,System.Reflection.Assembly,intptr,uint,object[]&,object[]&) > at System.Reflection.CustomAttributeData.ResolveArguments () [0x0000c] in /home/alexander/dev/mono/mcs/class/corlib/System.Reflection/CustomAttributeData.cs:76 > at System.Reflection.CustomAttributeData.ToString () [0x00000] in /home/alexander/dev/mono/mcs/class/corlib/System.Reflection/CustomAttributeData.cs:140 > ... Marcin Cieślak 2015-06-14 21:03:24 UTC It seems to work if you move the CoreFX dlls out of the way. Consider: > var asm = Assembly.ReflectionOnlyLoadFrom (Path.GetFullPath ("../System.Console.dll")); This gives the output (for the "a.AttributeType.Equals (typeof (AssemblyInformationalVersionAttribute)" variant): System.Console, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ReflectionOnlyAssemblyResolve: System.Runtime, Version=4.0.20.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ReflectionOnlyAssemblyResolve: System.Resources.ResourceManager, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a attr:[System.Reflection.AssemblyInformationalVersionAttribute("1.0.0.0 built by: DCI-WIN-FBLD-13-dotnet-bot")] if (a.AttributeType.Name == "AssemblyInformationalVersionAttribute") variant gives the same output. Marcin Cieślak 2015-06-22 14:40:43 UTC Zoltan: do you think my fix in https://github.com/mono/mono/pull/1874 is correct? Zoltan Varga 2015-06-22 15:27:33 UTC So the problem is that the assembly is linked against System.Runtime.dll, which should contain type forwarders to the real types in mscorlib. Instead, there is a System.Runtime.dll in the current directory, which contains dummy types. Mono loads this local version, so the types in the assembly will inherit from the dummy ValueType class, not the real ValueType class in mscorlib, so they are not treated as valuetypes as mono, which leads to the loading error. I think this is the correct behavior. Marcin Cieślak 2015-06-22 15:43:09 UTC Without the patch, you will end up with an assertion error - I've had the same when just using 'monodis' on mscorelib.dll. The original problem (not the later one stated by Alexander) was the assertion error, because Mono runtime could not accept something defined as class (token 0x12) to be used as valuetype (0x11). I'd love to have this patch merged, working on the next step will be to improve generics support - because Mono is unable to understand many methods with generic which are contained in the CoreCLR mscorlib.dll - this is https://bugzilla.xamarin.com/show_bug.cgi?id=31244. Alexander Köplinger 2015-06-23 05:40:51 UTC Thanks for applying the patch, it seems to solve the problem if I move System.Runtime.dll out of the folder (which isn't required on MS.NET, but I'm happy to ignore this for now as it's sufficient for the msbuild/corefx on Mono work) Alexander Köplinger 2015-06-23 06:06:07 UTC Zoltan: can this be ported to the Mono 4.2 branch? Zoltan Varga 2015-06-23 10:34:02 UTC Done. Hin-Tak Leung 2015-07-28 22:40:52 UTC I also have monodis crashing (comment 5) with mono 4.0.2.5 - judging from comment 21 the fix is in master and 4.2 but not in any of the other branches? Zoltan Varga 2015-07-28 23:07:14 UTC Yes.