了解MSVC ++中的“缓冲区安全检查/ GS”编译器选项

问题描述 投票:10回答:3

我最近惊讶地发现在MSVC ++ 2010中使用/GS(启用缓冲区安全检查)进行编译似乎在某些情况下对运行时性能产生了不可忽视的影响。有没有其他人有这种经验??

对于大型科学应用程序(网格生成库)来说,使用/GS-进行编译似乎可以使我的测试套件中的几个大基准测试的运行时间提高近10%(“大”值> = 1秒)运行时)。默认情况下,/GS在MSVC ++ 2010中的所有优化级别上都处于启用状态。

我必须承认,我之前从未过多地关注过这个选项,而且我想要澄清它实际上做了什么。在线documentation似乎广泛谈论字符串缓冲区,但由于我不使用stringchar[]缓冲区,我必须丢失一些东西。

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

必须在应用程序中使用安全检查进行性能权衡。 Visual C ++编译器团队专注于降低性能下降。在大多数情况下,性能不应降低2%以上。实际上,经验表明,大多数应用程序(包括高性能服务器应用程序)都没有注意到任何性能影响。

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

c++ visual-studio
3个回答
12
投票

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

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

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

马丁


12
投票

我有与你相同的经验:/ GS-在运行时间方面提高了约10%。我在我的博客上分享了一些基准:The Cost of Buffer Security Checks in Visual C++

当启用/ GS(这是VC ++ Release配置的默认设置)时,似乎任何时候你创建一个C风格的数组作为局部变量,编译器将插入一些额外的指令,以确保数组后面的4个字节堆栈尚未修改。正如您所注意到的,如果它是char数组或其他类型的数组似乎并不重要。我想这个编译器选项背后的想法是黑客可以利用任何堆栈缓冲区溢出,无论类型如何。

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


0
投票

TrendMicro会将您的应用程序标记为可疑,以便使用/ GS-进行编译以获得性能。

TrendMicro-HouseCall Suspicious_GEN.F47V0828。

似乎他们也忽略了所有重新评估为误报的请求。

© www.soinside.com 2019 - 2024. All rights reserved.