2012-11-24 2 views
2

저는 컴파일러와 Windows 4.5가 설치된 .NET 4.5의 문제점을 해결하기 위해 노력하고 있습니다. 코드 조각을 간단히 만들었고 누군가가 문제에 대한 통찰력. 리플렉션을 사용하여 문제를 나타내는 어셈블리를 생성하는 C#을 작성했습니다. C#은 (여기 VS2010 솔루션에서 https://dl.dropbox.com/u/10931452/sdata.zip)이 게시물의 하단에 있습니다. 'sdata'클래스를 만들고 'blank16'이라는 정적 필드를 추가합니다. 그런 다음이 필드를 초기화하는 정적 생성자를 만듭니다. 결과 실행 파일은 c : \ temp \ sdatatest.exe에 기록됩니다. sdatatest는 .NET 4.5에서 Windows 8을 실행하면 그것은 생산 :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()

가 실행 설치 .NET 4.5 윈도우 7에서 실행합니다. 이전 .NET 프레임 워크에서 실행될 때도 실행되고 10 년 동안 수행되었습니다. 일리노이 생산

유효 같습니다

enter image description here

JITed 86 코드도 완벽하게 유효 같습니다 EDI의

enter image description here

값은로드 된 실행 파일의 위치처럼 의심스럽게 보이는 관리되는 메모리 공간이 아니라 읽기 전용 인 경우 액세스 위반을 설명합니다. 왜 이것이 Windows 8에서 변경 될까요? 이 읽기 전용으로 만들기 :

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)); 
     } 
    } 
} 
+0

생성 된 어셈블리에서 PEVerify를 실행 해 보셨습니까? – svick

+0

ModuleBuilder.CreateGlobalFunctions()가 코드에서 누락되었으므로 DefineUninitializedData()를 사용할 때 필요합니다. 그래도 도움이되지 않으면 connect.microsoft.com에서 버그 보고서를 제출하십시오. –

+0

ModuleBuilder.CreateGlobalFunctions()가 아무런 변화가 없었습니다 (불행히도). – Rob

답변

5

대답은 윈도우 8이 .sdata 부분에 대한 액세스 권한을 변경한다는 것입니다 :

C#을 sdatatest 어셈블리를 생성합니다. DefineUninitializedData를 사용하는 경우에는 코드가 Windows 8에서 중단되고 변경해야합니다.