Cool Blue Cool Blue - 1 year ago 153
C# Question

How to temporarily stop optimisation of WPF framework elements?

I am stepping through the WPF source code to debug some issue with my own code. I have the source and the pdb's (I'm using dotpeek as a symbol server so I have the full pdbs with source code) and I can step into the WPF code no problem. The modules I am interested in are PresentationFramework and System.Xaml. The debugging experience is horrible because the framework modules are optimised (normally a good thing!).

My (very vauge) understanding is that they are pre-JITed with ngen.exe by VS or whatever, on installation... and this is causing the obfuscation.

Uninstalling .NET Framework elements from Native Image Cache to improve debugging

As I understand it, I can use ngen.exe (from the Developer Command Prompt launched from the Visual Studio folder) to uninstall the native image files. For example...

ngen uninstall PresentationFramework
Uninstalling assembly PresentationFramework, Version=, Culture=Neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=msil
Uninstalling assembly PresentationFramework, Version=, Culture=neutral, PublicKeyToken=31bf3856ad364e35
Uninstalling assembly PresentationFramework, Version=, Culture=Neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=msil

I'm lead to believe that this will force the C# compiler to revert to the MSIL versions and JIT compile them at run time. I'm also assuming that I can then disable the runtime JIT optimization and that's how I can get a decent debugging experience.

However, uninstalling the target native images proves troublesome. Ngen does it but, it has no effect as far as the debugging experience is concerned.

When I try to uninstall the same modules again, I am informed that they are not installed - which is encouraging - but I also get a list of files that depend on them, a lot of dll and exe files and also some native image files (about ten of these) and the following message...

You may need to uninstall these assembly roots in order to delete the native image for PresentationFramework
Error: The specified assembly is not installed.

So, I assume that I will need to find the roots for these ten files and start uninstalling everything from there. This could get out of control fairly quickly if there are a loot of dependencies.

Disabling JIT optimisation of particular MSIL modules

Assuming I can get un-optimised modules, in order to supress JIT optimisation, I added ini files to the same folder as the modules that I want to step through, for example, in
I have


[.NET Framework Debugging Control]

In Tools/Options/Debugging/General/ I have Enable source Server support disabled and Suppress JIT optimization on module load enabled.

In the Project Options, I have Optimize code disabled in the Build section, I also have Debugging information set to full in Build/Advanced.

Am I on the right track?
Is there a config option somewhere in VS where I can just tell it to use the dll files and ignore the aggressively optimised native images?

Answer Source

Thanks to help from @HansPassant I finally figured it out.

The native image files are stored in C:\Windows\assembly\ but there is a windows extension called shfusion.exe which prevents normal access to this folder. This is fixed by running the following command from an elevated cmd window...

regsvr32 /u C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\shfusion.dll

Then you can see the the contents described by Hans... enter image description here

Next, I confirmed exactly which versions of the native images was being used by Visual Studio by using Process Hacker/Properties context menu to check out the .NET assemblies used by the devenv process. It has a "Path" and a "Native image path" column so I could see exactly which NIs were being used by VS. enter image description here Then I renamed the folders of the modules that I don't want optimised...

enter image description here

Make sure I have the right settings in VS Options/Debugging, including Suppress JIT optimisation... ![enter image description here

Note that it's not necessary to check the Suppress JIT optimisation box if you add the ini files as described in my question in Disabling JIT optimisation of particular MSIL modules.

And the debug problems with objects being optimised away and lines skipped were fixed.
As explained in this answer, I can put expressions like this in the breakpoint Action and it will work every time...

{((EventSetterNull_SO_41604891_2670182.MainWindow)System.Windows.Application.Current.MainWindow).Logger.LogMemberTry(data, new [] \{"Name", "_value"\}, "XamlNodeList.Add ")}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download