How to debug Windows services with Windbg
Hi all,
If you want to know how to debug a Windows service, the following article will be of great assistance: How to debug Windows services. I suggest you read this article before you continue reading this post. Also, you should have Debugging Tools for Windows installed in your machine; the tools I'll mention (windbg.exe, cdb.exe, gflags.exe & remote.exe) are part of them.
Basically, we can attach a debugger to a service:
a) Just when process starts.
1) Go to HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control registry key and add or modify ServicesPipeTimeout REG_DWORD value to i.e. 3600000 (1h in milliseconds). Restart machine to apply changes. Default is 30 seconds.
2) Use Gflags to associate a debugger to the service. The debugger will attach to the service when starting.
2.1) If service interacts with desktop, we can associate 'windgb' to the service directly.
2.2) If service won't interact with desktop, we can associate 'cdb -server tcp:port=9999' to the service instead. Cdb.exe is the command line version of Windbg. It will attach to the service and expose itself as a server. Then we can launch and connect a windbg instance to that cdb with 'windbg.exe -remote tcp:Port=9999,Server=machinename' and control it remotely.
Note: I use cdb to attach to the service because windbg may fail to start if service won't interact with desktop.
3) Don't forget to undo registry and gflags changes once you are done debugging.
b) At any time. Just find out the service's process ID (PID) or name and attach a debugger to it with i.e. 'windbg -p PID' or ' windbg -pn servicename.exe' .
Here you may have an issue on Windows 2000, for instance. We can only do live debugging on Windows 2000 if we are in the same Window Station as the process we are debugging. When we connect through Terminal Services, we are in a different Window Station than the services, so we can’t attach to their processes.
On Windows Server 2003, for instance, we can cross the barrier between WinStations. More info on WinStations here: INFO: Services, Desktops, and Window Stations.
So in order to debug services with Windbg on Windows 2000 we can do the following:
1) Use AT command to launch remote.exe and expose a cmd.exe as a server with 'at 14:48 remote /S cmd "any string" ' . AT command launches a process under the System acccount at a given time. Remote.exe is a very cool tool which exposes any command line tool as a server. Cmd.exe won't be visible and it will be running under System account in the same WinStation as the services.
Note: We may also use Task Scheduler or any other app which allows us to launch processes under the System account.
2) Use remote.exe to launch another cmd.exe as a client of server cmd instance with 'remote /C machinename "any string" ' . Now we can control the invisible cmd.exe which is running under System account.
3) Thanks to client cmd we can tell server cmd to launch cdb.exe and attach to the service with i.e. 'cdb -p PID' . We can now use cdb to debug the service directly, as cdb is running as System in same WinStation as services.
4) If we prefer to debug with Windbg.exe instead of cdb (so we can do live debugging with source code, for instance) we can expose cdb as a server with its ' .server tcp:port=9999' command and connect to it with 'windbg.exe -remote tcp:Port=9999,Server=machinename' .
I hope this helps.
Regards,
Alex (Alejandro Campos Magencio)
Comments
- Anonymous
August 12, 2010
very intresting, running cmd as system account could be taken as a security risk by some people,but it's a cool way to troubleshoot services.exe