2

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:

Dropdown

Upon click

Jez
  • 27,951
  • 32
  • 136
  • 233
  • coud you please share some screenshots about the "Quickview had an option for "Disable managed optimizations and restart debugging"" you mentioned? – Bowman Zhu-MSFT Apr 20 '23 at 07:26
  • Trouble is that now that I have disabled them, that option no longer appears. :-) – Jez Apr 20 '23 at 11:25
  • OK, I managed to get it to appear again in another debugging session and I've added screenshots. – Jez Apr 20 '23 at 11:42
  • _"I've disabled some optimizations which may slow things down"_ - yes, but that isn't a problem: debug builds are not meant to be fast. – Dai Apr 20 '23 at 11:47
  • @Dai So why does it ever optimize it in the first place? – Jez Apr 20 '23 at 15:37
  • @Jez Because 90% of the the time you _do_ want JIT optimizations of third-party library and framework code, e.g. `System.Windows.Forms` controls. – Dai Apr 20 '23 at 15:44
  • Yeah, so how do I turn them back on if they've been turned off by the method in my above question? – Jez Apr 20 '23 at 15:49
  • @Jez See the "Suppress JIT optimization on module load" documentation here: https://learn.microsoft.com/en-us/visualstudio/debugger/jit-optimization-and-debugging?view=vs-2022 – Dai Apr 20 '23 at 16:29

2 Answers2

4

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 */ }).
  • 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 with isJITOptimizerDisabled: false - this attribute is added to assemblies when using csc.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 run ngen.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.

Recommended Reading


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 Tools > Options > Debugging:

enter image description here

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.

enter image description here

enter image description here


Dai
  • 141,631
  • 28
  • 261
  • 374
-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.

Albert D. Kallal
  • 42,205
  • 3
  • 34
  • 51
  • The OP is asking about the JIT Optimizer setting in the Debugger settings, not optimization in general. – Dai Apr 20 '23 at 15:44
  • yes, and in this context, that is EXACTLY what I was talking about. That optimized code is in fact code having been compiled by the JIT and ALSO having been optimized. As I stated, if you disable that option, then one can step and use break points. So, yes, my WHOLE response is in regards to the compiler (or in this case the JIT). So, now that you grasp what my context was and is? You can read my post again with that given context, and thus I sure you 100% agree with what I stated. – Albert D. Kallal Apr 20 '23 at 16:26
  • _"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."_ - this is true, but at the same time fails to mention how this works w.r.t. Just-My-Code mode and things like the Modules window and `COMPlus_ZapDisable`. – Dai Apr 20 '23 at 16:29