首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Windows 8,.NET 4.5 DefineUninitializedData问题

Windows 8,.NET 4.5 DefineUninitializedData问题
EN

Stack Overflow用户
提问于 2012-11-24 13:04:54
回答 1查看 539关注 0票数 2

我试图找出我们的编译器和Windows4.5的问题,我已经把它简化成一小块代码,想知道是否有人对这个问题有任何深入的了解。我编写了一些使用反射生成显示问题的程序集的C#。C# is (在VS2010解决方案中,这里是https://dl.dropbox.com/u/10931452/sdata.zip)位于文章的底部。它创建一个类“sdata”,并向其添加一个名为“blank16”的静态字段。然后,它创建一个静态构造函数来初始化该字段。生成的可执行文件被写入c:\temp\sdatatest.exe。当在.NET 4.5下的Windows 8上运行sdatatest时,它会生成:

未处理的异常: System.TypeInitializationException:“sdata”的类型初始化程序抛出一个异常。-> System.AccessViolationException:试图读取或写入受保护的内存。这通常表明其他内存已损坏。在sdata..cctor() --内部异常堆栈跟踪的末尾--在sdata.main()

在安装了.NET 4.5的Windows 7上运行时,它会运行。当在早期的.NET框架上运行时,它也会运行--并且已经运行了十年。

产生的IL看起来是有效的:

JITed x86代码看起来也非常有效:

edi的值看起来可疑地类似于加载的可执行文件中的位置,而不是托管内存空间中的位置,如果它是只读的,这将解释访问冲突。但是为什么Windows 8会改变这种情况呢?

C#用于生成数据最多的程序集:

代码语言:javascript
复制
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 ) );
        }
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-12-10 21:41:31

答案是Windows 8已经更改了.sdata部分的访问权限:使其只读。如果您使用的是DefineUninitializedData,那么您的代码可能会在Windows 8上中断,需要进行更改。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13541483

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档