A post from Georgi Bilyukov a couple of months ago about Debugging Sitecore Using DotPeek informed me of a new feature in the latest version of JetBrains dotPeek that allows it to function as a symbol as a symbol server. If you haven’t read the post then I suggest you have a quick read.
So this sounded great – a way to debug Sitecore code, see where those calls end up and what is going on in the internals.
I’ve been using dotPeek for a while now, and before that .NET Reflector. These tools have been invaluable in getting a peek at the Sitecore code, and has become an everyday tool alongside Visual Studio and Resharper. My usual way of trying to debugging something Sitecore related is:
- trial and error
- copying the code for an existing pipeline and adding it before the default Sitecore one
- override Sitecore controls, changing the codebeside to point to my own Class (which is also a copy of the Sitecore one)
- grepWin the /sitecore folder
- use dotPeek to generate a Visual Studio project and then grepWin the files to try and find something related as a starting point
So something that is very quick to debug in your own code can become quite long winded. Using dotPeek as a Symbol Server sounded hopeful, but anyone that has used Redgate .NET Reflector Pro will know that this is nothing new, just it is now free 🙂 For those of you that do not know, the Pro version is a Visual Studio plugin that allows you to debug 3rd party libraries, decompiling and set break points without leaving the IDE. I’ve used the plugin before, over 3 years ago, but never continued past the trial period for one main reason. Alas, using dotPeek I was faced with the same issue.
Same issue in the Immediate window:
args Cannot obtain value of local or argument 'args' as it is not available at this instruction pointer, possibly because it has been optimized away.
Stepping through code
Sometimes you just want to step through code and see where something ends up. For that purpose, this worked fine. But we are not able to see the values of the local variables, which is quite annoying 😦
Another problem with debugging compiled assemblies is optimized assemblies. For optimized assemblies, some debugger functions are just not available, e.g. you would not see values of local variables, even if symbol files are correct. You can check if the assembly is optimized when Visual Studio is in the debug mode – open the Modules window (Debug | Windows | Modules) and check the Optimized column.
I know some will argue that we should not really care what goes on in those external libraries and we should treat them as black boxes, but as any Sitecore developer worth their salt knows, it’s not that black & white, we very often have to act on variables and arguments passed into Sitecore code. So it’s back to duplicating code or replacing controls to see those values.
But not just Sitecore. Any third party library. I’ve been using Glass Mapper in projects for a while now, which we add in using NuGet. Yes, the source code is available on GitHub which we could download and add into our solution (and I’m sure there is an even more clever way debugging this) but there is a reason it was added in as a NuGet package in the first place.
Last week I was debugging some code which appeared like it should work but it was acting very differently to what I was expecting, even though I had duplicated a standard Sitecore Pipeline. I knew the limitation of dotPeek Symbol Server since I tried it a few months ago, so decided to take that old friend Reflector Pro for a spin again, so I installed the trial version. And after some research it appears there is a way to debug 3rd party libraries AND see the local variables!
Disable optimizations during debugging
There are 2 steps required. Firstly you need to start VS with the Environment Variable COMPLUS_ZapDisable=1. Create a .cmd in any text editor with the following:
set COMPLUS_ZapDisable=1 cd /d C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE start devenv.exe exit
You also need to disable JIT optimizations while debugging. Create an .ini file with the following and call it
Sitecore.Client.ini etc) and place it in the /bin folder alongside the DLL.
[.NET Framework Debugging Control] GenerateTrackingInfo=1 AllowOptimize=0
Then follow the instructions to create the pdb and add Reflector or dotPeek as a Symbol Server location in Visual Studio. Make sure you have also unchecked “Enable Just My Code” from the Debug Options.
The last point is to make sure you start Visual Studio with Administrator privileges in order to be able to attach to the w3wp worker process in order to debug:
And voila! We can now step through Sitecore code, set breakpoints AND see local variables! 🙂
This should work for any 3rd party library for which you do not have the source code, not just Sitecore.
Depending on what you are using, there are different ways to set breakpoints in order to debug the 3rd party library.
If you are just using vanilla Visual Studio and dotPeek Symbol Server then you will need to:
- Click Debug > New Breakpoint > Break at Function > enter the full name of the function
If you use Resharper then you can set you can use the Assembly explorer to browse and assembly, open the code in VS and set the breakpoint:
- Resharper > Windows > Assembly Explorer
If you are using Reflector then a similar assembly explorer is available making it very simple to set your breakpoints.
- .NET Reflector > .NET Reflector Object Browser
Debugging using JetBrains dotPeek vs Redgate .NET Reflector Pro
The above methods worked using both dotPeek Symbol Server and .Net Reflector Pro.
Both seem to achieve the same results, but my experience with Reflector Pro was much better. When attaching to w3wp process Visual Studio take approx 2-3 minutes to load the assemblies. This seems much slicker in Reflector. Also using dotPeek it was a less satisfactory debugging experience – sometimes I was able to see the local variables, next time I started Visual Studio it would complain they had been optimized away. I tried many times, in different combinations (restart IIS, restart Symbol Server, start applications in particular order etc) but couldn’t find any consistency to when it would work. It always seemed to work with Reflector Pro.
So I think I’ll head back to Reflector Pro. Well worth the £125 in my opinion, but you know, feel free to reach out and shout me a free copy 😀
I’ll also throw in a plug for JetBrain’s Resharper as well, it’s an awesome tool and once you’ve used it for a while you’ll have trouble using vanilla Visual Studio again. Also feel free to throw me a free copy, time to upgrade it anyway 😀
Both add in the functionality to jump to definition by pressing F12 in Visual Studio, you it’s much easier to hop around that external library from within the IDE and calls in your own code.
The issue I was having with dotPeek Symbol Server may be due to IIS loading a precompiled version of the assemblies before the debugger is attached. This article about Debugging into SharePoint and seeing the locals points to a registry setting to prevent that
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment Add Key: COMPLUS_ZAPDISABLE Type: REG_SZ (String) Value: 1
I’ll give this a try and update the post if anything changes.
Be sure to read the comments below, there are some very useful tips.
- Debugging Sitecore Using DotPeek
- dotPeek Symbol Server and PDB Generation
- What invokes this Pipeline in the Sitecore ASP.Net CMS?
- How to disable optimizations during debugging
- How to set breakpoints without source code in Visual Studio 2010
- .NET Reflector Pro: Debugging the .NET Framework Source Code
- Debugging into SharePoint and seeing the locals