Debugging trick for .NET Windows Service
I was recently reading a blog post about debugging windows service. I don’t want to duplicate the same, IMO it was a very good post. One of things the post had mentioned about updating the registry key “ServicesPipeTimeout” and to increase timeout ,so that SCM does not kill the debugger and service. The one issue with changing this registry key is ,the system has to be rebooted for this to take effect and, this change is applicable across for all services. To restart a server in a production environment is never easy, because of other applications.
The same problem that was mentioned in the post ,can be dealt as Post-Mortem debugging. What I mean by that is ,taking a memory dump when there is an unhandled exception in the process. This can be automated by using a config file for cdb/windbg.exe . In this config file we write actions for events, like on the first chance of .NET Exception log the call stack , on the second chance generate a full memory dump. The debugger commands are pretty arcane and there isn’t editor with Intellisense, so what is the solution to this.
Adplus is the answer. Adplus.vbs is a vb script file (until the recent windows debugger release) that generates this necessary config file , which is much easier to edit than to create. So here is the command to generate memory dump on Unhandled .NET Exception
sxe -c2 @".echo ---;.echo --- 2nd chance NET_CLR exception ----;.echo ---------------------------------------------------------------;.echo;.echo Occurrence happened at: ;.time;.echo;.echo Faulting stack below ---;~#kvn250;.echo;.dump -u /ma /c 2nd_chance_NET_CLR_exception_in_app_running_on_server D:\debuggers\app_running_on_server_2nd_chance_NET_CLR__full.dmp;!elog_str ADPlus detected a 2nd chance NET_CLR exception in process app_running_on_server and has taken the following actions at the time of the crash: Log Time Stack FullDump EventLog. The output directory is D:\debuggers\Debug-Crash; GN" clr
So we can still trouble shoot windows service start-up without changing the registry entry and not getting terminated by SCM. So here is my cdb config file that I use for debugging. Like I said I did not hand create it , rather I update the one which the adplus created. This script will start a remote server for the debugger clients to connect , similar to the one that was mentioned in the blog post, loads sos when clr gets loaded and few more things. This is script nothing but a simple automation for mundane things inside the debugger.
The config file has to be passed a parameter to the cdb.exe . Here is the sample gflags debugger text that I use
d:\Program Files\Debugging Tools for Windows (x64)\cdb.exe -cf d:\Tools\debug.cfg
And a usual mistake people do within the script it forgetting the escape character and here is example how to use one
sxe -c “.load c:\\Windows\\Microsoft.NET\\Framework64\\v2.0.50727\\SOS;GN ” ld:mscorjit