7

Für eine Win32-ausführbare Datei (x86) können wir das LargeAddressAware-Flag festlegen, so dass es auf einen virtuellen Adressraum von 4 GB (statt nur 2 GB) auf x64 Windows zugreifen kann.
Das sieht sehr ansprechend aus. Es gibt jedoch Risiken. siehe
Zum Beispiel: Drawbacks of using /LARGEADDRESSAWARE for 32 bit Windows executables?Unit Testing für x86 LargeAddressAware Kompatibilität

So lassen Sie uns fortfahren und konfigurieren Sie das System, das einige Unit-Tests mit der systemweiten Registrierungsschalter AllocationPreference Satz MEM_TOP_DOWN ausgeführt wird.
Das sollte tun, sollte es nicht?

Es tut es nicht!
Das Problem ist, dass der x86 "Test Runner" (Ausführungsengine) von Visual Studio nicht LAA selbst aktiviert ist.
Dieser übergeordnete Prozess sieht nur die "niedrigeren" 2 GB VAS, und so werden unsere Module getestet.

Beispiele aus VS2013.1

  • mstest.exe laicht QTAgent32.exe
  • vstest.console.exe Spawns vstest.executionengine.x86.exe

Alle von ihnen sind nicht LAA aktiviert!

Also, was ist die empfohlene Möglichkeit, einen x86 Test Runner zu verwenden, der LAA aktiviert ist?


hier ein kleiner Code-Schnipsel (VS Unit-Test, csharp) für LAA Ausführungsumgebung zu überprüfen.
es sei denn, es gelingt die Testumgebung ist nicht geeignet Ihren Satz von Unit-Tests zu haben (auch) deckt die Kompatibilität mit LAA:

using System; 
using System.Diagnostics; 
using System.Runtime.InteropServices; 
using Microsoft.VisualStudio.TestTools.UnitTesting; 

namespace TestCheckEnv32LAA 
{ 
    [TestClass] 
    public class CheckEnv32LAA 
    { 
     #region [Native DLL import] 

     [Flags()] 
     public enum AllocationType : uint 
     { 
      COMMIT = 0x1000, 
      RESERVE = 0x2000, 
      RESET = 0x80000, 
      LARGE_PAGES = 0x20000000, 
      PHYSICAL = 0x400000, 
      TOP_DOWN = 0x100000, 
      WRITE_WATCH = 0x200000 
     } 

     [Flags()] 
     public enum MemoryProtection : uint 
     { 
      EXECUTE = 0x10, 
      EXECUTE_READ = 0x20, 
      EXECUTE_READWRITE = 0x40, 
      EXECUTE_WRITECOPY = 0x80, 
      NOACCESS = 0x01, 
      READONLY = 0x02, 
      READWRITE = 0x04, 
      WRITECOPY = 0x08, 
      GUARD_Modifierflag = 0x100, 
      NOCACHE_Modifierflag = 0x200, 
      WRITECOMBINE_Modifierflag = 0x400 
     } 

     [StructLayout(LayoutKind.Sequential)] 
     struct MEMORYSTATUSEX 
     { 
      public uint dwLength; 
      public uint dwMemoryLoad; 
      public ulong ullTotalPhys; 
      public ulong ullAvailPhys; 
      public ulong ullTotalPageFile; 
      public ulong ullAvailPageFile; 
      public ulong ullTotalVirtual; 
      public ulong ullAvailVirtual; 
      public ulong ullAvailExtendedVirtual; 
     } 

     [DllImport("kernel32.dll")] 
     extern static void GlobalMemoryStatusEx(ref MEMORYSTATUSEX status); 

     [DllImport("kernel32.dll", SetLastError = true)] 
     public static extern UIntPtr VirtualAlloc(UIntPtr lpAddress, UIntPtr dwSize, 
     AllocationType flAllocationType, MemoryProtection flProtect); 

     #endregion 

     public CheckEnv32LAA() 
     { 
     } 

