Among the worst things that can happen to an application developer is having their software crash at a customer’s location—and having the customer on the phone to them, screaming. So how do you prepare against such an eventuality?
In this article I’ll look at a few things you can do to be ready when–not if–something goes wrong, whether it’s hardware failure, a disk crash or someone pulling out a power cable and corrupting a disk. Actually, if you can deal with that last event you’re doing very well. But hopefully the client makes backups.
Catch All Exceptions
If an exception reaches the operating system, then your application will either vanish without a trace or, if you’re lucky, show some kind of message before it does. Either way, it’s a poor user experience. Displaying a message saying that something has gone wrong and the program will now terminate–hopefully saving the user’s data first–is the least you can do.
In my experience, Microsoft Office is very good at saving data. There are a variety of ways to do this in your software: Catch the exception and save the data or implement a journaling scheme where it’s held on disk in a temporary file until properly saved. If a crash occurs, then the journal can be read to recover recent data.
Retrieving a stack dump and logging or emailing it have been standard in the .NET/Java world for many years, and it’s done in the Win32 world as well.
Build In Secret Debug Tools
Saving the user’s data is one thing, but finding out what went wrong is another. To help, I like to build in advanced debugging tools but leave them hidden until activated by the dual combination of a special text file and hidden mouse/key-click combination.
The last thing you want is to give the client admin level access. Unless they are a techie themselves, doing that is unlikely to end well. I’ve used an approach where activation only works if a special named file is present in the application’s folder. The file is named something like C53A.txt. The odd name uses a simple obfuscation scheme by reversing the “Excel Date” in hexadecimal so that the file is only good for the rest of that day. But any scheme will do so long as it keeps the casual user out.
Admin level debug tools should include SQL console run commands, as well as provide access to internal data structures, etc., and change logging levels. Running the application in an enhanced logging mode may help pinpoint the cause of the crash. On a few occasions when I’ve not been able to debug the application live, I’ve built a version with a logging statement for every line in the affected method. It’s not a great technique (it bloats and slightly slows the application in that area) but sometimes it’s been the only way.
Providing the client with “debug tools,” such as sending a screen shot or emailing a text file containing the internal stack trace, will help you as well.
Data Spew Debugging
This is my name for building your application so it continually outputs data to a debug channel.
Win32 has a useful function, OutputDebugString(), part of Kernel32.dll. It sends a string to an attached debugger. You can build lots of calls to this into your program with little overhead. If no debugger is present, it makes no difference. Microsoft has given away many useful tools, among them DebugView. It’s part of the excellent SysInternals collection. Inside of Visual Studio you can see the output, and if you run DebugView on the same PC as your program, it’ll capture all of the OutputDebugString output.
Finally, any non-trivial application should keep a log file. Rolling logs are best, since it’s really bad form to fill someone’s disk with a multi-gigabyte log file (which is going to be difficult to edit or view in any case). Back in 1983, I once drove 30 miles to an airport hotel to clear a log file that was preventing the client’s main booking application from starting. It’s best to avoid that kind of situation.
Images: Laborant/Shutterstock.com, David Bolton