Bugzilla – Bug 315174
[PATCH] mcs does not emit assembly qualified type name for types used in attributes
Last modified: 2007-09-15 21:24:46 UTC
---- Reported by gert.driesen@pandora.be 2004-06-18 16:00:10 MST ---- mcs does not seem to emit the right assembly qualifed name of a type that's used in an assembly. Apparently the publickeytoken is always null. compile the following code (with /r:System.Drawing.dll) : using System; using System.ComponentModel; using System.Drawing.Design; public class EntryPoint { public static void Main () { Type type = typeof(TestClass); object[] attributes = type.GetCustomAttributes (false); Console.WriteLine (attributes.Length); } } [Editor ("Doesn't Matter", typeof(UITypeEditor))] public class TestClass { } when you run the built exe, you'll get the following exception : ** (test.exe:3972): WARNING **: Cannot load type 'System.Drawing.Design.UITypeEd itor, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=null' Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object in <0x00016> System.ComponentModel.EditorAttribute:.ctor (string,System.Type) in (unmanaged) (wrapper managed-to-native) System.MonoCustomAttrs:GetCustomAttri butes (System.Reflection.ICustomAttributeProvider) in <0x00004> (wrapper managed-to-native) System.MonoCustomAttrs:GetCustomAttribu tes (System.Reflection.ICustomAttributeProvider) in <0x0004a> System.MonoCustomAttrs:GetCustomAttributes (System.Reflection.ICust omAttributeProvider,bool) in <0x00010> System.MonoType:GetCustomAttributes (bool) in <0x00023> EntryPoint:Main () As you can see, Mono is trying to load the type with a null publickeytoken, as this is what's emitted by mcs. ---- Additional Comments From sebastien@ximian.com 2004-06-19 11:15:23 MST ---- Confirmed as a compiler/runtime issue as the same code assembly (compiled by mcs) doesn't work on the MS runtime either. ---- Additional Comments From sebastien@ximian.com 2004-06-19 11:18:29 MST ---- There's also no problem when we are only referencing corlib. So the following code returns 1 on both Mono and MS runtime (compiled by MCS). using System; using System.Reflection; public class EntryPoint { public static void Main () { Type type = typeof(TestClass); object[] attributes = type.GetCustomAttributes (false); Console.WriteLine (attributes.Length); } } [AttributeUsage (AttributeTargets.All)] public class TestClass { } ---- Additional Comments From sebastien@ximian.com 2004-06-19 11:39:23 MST ---- We get a very similar error when the original source code is compiled by CSC (7.1) and executed on Mono (CVS). This time we have the public key token (so MCS, or a runtime function used by MCS, must have a problem here) but we still get the same error about loading the type (resulting in the later NullReferenceException). ** (https://bugzilla.novell.com/show_bug.cgi?id=MONO60439.exe:17813): WARNING **: Cannot load type 'System.Drawing.Design.UITypeEditor,System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object in <0x00016> System.ComponentModel.EditorAttribute:.ctor (string,System.Type) in (unmanaged) (wrapper managed-to-native) System.MonoCustomAttrs:GetCustomAttributes (System.Reflection.ICustomAttributeProvider) in <0x00004> (wrapper managed-to-native) System.MonoCustomAttrs:GetCustomAttributes (System.Reflection.ICustomAttributeProvider) in <0x0004d> System.MonoCustomAttrs:GetCustomAttributes (System.Reflection.ICustomAttributeProvider,bool) in <0x00010> System.MonoType:GetCustomAttributes (bool) in <0x00023> EntryPoint:Main () ---- Additional Comments From sebastien@ximian.com 2004-06-19 11:59:48 MST ---- The problem disappears if the type was already use (i.e. loaded) before. For example adding the following line just before "type.GetCustomAttributes" returns on the console 1 (as expected). Type t = Type.GetType ("System.Drawing.Design.UITypeEditor,System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"); ---- Additional Comments From sebastien@ximian.com 2004-06-21 09:00:43 MST ---- There seems to be two bugs here (1) mcs doesn't include the public key token in the compiled assembly (as CSC does). (2) the code fails wheter or not the public key token is present. The problem seems located in reflection.c, function mono_reflection_type_from_name. Right now the assembly isn't loaded if it hasn't yet been used (see comments ;-). /* do we need to load if it's not already loaded? */ ---- Additional Comments From sebastien@ximian.com 2004-06-21 09:30:38 MST ---- Here's a patch for problem #2. This works for both MCS and CSC compiled test because a null public key token is valid and will (try to) match an assembly. ---- Additional Comments From sebastien@ximian.com 2004-06-21 09:31:25 MST ---- Created an attachment (id=166274) reflection.diff ---- Additional Comments From sebastien@ximian.com 2004-06-21 11:12:41 MST ---- Patch for problem #2 now in CVS. As for problem #1 running monodis on the test code shows that MCS do not include the public key token of the attribute class in the assembly. ---- Additional Comments From sebastien@ximian.com 2004-06-21 12:08:20 MST ---- Moved issue to runtime. MCS on the MS runtime does include the public key token in the assembly. ---- Additional Comments From sebastien@ximian.com 2004-06-21 16:33:04 MST ---- More informations... Managed-side (MCS) Stack trace (true for both runtime) 1. Mono.CSharp.Driver.Main 2. Mono.CSharp.Driver.MainDriver 3. Mono.CSharp.RootContext.EmitCode 4. Mono.CSharp.TypeContainer.Emit 5. Mono.CSharp.Attributes.Emit 6. Mono.CSharp.Attribute.Emit 7. Mono.CSharp.Attribute.Resolve Managed-side (mono class library) 1. public CustomAttributeBuilder (ConstructorInfo con, object[] constructorArgs) 2. Initialize (...) 3. GetBlob (...) The two arguments to the constructor are a System.String and a System.MonoType (which, "somehow", represents the System.Drawing.Design.UITypeEditor). MonoType seems to behave differently from RuntimeType. Runtime (mono) 1. mono_reflection_get_custom_attrs_blob (...) 2. encode_cattr_value (...) 3. we switch in the case MONO_TYPE_CLASS 4. str = type_get_qualified_name (((MonoReflectionType*)arg)->type, NULL); The runtime is able to find the MonoType internal informations (i.e. it's real type). The resulting string has the right class name, assembly name and version but doesn't have a public key token (so null is used). ---- Additional Comments From sebastien@ximian.com 2004-06-22 08:59:41 MST ---- Added patch for problem #2 (assembly.diff). The public key was loaded in mono_assembly_fill_assembly_name but the public key token wasn't created (so was unavailable later). ---- Additional Comments From sebastien@ximian.com 2004-06-22 09:00:16 MST ---- Created an attachment (id=166275) assembly.diff ---- Additional Comments From sebastien@ximian.com 2004-06-22 10:43:50 MST ---- Patch 'assembly.diff' is not correct (was using ASCII representation, not the byte array). New patch "final.diff" has the (hopefully) correct fix for closing the bug. ---- Additional Comments From sebastien@ximian.com 2004-06-22 10:44:23 MST ---- Created an attachment (id=166276) final.diff ---- Additional Comments From sebastien@ximian.com 2004-06-22 16:04:42 MST ---- Updated patch for problem #2 (p2.diff). Changes * public key token was a string (not a byte array); * public key token is now totally (not a pointer) inside MonoAssemblyName (so we don't leak it); * includes fix for #60519 (referenced assemblies in icall.c) ---- Additional Comments From sebastien@ximian.com 2004-06-22 16:05:12 MST ---- Created an attachment (id=166277) p2.diff ---- Additional Comments From sebastien@ximian.com 2004-06-22 17:14:32 MST ---- Fixed in CVS. Imported an attachment (id=166274) Imported an attachment (id=166275) Imported an attachment (id=166276) Imported an attachment (id=166277) Unknown operating system unknown. Setting to default OS "Other".