How to debug a crash that only occurs on application shutdown? (Delphi)

8.1k views Asked by At

So, after some recent changes we discovered that one of our oldest applications is sometimes crashing on shutdown. This manifests itself either in the form of "Runtime error 216" messages or in a message from Windows Error Reporting that the application has stopped working. The application is already emitting OutputDebugString-messages at every turn and AFAICT all of our own code gets executed correctly to completion. All destructors are called as are all finalization sections and class destructors, none of which are raising any exceptions.

Also, neither madExcept nor FastMM4's Full Debug Mode seem to have anything to complain about (though that might be a false conclusion because the crash might happen even before those components' own finalization code runs).

So, what would you do? Where would you start?


This question is supposed to be more about the general approach to this class of problems than about the specific instance I'm currently facing so I'm deliberately leaving out details. Feel free to ask if you think they might be relevant to the choice of debugging approach and I will add them later.

6

There are 6 answers

3
Chris Thornton On

You've likely got a pointer problem. Some event or method is trying to run on an object that doesn't exist anymore.

0
CloudyMarble On

Well the Runtime error 216 are memory issue (Access violation), it seems like you refer to some Object which doesnt exist at that point of time.

Emarcadero writes:

Applications that use the SysUtils class map most runtime errors to Exceptions, which allow your application to resolve the error without terminating

Did you try to set a breackpoint at the finalization section of Sysutils?

I would try it with an Allocation / Memory Profiler, its not sure you will find the error code line but this may show you some parts of your code where Memory issues occure.

3
Mason Wheeler On

Are you using runtime packages? I've seen similar issues before. If you're sharing globals or interfaces across package boundaries, you have to make sure that all references to classes that belong to a certain package get cleaned up before that package is unloaded; otherwise they'll try to make virtual calls into memory that's no longer valid.

0
Ritsaert Hornstra On

A runtime error 216 means that you have an Av (access violation) and SysUtils has already stopped translating those errors to exceptions.

First try: Build with debug DCU's and look in the unit system where the error is raised, set a breakpoint there. hopefully you can catch it in the debugger and work from there.

You probably have a memory bug (dangling pointer, null reference etc etc use of s string constant in an already finalized unit) and the best trick is to check the finalizations after sysutils is finalized. You can do this by building WITH debug dcu's, setting the break point to the finalization in sysutils and start stepping through the code until the error occurs.

4
user643124 On

"Runtime error 216" is from Windows itself, not the Delphi exception handler. I've found that it is caused by code that runs in initialization and finalization sections of units, which execute before the Delphi exception handler kicks in. Particularly. COM objects that need to unload through finalization code running after the Delphi App has terminated will cause this and similar errors. So check that stuff.

MNG

0
Alex On

Like others said: 216 means AV after SysUtils was shutdown. Usually, the only thing that shutdowns after SysUtils (and have chance to raise AV) - is System unit. Specifically: memory manager.

So, run-time error 216 at shutdown usually means memory corruption bug in your application.

That can be very easy to solve - just enable full debug mode in memory manager or use a debugging memory manager. Sometimes, however, it can be very hard to find. But you can start with debug mode of MM first.

See this article.