gpt4 book ai didi

windows - x86 LargeAddressAware 兼容性的单元测试

转载 作者:可可西里 更新时间:2023-11-01 12:51:07 29 4
gpt4 key购买 nike

对于 win32 可执行文件 (x86),我们可以设置 LargeAddressAware 标志,以便它在 x64 Windows 上运行时可以访问 4 GB(而不是仅仅 2 GB)的虚拟地址空间。
这看起来很吸引人。但是,也存在风险。
例如,请参阅:Drawbacks of using /LARGEADDRESSAWARE for 32 bit Windows executables?

因此,让我们继续配置正在执行一些单元测试 的系统,并将系统范围的注册表开关AllocationPreference 设置为MEM_TOP_DOWN
应该这样做,不是吗?

没有!
问题在于 Visual Studio 的 x86“测试运行器”(执行引擎)本身未启用 LAA。
这个父进程只会看到“较低的”2 GB 的 VAS,我们要测试的模块也是如此。

来自 VS2013.1 的例子

  • mstest.exe 生成 QTAgent32.exe
  • vstest.console.exe 生成 vstest.executionengine.x86.exe

所有这些都启用 LAA!

那么使用启用了 LAA 的 x86 测试运行程序的推荐方法是什么?


这里有一小段代码(VS 单元测试,csharp)来检查 LAA 执行环境。
除非它成功,否则您的测试环境适合让您的单元测试集(也)涵盖与 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) + ")");
}
}
}

最佳答案

到目前为止,我只遇到过建议将问题中列出的 Microsoft 二进制文件弄乱(即使用 editbin.exe 手动“修补”它们)。但这有以下缺点:

  • 一旦为 Visual Studio 安装了任何 future 的服务包,我需要重复打补丁
  • 我无法再并行测试:“常规”x86 和带有 LAA 的“扩展”x86

似乎微软必须实现一个适当的长期解决方案?:
http://visualstudio.uservoice.com/forums/196039-microsoft-test-tools/suggestions/5781437

关于windows - x86 LargeAddressAware 兼容性的单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23114068/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com