Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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=3.0.0.0, Culture=Neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=msil
Uninstalling assembly PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
Uninstalling assembly PresentationFramework, Version=4.0.0.0, 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 C:\Windows\Microsoft.NET\assembly\GAC_MSIL\PresentationFramework\v4.0_4.0.0.0__31bf3856ad364e35 I have

PresentationFramework.ini

[.NET Framework Debugging Control]
GenerateTrackingInfo=1
AllowOptimize=0

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?

like image 613
Cool Blue Avatar asked Jan 26 '17 04:01

Cool Blue


People also ask

Where is optimize code in Visual Studio?

The Optimize option is enabled by default for a Release build configuration. It is off by default for a Debug build configuration. You set the Optimize option from Build properties page for your project in Visual Studio. Optimize also tells the common language runtime to optimize code at run time.


2 Answers

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 ")}
like image 95
Cool Blue Avatar answered Oct 05 '22 23:10

Cool Blue


If you want to "debug" the framework turning off JIT is not what you need.

According to this blog,

All PDBs that are present in the Microsoft Symbol Server do not have any source information in them, which makes them not very useful for stepping through sources.

Starting with .NET 4.5.1, the symbol indexing and publishing process are changed to be in sync with the build process when updates are shipped, the corresponding PDBs are also updated to the reference source site appropriately.

So you should disable Microsoft Symbol server and change to change to use the new reference source site: http://referencesource.microsoft.com/

Please follow the steps:

1). Disable Microsoft Symbol Server lookup via Tools | Options | Debugging | Symbols. Ensure that the checkbox in front of Microsoft Symbol Server is unchecked.

2). Change Symbol file location to be http://referencesource.microsoft.com/

3). Configure .NET Reference Source for debugging: http://referencesource.microsoft.com/setup.html

For more detailed information, please take a look at the blog I provided above: http://blogs.msdn.com/b/dotnet/archive/2014/02/24/a-new-look-for-net-reference-source.aspx

Thanks.

Source: https://social.msdn.microsoft.com/Forums/vstudio/en-US/7bc17ae3-6480-439c-bec4-66be22dcfe02/obtaining-debug-symbol-pdb-files-for-net-framework-452?forum=clr

like image 35
Aron Avatar answered Oct 05 '22 23:10

Aron