Accessibility
navigation | page content |
Accessibility
top of site | navigation |
Latest Tutorials
Tutorials

Making sense of madExcept

Bug fixing and long-standing quality problems get Tim Anderson’s attention.
Making sense of madExcept

Some ideas are so good that you can’t help wondering why all development tools don’t have something like them – take madExcept from Mathias Rauen, for example. A few years back, there was a popular code-centric HTML editor called HomeSite. It was acquired by Macromedia and still comes bundled with Dreamweaver as an alternative editor for ColdFusion, although it is not installed by default. For a while it was my preferred web editor, but I gave up on it after it got into the habit of crashing. When it crashed, the only error dialogs displayed were ones that said ‘Runtime Error 216’ or ‘Runtime Error 217’. HomeSite had a responsive support forum, and others were suffering from the same issue, but the developers didn’t seem to be able to fix it. Even when a new version was released, the same error occurred on some systems. HomeSite is, of course, a Delphi application. One of the problems for both users and developers was that these error messages gave no clue as to the cause of the problem. Most likely, the developers couldn’t reproduce the exact issue, so some bugs were never fixed.

Helping developers
Anyone who has deployed an application will have faced similar problems. Most users report problems as they perceive them, not in a way that is helpful to the developers. A good solution is to automate crash reports, so that you can get the information you need. Enter madExcept. This component does two things: first, it does some low-level trickery to catch exceptions that Delphi normally fails to catch; second, it has a built-in mechanism for generating error reports and emailing them to the developer.

I tried the recently released version 3, which you can freely download from the madExcept website here. Here’s how it works. After you install madExcept, your Delphi IDE has two new features: ‘madExcept Settings’ appears in the Project menu, and ‘madExceptionHandler’ appears on the Madshi tab in the component palette. Now you can try it out.

Start a new project, and make sure that ‘Enable madExcept’ is not checked in the madExcept Settings. Then write some code to raise an exception.

raise Exception.Create(‘Some kind of error’);

You could make this the response to a button click. Run the application and click the button. Delphi’s default exception handler kicks in and you get an error dialog. Now enable madExcept and try it again. This time you get a dialog with five options:

Continue application. This means to ignore the problem and sail on regardless.
Restart application. The application will close and immediately restart.
Close application. Exits the application immediately.
Show bug report. This is the good stuff, letting you drill down into the error.
Send bug report. This enables your users to send you the bug report automatically.

Here is a closer look at the ‘Show bug report’ option. It displays a tabbed dialog with answers to most of the questions you would normally ask a user. The General tab has information including whether the user has local admin rights, free memory and disk space, how long the application has been running, how long the system has been running, and the time and date of the executable. Next, the call stack helps you to work out what path the code took to get to the point of failure. If you have Delphi running with the application project loaded, you can double-click this list to jump to the matching code or VCL unit. The next two tabs show running modules and processes, giving you a good idea of what else is running. For example, you might notice that your application crashes when a particular antivirus process is running.

The report continues with the Hardware tab. This is similar to the list in the device manager part of the System applet in the Windows control panel. CPU registers are listed next, followed by the stack dump, and finally a snippet of assembler showing the last few instructions.

Sending reports
This is not the kind of report that makes sense to most users. That doesn’t matter, though, because all they need do is to click ‘Send bug report’. This opens a wizard called the Send assistant, which creates an email, gives the user a chance to add a description of what went wrong, and attaches a text version of the bug report along with a screenshot of the application as it crashed.

madExcept doesn’t yet know where to send the email. To fix this, have a look at the madExcept Settings. Sending an email from an unknown client can be tricky, so madExcept covers pretty much all the options, including SMTP as server or client, HTTP upload and MAPI.

madExcept does more than simply handle Delphi exceptions. It runs for the most part outside the VCL, enabling a couple of useful characteristics. Delphi’s global exception handlers don’t run in all circumstances. For example, if you take the line of code above that raises an exception, tuck it into the initialisation section of a unit, and disable madExcept, you will get a different result from your first one. Instead of showing the exception, the application fails to start, displaying our old friend ‘Runtime Error 217’. This is because the code initialising the global exception handlers has not yet run. However, madExcept will still trap the exception. Another key ability is that madExcept can monitor the main thread of the application. If it hangs, madExcept will raise an exception for you.

One consequence of using madExcept is that the normal global exception handlers do not run. If you have handled Application.OnException or set the ErrorProc variable then this code will have to be revised. You can do this using the madExceptionHandler component. Drop this onto a form, and have a look at its events. The OnException event fires whenever madExcept handles an exception. It passes an argument of type IMEException. This object encapsulates the madExcept settings, which you can then modify for this occurrence only.

Fine-tuning options
You can also set ‘Handled’ to ‘True’ to cancel further handling of this exception. This allows fine-tuning, such as suppressing the bug report for certain categories of exception. The other event fired by madExceptionHandler is OnExceptAction. This fires for each action such as SendBugReport or ContinueApplication.

Overall, madExcept gives Delphi developers such insight into code problems that it could pay for itself in the course of just one technical support call.

Tim Anderson  
  PC Plus Issue 237 - December 2005