简体   繁体   English

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

[英]Understanding “Buffer Security Check /GS” compiler option in MSVC++

I was recently surprised to note that compiling with /GS (Enable buffer security check) in MSVC++ 2010 seems to have a non-negligible effect on run-time performance in some cases.我最近惊讶地发现,在某些情况下,在 MSVC++ 2010 中使用/GS (启用缓冲区安全检查)进行编译似乎对运行时性能产生了不可忽视的影响。 Has anyone else had this experience??有没有其他人有这种经验??

For a large scientific-style application (a mesh generation library) it seems that compiling with /GS- can lead to almost 10% improvements in run-time for several of the large benchmarks in my test suite ("large" being >= 1 second worth of run-time).对于大型科学风格的应用程序(网格生成库),似乎使用/GS-编译可以使我的测试套件中的几个大型基准测试的运行时间提高近 10%(“大型”>= 1第二个运行时间)。 /GS is on by default at all levels of optimisation in MSVC++ 2010. /GS在 MSVC++ 2010 的所有优化级别中默认启用。

I must admit that I'd never paid too much attention to this option before, and I'm wanting a bit of clarification as to what it actually does.我必须承认,我以前从未对这个选项给予过多关注,并且我想澄清一下它的实际作用。 The online documentation seems to talk extensively about string buffers, but since I don't use string or char[] buffers anywhere I must be missing something.在线文档似乎广泛讨论了字符串缓冲区,但由于我不在任何地方使用stringchar[]缓冲区,所以我一定会遗漏一些东西。

This paragraph (from the online doc) seems to indicate that the performance degradation I'm seeing is a bit unusual:这一段(来自在线文档)似乎表明我看到的性能下降有点不寻常:

A performance tradeoff for using security checks in an application must be made.必须权衡在应用程序中使用安全检查的性能。 The Visual C++ compiler team focused on making the performance degradation small. Visual C++ 编译器团队专注于减少性能下降。 In most cases, the performance should not degrade more than 2 percent.在大多数情况下,性能下降不应超过 2%。 In fact, experience has shown that most applications, including high-performance server applications, have not noticed any performance impact.事实上,经验表明,大多数应用程序,包括高性能服务器应用程序,都没有注意到任何性能影响。

Of course I can just turn it off, and get faster code, but I want to understand the implications before I do that.当然,我可以将其关闭,并获得更快的代码,但在我这样做之前我想了解其中的含义。

/GS adds code that tries to detect if a write overrun or similar stack attack has happend during a function, and to stop execution after a write overrun. /GS 添加了尝试检测在 function 期间是否发生写溢出或类似堆栈攻击的代码,并在写溢出后停止执行。 The patterns that it aims to find are ones that have been seen in real-world attacks.它旨在寻找的模式是在现实世界的攻击中看到的模式。 There are a bunch of real world security bulletins that would not have happened if today's /GS had been in use at the time.如果当时使用了今天的 /GS,那么很多现实世界的安全公告就不会发生。

In this case a write overrun can happen on structures, arrays and various other entities.在这种情况下,结构、arrays 和各种其他实体上可能会发生写溢出。 Changes and improvements to /GS are made in each version of VS.在 VS 的每个版本中都对 /GS 进行了更改和改进。 More /GS protection generally has cost, although in some cases newer VS may have learnt how to do the same protection cheaper.更多的 /GS 保护通常是有成本的,尽管在某些情况下,较新的 VS 可能已经学会了如何更便宜地进行相同的保护。

I'd recommend leaving /GS on unless your code doesn't ship to others - generally the protection is worth the cost;我建议保留 /GS ,除非您的代码没有发送给其他人 - 通常保护是值得的; at most you might choose to disable it for specific functions where there is no risk and high impact - just as you might hand-optimise the most critical parts of your program in other ways.最多您可以选择在没有风险和高影响的特定功能上禁用它——就像您可能以其他方式手动优化程序中最关键的部分一样。

Martyn马丁

I've had the same experience as you: /GS- leading to ~10% improvements in runtime.我和你有同样的经历:/GS- 导致运行时约 10% 的改进。 I've shared some benchmarks on my blog: The Cost of Buffer Security Checks in Visual C++我在我的博客上分享了一些基准: Visual C++ 中的缓冲区安全检查成本

When /GS is enabled (which is the default for the VC++ Release configuration), it seems anytime you create a C-style array as a local variable, the compiler will insert a few extra instructions to ensure the 4 bytes following the array on the stack have not been modified.当启用 /GS 时(这是 VC++ Release 配置的默认设置),似乎每当您创建 C 样式数组作为局部变量时,编译器都会插入一些额外的指令以确保数组后面的 4 个字节堆栈没有被修改。 As you've noticed, it doesn't seem to matter if it's a char array, or an array of another type.正如您所注意到的,它是 char 数组还是其他类型的数组似乎并不重要。 I guess the idea behind this compiler option is that any stack buffer overflow could be exploited by hackers, regardless of type.我猜这个编译器选项背后的想法是任何堆栈缓冲区溢出都可能被黑客利用,无论类型如何。

But if you're developing a Visual C++ application which is not a network service, and you're striving for maximum performance, such as in a game, editor, or benchmarking tool — and it's unlikely to be targeted by hackers — then I'd suggest to go ahead and disable this option.但是,如果您正在开发不是网络服务的 Visual C++ 应用程序,并且您正在努力获得最佳性能,例如在游戏、编辑器或基准测试工具中——而且它不太可能成为黑客的目标——那么我d 建议提前 go 并禁用此选项。

TrendMicro will flag your application as suspicious for compiling with /GS- for performance. TrendMicro 会将您的应用程序标记为使用 /GS- 进行编译以提高性能。

TrendMicro-HouseCall Suspicious_GEN.F47V0828. TrendMicro-HouseCall Suspicious_GEN.F47V0828。

It seems they also ignore all requests to re-evaluate as false positive.他们似乎也忽略了所有重新评估为误报的请求。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM