My Account account_circle

Debugging Windows Services with Delphi

Please note that this article is obsolete. Due to other users reporting problems in getting support for SvCom (and Google disabling the company’s website with their Safe Browsing system), we do not recommend using this component anymore.

Introduction
Drawbacks of Official Debugging Method
Best Practices and Development Tools
Conclusion

Introduction

Debugging Windows services with Delphi can be quite a challenge. The documented and recommended way to debug a Windows service with Delphi is to use the Attach to Process command from Delphi’s Run menu. This, however, is not the best approach to debug services.

Drawbacks of Official Debugging Method

The official way to debug services with Delphi has some drawbacks. The following points highlight the main problem areas:

  • Due to insufficient user rights or other reasons you are often not allowed to debug Windows services. Under Windows 2000, for instance, I never got Attach to Process work on a service, even with Admin rights. It looks like Microsoft fixed this, because it is now working under Windows XP (just like End Process in the Task Manager now works on services under Windows XP – it never worked on Windows 2000).
  • Debugging the starting code of a service is not really possible. Due to the nature of the Attach to Process command, you have to start the service through the Service Manager first and then attach to it. That’s why you will not be able to debug the starting code of your services.
  • Getting the stopping code of services right can be quite hard: If you have many threads, many data objects, database connections etc. and you have to synchronize them, close them and free them all in the right order, the possibility to have bugs waiting in the stopping code is high. Now, you can debug the stopping behavior of your service with Attach to Process (if you get the debugging working at all), however, it is not possible to debug your service when Windows shutdowns. My experience shows me that services often behave differently when Windows shuts down and it can be quite useful to be able to debug the shutdown behavior of services. I will show you how you can do this without even having Delphi running.

To summarize the drawbacks of the normal approach to debug Delphi services, we can say that it is often complicated to get Delphi Windows debugging working at all (due to OS shortcomings or user rights) and even when the service debugging works you will miss important parts of the service life-cycle like starting or shutdown code.

Best Practices and Development Tools

The first advice I will give you is applicable to both services and normal applications: I highly recommend that you get yourself a copy of VMWare Workstation if you not already own one. VMWare lets you run a virtual computer in a window on your Windows desktop. This effectively means that you can run multiple copies of Windows on one machine and test your software without interfering with other applications on your main Windows installation.

VMWare is especially useful when you debug Windows services. If you need to debug the behavior of a service during a Windows shutdown, for example, it is quite nice to only reboot the virtual machine and not the whole computer. I cannot say enough good things about this product, so check VMWare out and get a copy if you like it.

Testing a service on a virtual machine in VMWare
Testing a service on a virtual machine in VMWare (larger image)

To effectively debug Windows services with Delphi, I recommend that you get two tools to do it. The first one is Aldyn Software’s SvCom [link disabled due to problems with the SvCom website; please see our note at the beginning of this article]. When you use SvCom to develop your service, you are able to start your service in two modes. The first mode is the normal service mode where your program is started by the Windows Service Manager. This is the normal behavior when no command line option is specified. The second mode is called the Debug mode. The Debug mode is enabled when you call your program with the command-line option /debug. When you start your service with this option, a built-in Service Manager replacement of SvCom is started which emulates all the normal Service Manager functions like Start, Stop, Pause and Resume.

When your program is started in this Debug mode it is not really running like a Windows service, but uses a faked Service Manager replacement to emulate all the functionality of it. You can now easily debug your application within Delphi and use breakpoints, watches etc. Because SvCom comes with a whole TService and TServiceApplication replacement, you don’t have to write special code to use the normal service mode and the Debug mode. If you seriously develop Windows services with Delphi, SvCom is a must-have.

The second tool you should have available when you debug Windows services written in Delphi is a good logging tool. There are different logging tools available for Delphi but since my company, Gurock Software, sells its own advanced logging tool called SmartInspect, I will show you how this works with SmartInspect.

Logging means that you add log statements to your code to send all kind of useful information to a viewer application or to a log file. You can then analyze all these information in a comfortable way and identify bugs and solve them.

SmartInspect used in a multi-threaded server application
SmartInspect used in a multi-threaded server application (larger image)

The nice thing about this technique is that you don’t need Delphi running to debug your services and applications. This makes it possible to easily debug your services even at your customer’s place or in bizarre situations like the Windows shutdown problem we just talked about. You can even use the SmartInspect Console on one computer and inspect your service on another machine. Imagine you want to debug your service during Windows startup or shutdown in real-time – this is the only way you can do it.

When you use logging in your applications, you can keep all the log statements in your code and disable it by default when you ship it. Many of our customers do it this way. They can then just enable the logging when a problem occurred even after the code has shipped. This has the nice effect that your customers just send you a log file, for example, and you can debug and inspect your application just like during the development.

Conclusion

So my strategy for debugging and developing Windows services is to use SvCom as the service framework, make heavy use of SmartInspect to debug and monitor the service during development and production use and additionally use VMWare to save time and test different platforms. I hope this article helped you to learn more about Windows service debugging with Delphi and that you can apply this learned knowledge to your development activities. If you have any questions about this article, do not hesitate to contact me at [email protected].