Bug 33208 - System.Reflection.Module.ResolveMember() returning inconsistent results when querying dynamic assemblies
Summary: System.Reflection.Module.ResolveMember() returning inconsistent results when ...
Status: CONFIRMED
Alias: None
Product: Runtime
Classification: Mono
Component: Reflection (show other bugs)
Version: 4.4.0 (C7)
Hardware: All All
: --- normal
Target Milestone: ---
Assignee: Aleksey Kliger
URL:
Depends on:
Blocks:
 
Reported: 2015-08-18 18:12 UTC by Eirik Tsarpalis
Modified: 2016-09-21 14:21 UTC (History)
4 users (show)

See Also:
Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
F# script that reproduces the issue. (519 bytes, application/octet-stream)
2015-08-18 18:12 UTC, Eirik Tsarpalis
Details
C# script that reproduces the issue in the csharp repl (507 bytes, application/octet-stream)
2015-08-18 18:13 UTC, Eirik Tsarpalis
Details

Description Eirik Tsarpalis 2015-08-18 18:12:23 UTC
Created attachment 12563 [details]
F# script that reproduces the issue.

I came across this issue when using the Mono.Reflection library to read method instructions from dynamic assemblies.
Comment 1 Eirik Tsarpalis 2015-08-18 18:13:01 UTC
Created attachment 12564 [details]
C# script that reproduces the issue in the csharp repl

C# script that reproduces the issue in the csharp repl
Comment 2 Eirik Tsarpalis 2015-08-18 18:19:22 UTC
See also https://github.com/nessos/Vagabond/issues/2
Comment 3 Zoltan Varga 2015-08-23 01:37:23 UTC
The two fields seem to have the same token:
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
public class Foo {
	public static System.Object x;

	public class Bar<T> {
		public T value;
	}
}

var f0 = typeof(Foo).GetField("x");
var f1 = typeof(Foo.Bar<int>).GetField("value");
Console.WriteLine (f0.MetadataToken);
Console.WriteLine (f1.MetadataToken);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Comment 4 Eirik Tsarpalis 2015-08-24 09:40:46 UTC
Yes. Am I right to assume that this should not happen inside a single module?
Comment 5 Marek Safar 2015-09-21 05:05:42 UTC
This is reflection issue. Self contained repro

using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Threading;
using System.IO;

class X
{
	public static void Main ()
	{
		AssemblyName asmName = 
			new AssemblyName("NestedTypeGenericField");
		AppDomain domain = AppDomain.CurrentDomain;
		AssemblyBuilder demoAssembly = 
			domain.DefineDynamicAssembly(
				asmName, 
				AssemblyBuilderAccess.RunAndSave
			);

		ModuleBuilder module = 
			demoAssembly.DefineDynamicModule(
				asmName.Name, 
				asmName.Name + ".dll"
			);

		TypeAttributes attrs = TypeAttributes.Public;
		TypeBuilder tb = module.DefineType ("Foo", attrs);

		tb.DefineField ("x", typeof (object), FieldAttributes.Static | FieldAttributes.Public);

		var tnested = tb.DefineNestedType ("Bar`1", TypeAttributes.NestedPublic);
		var gpn = tnested.DefineGenericParameters ("T");
		tnested.DefineField ("value", gpn [0], FieldAttributes.Public);

		var tn = tnested.CreateType ();

		var t = tb.CreateType ();

		demoAssembly.Save(asmName.Name + ".dll");

		var f0 = t.GetField("x");
		var f1 = tn.GetField("value");
		Console.WriteLine (f0.MetadataToken);
		Console.WriteLine (f1.MetadataToken);

		return;
	}
}
Comment 6 Aleksey Kliger 2015-10-05 15:38:35 UTC
Simpler repro: no generics, no nested classes:

using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Threading;
using System.IO;

class X
{
	public static void Main ()
		{
			AssemblyName asmName = 
				new AssemblyName("NestedTypeGenericField");
			AppDomain domain = AppDomain.CurrentDomain;
			AssemblyBuilder demoAssembly = 
				domain.DefineDynamicAssembly(
					asmName, 
					AssemblyBuilderAccess.RunAndSave
					);

			ModuleBuilder module = 
				demoAssembly.DefineDynamicModule(
					asmName.Name, 
					asmName.Name + ".dll"
					);

			// public class Foo {
			//   public static object x;
			// }
			// public class Bar {
			//     public static object y;
			// }
			TypeAttributes attrs = TypeAttributes.Public;
			TypeBuilder tb = module.DefineType ("Foo", attrs);

			tb.DefineField ("x", typeof (Object),
					FieldAttributes.Static
					| FieldAttributes.Public);

			var tb2 = module.DefineType ("Bar",
						     attrs);
			tb2.DefineField ("y", typeof (Object),
					 FieldAttributes.Static
					 | FieldAttributes.Public);

			var t2 = tb2.CreateType ();

			var t = tb.CreateType ();

			demoAssembly.Save(asmName.Name + ".dll");

			var f0 = t.GetField("x");
			Console.WriteLine ("0x{0:x}", f0.MetadataToken);
			var f1 = t2.GetField("y");
			Console.WriteLine("0x{0:x}", f1.MetadataToken);

			return;
		}
}

Note You need to log in before you can comment on or make changes to this bug.