我正试图用我们的编译器和.NET 4.5与Windows 8的问题的底部。我简化了它的一小段代码,并想知道如果有人有任何洞察问题。我写了一些使用反射的C#来生成显示问题的程序集。 C#(在VS2010解决方案中,此处为https://dl.dropbox.com/u/10931452/sdata.zip)位于本文的底部。它创建一个类'sdata'并为其添加一个名为'blank16'的静态字段。然后它创建一个静态构造函数来初始化这个字段。生成的可执行文件写入c:\ temp \ sdatatest.exe。当sdatatest在Windows 8下的.NET 4.5中运行它产生:Windows 8,.NET 4.5 DefineUninitializedData问题
Unhandled Exception: System.TypeInitializationException: The type initializer for 'sdata' threw an exception. ---> System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. at sdata..cctor() --- End of inner exception stack trace --- at sdata.main()
在Windows 7与.NET 4.5安装运行运行。在早期的.NET框架上运行时,它也会运行 - 并且已经运行了十年。
的IL产生看起来有效:
的JIT编译x86代码看起来完全有效的太:
EDI的值看起来很像一个位置,在加载的可执行而不是在托管的内存空间中,如果它是只读的,则会解释访问冲突。为什么会在Windows 8上进行更改?
C#生产sdatatest组件:
using System;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
using System.Threading;
namespace sdata
{
class Program
{
static void Main(string[] args)
{
AssemblyName name = new AssemblyName();
name.Name = "sdatatest.exe";
string exepath = "c:\\temp\\" + name.Name;
name.CodeBase = "file:://" + exepath;
AssemblyBuilder ass_bldr = Thread.GetDomain().DefineDynamicAssembly(name, AssemblyBuilderAccess.RunAndSave, Path.GetDirectoryName(exepath));
ModuleBuilder module_bldr = ass_bldr.DefineDynamicModule(Path.GetFileName(exepath), Path.GetFileName(exepath), true);
TypeBuilder tb = module_bldr.DefineType("sdata", TypeAttributes.Public | TypeAttributes.AnsiClass);
TypeBuilder sixteen = module_bldr.DefineType("sixteen", TypeAttributes.Sealed, typeof(ValueType), PackingSize.Size8, 16); // value type of size 16
Type t16 = sixteen.CreateType();
var fb = tb.DefineUninitializedData("blank16", 16, FieldAttributes.Public | FieldAttributes.Static);
ConstructorBuilder cons = tb.DefineConstructor(MethodAttributes.Static, CallingConventions.Standard, Type.EmptyTypes); // ..cctor
var il = cons.GetILGenerator();
il.BeginScope();
il.Emit(OpCodes.Ldsflda, fb);
il.Emit(OpCodes.Ldc_I4, 0);
il.Emit(OpCodes.Ldc_I4, 16);
il.Emit(OpCodes.Initblk);
il.Emit(OpCodes.Ret);
il.EndScope();
MethodBuilder mb = tb.DefineMethod("main", MethodAttributes.Static | MethodAttributes.Public);
il = mb.GetILGenerator();
il.BeginScope();
il.Emit(OpCodes.Ldsflda, fb);
il.Emit(OpCodes.Pop);
il.Emit(OpCodes.Ret);
il.EndScope();
tb.CreateType();
ass_bldr.SetEntryPoint(mb);
ass_bldr.Save(Path.GetFileName(exepath));
}
}
}
我假设你尝试在生成的程序集上运行PEVerify? – svick
您的代码中缺少ModuleBuilder.CreateGlobalFunctions(),当您使用DefineUninitializedData()时,它是必需的。如果这没有帮助,请在connect.microsoft.com上提交错误报告。 –
ModuleBuilder.CreateGlobalFunctions()没有任何区别(不幸)。 – Rob