对于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测试运行器的推荐方法是什么?

这是一个用于检查LAA执行环境的小代码片段(VS单元测试,csharp).
除非它成功,否则您的测试环境不适合让您的单元测试(也)覆盖与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,AllocationType.RESERVE,"System-wide MEM_TOP_DOWN is not set (allocated at: " + uAddress / (1024 * 1024) + ")");
        }
    }
}
到目前为止,我只是遇到了混淆问题中列出的Microsoft二进制文件的建议(即使用editbin.exe手动“修补”它们).但这有以下缺点:

>为Visual Studio安装任何未来的Service Pack后,我需要重复修补
>我不能再并行测试:“常规”x86和“扩展”x86与LAA

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

windows – x86 LargeAddressAware兼容性的单元测试的更多相关文章

  1. 如何通过代码设置iOS的系统时区?

    我想通过代码在iOS中设置系统时区,日期时间.任何想法或私人api帮助我?示例:将时区设置为GMT8,将日期时间设置为2013年8月10日晚上8:30.怎么做?

  2. ios – 如何为NSNotification编写单元测试

    我在swift工作,我想刷新一个页面,所以我使用通知发送它,我在一个ViewController中发布通知并在另一个中添加观察者,它工作正常.我想要做的是在swift中添加单元测试.我查了很多网站但是没能做到.我是新手,不知道从哪里开始.基本上工作是,当我点击按钮通知被发布时,并且当加载下一个视图控制器时,添加通知观察者.我该怎么做单元测试提前致谢编辑:码并添加观察者解决方法一般的解决方案是:使用

  3. 如何在iOS中为预期的assert / assertionFailure编写单元测试?

    这里的问题是,当someString参数为空字符串时,您可以保证函数不会失败–在您的实际应用程序中.这是因为断言不在发布版本中运行.结果是你可以在开发过程中使用assert作为调试的一种形式,但如果这种情况在现实生活中发生,你应该按顺序处理它,而不是崩溃.因此测试断言“发生”是否真的不是一种有效的单元测试技术,这就是为什么你以这种方式使用它的麻烦.

  4. xcode – 如何在不影响单元测试目标构建的情况下更改发布目标的名称?

    我有一个发布目标和一个测试目标,我想更改发布目标的名称,但如果我这样做,我开始在测试目标中获得链接错误.由于它们是单元测试,我认为在测试目标中不会/应该是对发布目标的依赖,但显然存在.链接错误是:在重命名之前,XYZ.app是发布目标的名称.是否有自动或快速更新单元测试目标的方法,以便它保持步调状态?

  5. ios – 可以测试IBAction吗?

    对IBOutlets进行单元测试有点容易,但IBActions呢?我试图找到一种方法,但没有任何运气.有没有办法在ViewController中的IBAction和nib文件中的按钮之间进行单元测试连接?解决方法对于完整的单元测试,每个插座/操作需要三个测试:>插座是否连接到视野?

  6. ios app如何“知道”运行单元测试

    我知道我可以用xcodebuild开始我的应用程序的单元测试,但我想知道是什么告诉应用程序在启动期间运行测试,它是一个发送到应用程序的特殊参数,还是以不同的方式编译以运行测试?

  7. ios – Xcode 6.1直到运行时才检测到单元测试

    我遇到了Xcode6.1.1没有检测到单元测试文件的问题.我运行了与之关联的方案,并在运行时找到了该文件,最后在单元测试导航器中找到了一个“rT”图标.这导致我到thisquestion,但没有一个答案对我有用.删除我的派生数据或重新启动Xcode没有任何帮助.接近工作的唯一事情是在Xcode运行时删除我的派生数据文件夹–当它重新编制索引时,它发现了我的三个方案中的一个中的所有测试文件.所有这些测

  8. xcode – 在仪器中运行SenTestingKit单元测试

    我正在开发一个数据库访问库,我试图使用已经写的单元测试检查内存泄漏.这些是基于SenTestingKit的逻辑测试,在Xcode4.2中设置了正常的方式.我可以使用Cmd-U运行它们,但是没有看到从仪器启动它们的方法,或者调用仪器来检查它们.我该怎么做这个工作?我需要编写新的案例并将其构建到应用程序中吗?

  9. Xcode:用于条件DEBUG / TEST代码的预处理器宏

    我在我的代码(例如AppDelegate.m)中有不应该为单元测试编译的部分,例如当您在创建新项目时选择“添加单元测试”时,目标是由Xcode设置的.在项目文件中,我已将标志CONfigURATION_TESTS添加到内置目标的MyAppTests的预处理器宏中,但未添加到MyApp目标.这是我发现的许多帖子中的建议方式.但是这不起作用,因为(我猜)MyAppTests目标将MyApp目标作为依赖

  10. xcode – 如何将Compile Sources中的文件从一个目标复制并粘贴到另一个目标?

    我有一个主要目标,其目标下包含某些文件–>构建阶段–>编译源我开始单元测试,并希望单元测试包含与主要目标相同的文件.有没有办法将包含在一个目标中的文件复制粘贴到另一个目标?

