Debugging framework internals without source code - mitikov/KeepSitecoreSimple GitHub Wiki

Problem

Getting unexpected results produced by frameworks (f.e. parsing data and getting null) is a common thing nowadays.

From a developer perspective it looks like:

I'm doing everything right.

From framework development team it looks like:

No, you do not do it right. Your data hits this sanity check in 67th line and returns Null as incorrect input.

im-right-youre-wrong

If only a developer that ran into a problem could debug framework code execution step-by-step as if it was his own =\

What stops us from debugging ?

A lack of PDB files that hold debugging information is a main showstopper ( Why PDB and Know PDB to have more information), and runtime optimizations.

PDBs are typically generated on compile time, however they can be re-created/re-generated from assembly itself.

Runtime optimization can be disabled by asking .NET to load assembly with debug data.

Step Uno. Re-create PDBs

You can either use free dotPeek or not free Reflector. Lets take a closer look on a free tool first.

Using dotPeek

  1. Need to load exact assembly as referenced in project via File -> Open:

dotpeek_right_reference

Picking a different version than referenced in VS project will not allow re-generated PDB to be loaded during debugging.


  1. Select Generate PDB on loaded assembly. Use a cache folder (f.e. c:\symbols) rather than solution bin to reuse PDB across multiple solutions:

regenerate


  1. Setup dotPeek to act as Symbol Server to generate PDBs on fly per debugger request ( killer feature ):

dotpeek_symbolserver


  1. Let Visual Studio know about PDB cache folder, and Symbol Server:

visual_studio_sympath


  1. Disable runtime optimizations by putting a *.ini file with same name as assembly ( in our case Sitecore.Kernel.ini ) with following content:

[.NET Framework Debugging Control]

GenerateTrackingInfo=1

AllowOptimize=0

It will allow to disable a part of code translation optimizations thereby enable watching values of local variables.


  1. Attach to running process, and load assembly symbols via Debug -> Windows -> Modules -> Right click on correct assembly -> load symbols. You can ask VS to load symbols automatically each time:

load_symbols

If assembly is shown as optimized, create ini file in the folder where assembly was loaded from, and restart application.

NOTES I have disabled shadowCopyBinAssemblies in a local solution to speedup application start a bit.

Your assembly would be loaded from a %windows%\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\ folder, thus ini file ought be added there.

Results with dotPeek

Having PDBs loaded, and optimization disabled allows debugger to inspect framework internal code flow, thereby understanding the output produced:

summary

Using Reflector

The only difference is that Reflector has VS plugin that allows to generate PDB from VS interface:

reflector

And will automatically put PDBs into %app_data%\Local\Red Gate\.NET Reflector 9\Cache\ folder.

Thereby you need to put this folder as PDB source for VS.