了解 MSVC++ 中的"Buffer Security Check /GS"编译器选项

Understanding "Buffer Security Check /GS" compiler option in MSVC++

本文关键字:GS 编译器 选项 Check Security MSVC++ 中的 Buffer 了解      更新时间:2023-10-16

我最近惊讶地注意到,在msvc++ 2010中使用/GS(启用缓冲区安全检查)编译在某些情况下似乎对运行时性能有不可忽视的影响。还有其他人有过这样的经历吗?

对于一个大型科学风格的应用程序(一个网格生成库),用/GS-编译似乎可以在我的测试套件("large")中几个大型基准测试的运行时提高近10%。= 1秒的运行时间)。在msvc++ 2010中,/GS在所有级别的优化中默认为开启。

我必须承认,我以前从来没有太关注过这个选项,我想要一点澄清,它实际上是做什么的。在线文档似乎广泛讨论字符串缓冲区,但由于我不使用stringchar[]缓冲区的任何地方,我必须错过的东西。

这段(来自在线文档)似乎表明我所看到的性能下降有点不寻常:

使用的性能权衡必须在应用程序中进行安全检查被制成Visual c++编译器团队专注于表演退化小。在大多数情况下,性能不应该再下降了而不是2%。事实上,经验证明了大多数应用,包括高性能服务器申请,没有注意到任何性能影响。

当然,我可以直接关闭它,以获得更快的代码,但在我这样做之前,我想了解其含义

我有和你一样的经验:/GS-导致运行时改善了约10%。我在我的博客上分享了一些基准测试:Visual c++中缓冲区安全检查的成本

当/GS被启用时(这是vc++发布配置的默认值),似乎任何时候你创建一个c风格的数组作为局部变量,编译器会插入一些额外的指令,以确保堆栈上数组后面的4个字节没有被修改。正如您所注意到的,它是字符数组还是其他类型的数组似乎并不重要。我猜这个编译器选项背后的想法是,任何堆栈缓冲区溢出都可能被黑客利用,无论类型如何。

但是如果你正在开发一个Visual c++应用程序,它不是一个网络服务,并且你正在努力获得最大的性能,比如在游戏,编辑器或基准测试工具中-并且它不太可能成为黑客的目标-那么我建议继续禁用此选项。

/GS添加了一些代码,这些代码试图检测函数期间是否发生了写溢出或类似的堆栈攻击,并在写溢出后停止执行。它旨在寻找的模式是在现实世界的攻击中看到的模式。如果当时使用的是今天的/GS,那么现实世界中的许多安全公告就不会发生。

在这种情况下,写溢出可能发生在结构、数组和各种其他实体上。每个版本的VS都对/GS进行了更改和改进,更多的/GS保护通常是有成本的,尽管在某些情况下,新版本的VS可能已经学会了如何更便宜地做同样的保护。

我建议保持/GS打开,除非你的代码不发送给其他人——通常保护是值得的;您最多可以选择在没有风险和高影响的特定功能中禁用它-就像您可以通过其他方式手动优化程序的最关键部分一样。

Martyn

TrendMicro将标记您的应用程序为可疑的/GS-编译性能

TrendMicro-HouseCall Suspicious_GEN.F47V0828 .

他们似乎也忽略了所有重新评估的请求,认为是假阳性。