6
votes

I'm using Delphi 6 and I've got an application which when being shut down produces access violation errors. We use EurekaLog so I'm getting stack traces for debugging, but the errors seem to occur randomly in a different unit each time, but always when something is being freed in the finalization section.

How can I go about debugging this to see what's causing the problem? I'm not sure how to start debugging things that happen when the application is being finalised.

[Edit:] Sorry if I was unclear, perhaps a better question would be: What's the best place to start debugging with breakpoints if I only want to walk through the finalisation sections? The errors seem to arise in third party components we use (the devexpress dx/cxgrid library) so I'd like to start debugging in my code at pretty much the last point before Delphi will start calling finalise routines in other units.

2
Debug just like normal. You may want to use Debug DCUs if AVs occur in RTL/VCL units. Set breakpoints in the finalization sections and step though. In fact you don't really need to set breakpoints, you can just run under the debugger and arrange that exceptions trigger a breakpoint.David Heffernan
The FastMM memory manager is also an invaluable tool for tracking memory leaks. fastmm.LU RD
Do you have many forms? Try and free these from the .dpr file after the call to Application.Run. See if that helps. If you let Application do it then you can run into some complex VCL bugs (but I'm not sure they extend back as far as D6).David Heffernan
@David do you have more information or a link concerning these bugs with form destruction? I recently debugged some situation where this might have played a role...jpfollenius
I put in a qc report. Can't remember number. Search on my name would get you it.David Heffernan

2 Answers

4
votes

This isn't much to go on, but if I had to guess, based on past experience... are you using packages or COM libraries? If you've got a global variable that's an interface, or an object whose class is declared in a BPL, and you unload the DLL/BPL before cleaning up the object/interface, you'll get access violations because your code is trying to do a VMT lookup in address space that is no longer mapped into the application.

Check for that and make sure you clean up all such variables before finalization begins.

-3
votes

When the application is shutting down, do not free things in the finalization section.

1) When the application shuts down, Windows frees all the application memory. You don't have to do that.

2) When the application shuts down, the memory is released, and the infrastructure is unloaded. You can't call code to close or free objects, because that code may have been already unloaded. You can't access pointers to memory, because those pointers may have already been released.

3) When you try to free things in the finalization section while the application is shutting down, you may get failures that prevent your code from finalizing, thus preventing the application from shutting down, causing a hung application and memory loss. Which is what you were trying to prevent in the first place. Don't do it.

Ok, when you are running on Win95/98, or using external processes, you may in some circumstances have to free shared resources and notify those external processes that you are shutting down. Apart from that, it all happens automagically now.