英文:
What settings does "Disable managed optimizations and restart debugging" actually change in Visual Studio?
问题
During a Visual Studio 2022 debugging session, I was debugging some ASP.NET internal code using source link and the Microsoft symbol servers, and I was unable to view a variable because it had been optimized away; however, Quickview had an option for "Disable managed optimizations and restart debugging". I chose that, debugging restarted, and I was indeed able to view the variable. However, I'm now worried that I've disabled some optimizations which may slow things down and it's not clear to me what selecting that option actually changed. What settings does that change in Visual Studio, and how can I re-enable the managed optimizations?
英文:
During a Visual Studio 2022 debugging session I was debugging some ASP.NET internal code using source link and the Microsoft symbol servers, and I was unable to view a variable because it had been optimized away; however, Quickview had an option for "Disable managed optimizations and restart debugging". I chose that, debugging restarted, and I was indeed able to view the variable. However I'm now worried that I've disabled some optimizations which may slow things down and it's not clear to me what selecting that option actually changed. What settings does that change in Visual Studio and how can I re-enable the managed optimizations?
Here are some screenshots of what the option looks like in the UI dropdown, and when you click it:
答案1
得分: 4
以下是您要翻译的内容:
背景信息:.NET 中的不同类型优化
在许多编译语言中,比如 C 和 C++,通常只有一个地方应用优化:当你运行编译器时(尽管老的工具链,有独立的编译器和链接器,也常常有编译时和链接时的优化)。
... 但在 .NET 世界中,情况稍微复杂一些:
-
csc
C# 到 IL(或 VB.NET 到 IL,F# 等)编译器可以优化从你的 C# 生成的 IL(使用/optimize
标志)。- 这些通常是更简单的优化,比如移除无用代码(例如,
if( false ) { /* here */ }
这样块的内容)。
- 这些通常是更简单的优化,比如移除无用代码(例如,
-
当由 CLR 加载已构建的 .NET 程序集(.NET
.dll
或.exe
)时,JIT 可以应用自己的优化。- 这些 JIT 时优化更高级,比如循环展开和可执行代码内联。
- 这些 JIT 时优化不会应用于带有
DebuggableAttribute( DebuggingModes.DisableOptimizations )
或isJITOptimizerDisabled: false
的程序集 - 当使用/debug
运行csc.exe
时,将添加此属性。
-
严格来说,当 .NET 程序运行时,CLR 可能会加载缓存的托管程序集的本机映像版本,这些版本特定于您的计算机。
- 对于 .NET Framework 1.x-4.x 程序集,这些本机映像由
ngen.exe
生成 - 从 Windows 8 开始,可能会在后台主动编译程序集,而无需手动运行ngen.exe
。 - 对于 .NET 5+,请参阅
CrossGen2
。 - 这与
readytorun
和/或 AOT 编译的程序集不同,它们具有自己的优化,超出了本答案的范围。
- 对于 .NET Framework 1.x-4.x 程序集,这些本机映像由
推荐阅读
- 托管调试:推荐的属性设置
- JIT 优化和调试
- https://stackoverflow.com/questions/35486740/what-is-complus-zapdisable-and-why-is-it-not-set-by-default
- Ngen.exe (本机映像生成器)
[assembly: Debuggable]
/DebuggableAttribute
英文:
Background-info: the different types of optimizations in .NET
In many compiled languages, like C and C++, often there's only really just one place where optimizations are applied: when you run your compiler (though it's also common for older toolchains, with separate compilers and linkers, to have separate compile-time and link-time optimizations).
...but in the .NET world it's slightly more complicated:
-
The
csc
C#-to-IL (or VB.NET-to-IL, F#, etc) compiler can optimize the IL that's generated from your C# (the/optimize
flag).- These tend to be simpler optimizations, such as removing dead code (e.g. the contents of a block like
if( false ) { /* here */ }
).
- These tend to be simpler optimizations, such as removing dead code (e.g. the contents of a block like
-
When a built .NET assembly (.NET
.dll
or.exe
) is loaded by the CLR then the JIT can apply its own optimizations.- These tend to be more advanced, such as loop-unrolling and executable code-inlining.
- These JIT-time optimizations are not applied to assemblies with
DebuggableAttribute( DebuggingModes.DisableOptimizations )
or withisJITOptimizerDisabled: false
- this attribute is added to assemblies when usingcsc.exe
with/debug
.
-
While strictly-speaking not a compiler "optimization", when a .NET program runs the CLR may load cached native-image versions of managed assemblies, which are specific to your machine.
- For .NET Framework 1.x-4.x assemblies, these native images are generated by
ngen.exe
- which (since Windows 8) may preemptively compile assemblies in the background without needing to runngen.exe
manually. - For .NET 5+, see
CrossGen2
. - This is not the same thing as
readytorun
and/or AOT-compiled assemblies, which have their own optimizations and is out-of-scope for this answer.
- For .NET Framework 1.x-4.x assemblies, these native images are generated by
Recommended Reading
- Managed Debugging: Recommended Property Settings
- JIT Optimization and Debugging
- https://stackoverflow.com/questions/35486740/what-is-complus-zapdisable-and-why-is-it-not-set-by-default
- Ngen.exe (Native Image Generator)
[assembly: Debuggable]
/DebuggableAttribute
> What settings does "Disable managed optimizations and restart debugging" actually change in Visual Studio?
The message-box lets you change the "Suppress JIT optimization on module load (Managed only)" setting under <kbd>Tools</kbd> > <kbd>Options</kbd> > <kbd>Debugging</kbd>:
> However I'm now worried that I've disabled some optimizations which may slow things down
Worry not: the "Suppress JIT optimization..." setting only prevents JIT optimizations for non-project assemblies when debugging - though in many cases ngen'd images will still be used (thus still running optimized cod unless you use COMPlus_ZapDisable
).
> What settings does that change in Visual Studio and how can I re-enable the managed optimizations?
Go to Debugger settings and uncheck the "Suppress JIT optimizations..." option.
You can see what's going on if you use the Debugger Modules window to see each .NET assembly that's loaded, along with its JIT optimization status, symbols status, and if VS considers it "user code" or not.
答案2
得分: -1
未启用优化将简单地使代码编译为运行速度较慢(编译后的机器代码)。因此,您可以逐步执行并查看代码变量。然而,在调试包含大量代码的大型应用程序时,未启用优化的代码将运行相对较慢。因此,您可以选择允许代码运行更快,但然后调试过程将无法使用或查看变量的值,因为该代码的调试信息不存在。如果代码已被优化,那么在大多数情况下,这意味着它已被编译为机器代码,调试器实际上无法显示变量的值,甚至无法设置断点。
在某种意义上,如果允许优化,那么您正在运行类似于“发布模式”的代码,因此选项和您调试此类代码的能力会大大减少。
鉴于当今计算机具有如此巨大的速度和处理能力,我会建议在几乎所有情况下,您都应该禁用优化来调试您的代码。
英文:
Having optimization's NOT TURNED on will simple "not" compile the code to run faster (as compiled machine code). Thus, you can step and see your code variables. However, in debugging large applications with a lot of code, un-epitomized code will run rather slow. So, you have a option to allow your code to run faster, but then the debugging process THEN can't use or see the value of variables, since the debugging information for that code does not exist. If the code has been epitomized, then in most cases that means it been compiled to machine code, and the debugger really can't then show values of variables, or even allow break-points.
In a sense, if you allow optimizations, then you are running code much like it will run as "release mode" and thus options and your ability to debug such code is much reduced.
with computers today having such VAST amounts of speed and processing, then I would accept that in near all cases, you want to debug your code with optimizations disabled.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论