     [TestMethod] 
     public void CheckEnvironment32LAA() 
     { 
      // check for a suitable environment to test modules for compatibility with LargeAddressAware (LAA): 
      // 1) OS must be x64 
      // 2) test runner must be x86 
      // 3) test runner must be LAA enabled itself 
      // 4) memory allocation (with manual TopDown flag) must happen beyond the 2 GB boundary 
      // 5) memory allocation (with default settings) must happen beyond the 2 GB boundary 
      // 
      // RE 3) this requirement is true for "regular" unit tests (to test DLL modules). it does not apply 
      // for any tests spawning the application (EXE) to be tested as a separate process. 
      // 
      // RE 5) a failure indicates the following registry switch has not been set: 
      // [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management] 
      // "AllocationPreference"=dword:00100000 
      // 
      // see: 
      // https://stackoverflow.com/questions/2288728/ 

      String sParentProcName = Process.GetCurrentProcess().MainModule.FileName; 

      //CHECK_1 
      Assert.IsTrue(Environment.Is64BitOperatingSystem, "Test is not executing on x64 OS"); 

      //CHECK_2 
      Assert.IsFalse(Environment.Is64BitProcess, "Test runner is not x86: " + sParentProcName); 

      //CHECK_3 
      MEMORYSTATUSEX tmpStatus = new MEMORYSTATUSEX(); 
      tmpStatus.dwLength = (uint)Marshal.SizeOf(typeof(MEMORYSTATUSEX)); 
      tmpStatus.ullTotalPhys = 0; 
      GlobalMemoryStatusEx(ref tmpStatus); 
      ulong uVM = tmpStatus.ullTotalVirtual; 
      Assert.IsTrue(uVM > 0x80000000, "Test runner is not LAA enabled (max: " + uVM/(1024 * 1024) + "): " + sParentProcName); 
      Assert.IsTrue(uVM <= 0x100000000, "Test runner is not x86 (max: " + uVM/(1024 * 1024) + "): " + sParentProcName); 

      //CHECK_4 
      UIntPtr pMem = UIntPtr.Zero; 
      ulong uAddress = 0; 
      pMem = VirtualAlloc(UIntPtr.Zero, (UIntPtr)1024, AllocationType.RESERVE | AllocationType.TOP_DOWN, MemoryProtection.READWRITE); 
      uAddress = (ulong)pMem; 
      Assert.IsTrue(uAddress > 0x80000000, "Test runner is not LAA enabled (highest: " + uAddress/(1024 * 1024) + "): " + sParentProcName); 

      //CHECK_5 
      pMem = VirtualAlloc(UIntPtr.Zero, (UIntPtr)1024, AllocationType.RESERVE, MemoryProtection.READWRITE); 
      uAddress = (ulong)pMem; 
      Assert.IsTrue(uAddress > 0x80000000, "System-wide MEM_TOP_DOWN is not set (allocated at: " + uAddress/(1024 * 1024) + ")"); 
     } 
    } 
} 
+0

Bitte beachten Sie, dass die 4 GB Adressraum auf 64-Bit-Systeme verfügbar ist. Auf 32-Bit-Systemen können große adresssensitive Anwendungen nur 3 GB adressieren. –

+2

Patchen der EXE mit editbin.exe ist die einzige pragmatische Lösung. –

Antwort

3

Bisher habe ich nur mit den Microsoft-Binärdateien über Vorschläge zu Chaos kommen in der Frage aufgelistet (dh verwenden, um sie manuell zu "patchen"). Das hat aber folgende Nachteile:

  • Ich muss wiederholen, wird das Patchen einmal jeder zukünftigen Service Pack für Visual Studio installiert
  • ich kann nicht mehr Test parallel: „regular“ x86 und „extended“ x86 mit LAA

Es scheint eine richtige langfristige Lösung würde von Microsoft umgesetzt werden müssen ?:
http://visualstudio.uservoice.com/forums/196039-microsoft-test-tools/suggestions/5781437