VS2015 update 1: 新功能 – MPX

[原文发表地址] Visual Studio 2015 Update 1: New Experimental Feature - MPX

[原文发表时间] 2016/1/20 10:00AM

导论:

这篇文章是关于在VS2015中支持Intel®内存保护扩展(Intel® MPX),文章的内容是由Intel公司的Gautham Beeraka, George Kuan,和Juan Rodriguez提供的。

概述:

VS2015 update 1 于2015年11月30日发布, 在这个更新版本中包含了对Intel MPX编译和调试功能的支持。Intel MAX能够检查所有指针的读取和写入,以确保它们在已声明的内存范围内。这个技术可以检测缓存区的溢出,并且停止正在运行的程序以避免危及系统。它允许C/C++代码使用第六代 Intel 酷睿处理器(启用MPX的 平台) 中介绍的最新的MPX 指令集和寄存器。

微软Visual C++编译器和链接器现在有通过特定的命令行选项启动自动检测的能力。

这篇博客解释了你该如何使用MPX代码自动生成以及启用MPX调试二进制文件。如果你想了解更多的有关Intel MPX的信息,请查看Intel MPX Technology web page.

如何来启用MPX代码的自动生成功能

VS2015 Update 1 有一个新的编译选项: /d2MPX.

/d2MPX当前支持:

  • 检查写入内存时的潜在缓存溢出, 它可以保护本地的和公用的指针和数组。
  • 扩展到函数调用来自动提示指针参数的边界。

在你的工程中启用MPX的代码自动生成功能:

在VS中,如图1所示在添加其他选项框(项目|属性|配置属性|C/C++|命令行|其他选项)中添加/d2MPX编译选项。


图1:添加 /d2MPX编译选项必须做的配置。

使用示例:

下面这个示例是一个包含缓存溢出的程序。


图2: 代码中的缓存溢出会被/d2MPX检测到。

在图2中,当循环里面的语句试图向数组的尾部写入时,out数组会内存溢出, 因为out长度小于字符串str。只有程序出现越界存储,MPX硬件才会生成一个#BR(绑定范围边界)异常, 它表现为一个 “超出数组边界” 的结构化异常操作(SEH)异常。立即终止程序的默认行为不再发生在数组越界的异常处理。取而代之的,一是你可以添加一个如上图所示的示例代码中的异常处理来记录代码的异常,或者执行一些上下文依赖恢复比如分拆进程始终避免越界存储。

构建并运行示例的步骤:

1. 在驱动管理窗口的系统驱动中(图3)检查Intel@MPX运行驱动是否安装在2016年11月更新的或更高版本的Windows 10操作系统上。如果没有该驱动,请从Intel® Memory Protection Extensions Enabling Guide下载并安装。

2. 安装VS2015 Update 1, 请注意如果你的VS是通过手机模拟器安装的,Hyper-V将不得不被禁用(运行bcdedit /set hypervisorlaunchtype off 并且重启电脑), 因为这个版本的窗口还不能将MPX指令暴露给用户。

3. 创建一个Win32控制台应用程序命名为” MPXExample”,并且使用图2所示的驱动代码。

4. 如上所示,请再次检查/d2MPX选项是否在当前配置中启用。

5. 在VS的X64平台上构建该工程会生成MPXExample.exe二进制文件。

6. 在启用了MPX支持的Windows 10 上执行二进制文件MPXExample.exe。

7. 想要VS调试器在超出数组越界时中断,请在图4所示的异常设置窗口(调试|窗口|异常设置)启用”超出数组界限”的选项,然后在调试模式下执行MPXExample.exe,这时应该会在这个异常上(图5)中断。在这个示例中,当MPX发现写入超出了数组的上限(图 6)时会抛出#BR异常。

图3:通过驱动管理窗口来检查是否安装Intel MPX Runtime驱动程序。


图4:通过在异常设置窗口中启用超出数组边界中断选项,可以使VS调试器在这个异常上中断。

图5: VS调试器在超出数组越界异常发生时中断。

图6:这是在反汇编窗口中,当检查上界限时抛出异常的截图。

VS2015 Update 1支持当在启用MPX的平台上运行时,通过MPX 寄存器窗口(图7)和监视窗口(图8) 显示和控制MPX 寄存器。

图7:观察MPX中注册器边界的上下文,并且调试模式下的注册器窗口启用MPX。

图8:添加一个边界测量在调试监视窗口也十分简单,监视窗口的BND0.UB和BND0.LB在BND0寄存器中分别表示上下边界。

注意边界寄存器中的上限边界是用二进制补码的形式显示的。

如何判断一个二进制文件是否启用了MPX

运行dumpbin /headers MPXExample.exe后MPX调试目录应该如图9所示。

图9:用来说明如果一个二进制文件启用了MPX,那么需要通过dumpbin来检查二进制是否包含MPX调试目录, 而且MPX调试目录应该显示在调试目录部分的列表中。

我们必须用MPX编译所有的代码吗?

你不需要启用MPX编译所有的代码,MPX和非MAX代码可以混合在一起正确的执行。不过,没有启用MPX的代码不支持任何MPX的检查。

我们需要什么样的硬件和windows版本?

为了获得MPX 的优点,启用MPX的代码应该运行在支持MPX平台的windows版本上。 现在MPX支持下面的环境:

如果我们在一个不支持MPX的平台或Windows版本上启用MPX功能来执行代码会是什么结果?

启用了MPX的代码将会正确的执行,但是它不会受益于MPX,所以你需要在MPX-aware操作系统上启用MPX平台来运行我们的代码。反之,MPX指令会被当作空操作来对待,所以你可能在这些场景中发现性能有所下降。

对性能的影响

MPX技术针对缓存溢出问题提供了有利的保障。在每次写入内存时插入检查操作可能会多花费一些执行时间和内存消耗,但在我们的测试过程中所消耗的资源量是可接受的。然而,当在产品中启用它,开发人员必须衡量内存安全的提高是否胜于他们的客户对性能的需求,今后我们会根据大家的反馈来努力提高它的性能。

已知的问题

这里现在有一个已知的问题是当调试X86的程序时调试工具会干扰MPX操作。

更多的反馈信息

更多的有关于如何在Intel MPX工作的信息、MPX内部函数的详情、调用扩展协定以及MPX运行时的行为,请查看Intel® Memory Protection Extensions Enabling Guide.

请尝试VS 2015 Update 1 中的MPX代码自动生成功能,我们非常期待可以听到您的使用经验的分享,特别是可用性、代码大小对运行时性能的影响,以及您关于改善这个功能的建议,请在下面的评论框中或Intel ISA Extensions Forum on Intel® Developer Zone留下您的反馈信息。

Intel技术带来的功能和好处依赖于系统配置,可能需要启用硬件、软件和激活服务。您可以通过联系您的系统生产商或零售商或者从Intel MPX Technology web page学习更多的相关知识。

Intel第六代酷睿处理器是Intel公司在美国和其他国家的商标,其他名字和品牌可能是其他公司的。