随机推荐

  1. static – 在页面之间共享数据的最佳实践

    我想知道在UWP的页面之间发送像’selectedItem’等变量的最佳做法是什么?创建一个每个页面都知道的静态全局变量类是一个好主意吗?

  2. .net – 为Windows窗体控件提供百分比宽度/高度

    WindowsForm开发的新手,但在Web开发方面经验丰富.有没有办法为Windows窗体控件指定百分比宽度/高度,以便在用户调整窗口大小时扩展/缩小?当窗口调整大小时,可以编写代码来改变控件的宽度/高度,但我希望有更好的方法,比如在HTML/CSS中.在那儿?

  3. 使用Windows Azure查询表存储数据

    我需要使用特定帐户吗?>将应用程序部署到Azure服务后,如何查询数据?GoogleAppEngine有一个数据查看器/查询工具,Azure有类似的东西吗?>您可以看到的sqlExpressintance仅在开发结构中,并且一旦您表示没有等效,所以请小心使用它.>您可以尝试使用Linqpad查询表格.看看JamieThomson的thispost.

  4. windows – SetupDiGetClassDevs是否与文档中的设备实例ID一起使用?

    有没有更好的方法可以使用DBT_DEVICEARRIVAL事件中的数据获取设备的更多信息?您似乎必须指定DIGCF_ALLCLASSES标志以查找与给定设备实例ID匹配的所有类,或者指定ClassGuid并使用DIGCF_DEFAULT标志.这对我有用:带输出:

  5. Windows Live ID是OpenID提供商吗?

    不,WindowsLiveID不是OpenID提供商.他们使用专有协议.自从他们的“测试版”期结束以来,他们从未宣布计划继续它.

  6. 如果我在代码中进行了更改,是否需要重新安装Windows服务?

    我写了一个Windows服务并安装它.现在我对代码进行了一些更改并重新构建了解决方案.我还应该重新安装服务吗?不,只需停止它,替换文件,然后重新启动它.

  7. 带有双引号的字符串回显使用Windows批处理输出文件

    我正在尝试使用Windows批处理文件重写配置文件.我循环遍历文件的行并查找我想要用指定的新行替换的行.我有一个’函数’将行写入文件问题是%Text%是一个嵌入双引号的字符串.然后失败了.可能还有其他角色也会导致失败.如何才能使用配置文件中的所有文本?尝试将所有“在文本中替换为^”.^是转义字符,因此“将被视为常规字符你可以尝试以下方法:其他可能导致错误的字符是:

  8. .net – 将控制台应用程序转换为服务?

    我正在寻找不同的优势/劣势,将我们长期使用的控制台应用程序转换为Windows服务.我们为ActiveMQ使用了一个叫做java服务包装器的东西,我相信人们告诉我你可以用它包装任何东西.这并不是说你应该用它包装任何东西;我们遇到了这个问题.控制台应用程序是一个.NET控制台应用程序,默认情况下会将大量信息记录到控制台,尽管这是可配置的.任何推荐?我们应该在VisualStudio中将其重建为服务吗?我使用“-install”/“-uninstall”开关执行此操作.例如,seehere.

  9. windows – 捕获外部程序的STDOUT和STDERR *同时*它正在执行(Ruby)

    哦,我在Windows上:-(实际上,它比我想象的要简单,这看起来很完美:…是的,它适用于Windows!

  10. windows – 当我试图批量打印变量时,为什么我得到“Echo is on”

    我想要执行一个简单的批处理文件脚本:当我在XP中运行时,它给了我预期的输出,但是当我在Vista或Windows7中运行它时,我在尝试打印值时得到“EchoisOn”.以下是程序的输出:摆脱集合表达式中的空格.等号(=)的两侧可以并且应该没有空格BTW:我通常在@echo关闭的情况下启动所有批处理文件,并以@echo结束它们,所以我可以避免将代码与批处理文件的输出混合.它只是使您的批处理文件输出更好,更清洁.

返回
顶部