A few things to think about.

1) Double check all free operations. Freeing pointers, clearing arrays, and nullifying certain types in slightly wrong ways can make big errors on exit.

2) Ensure that you are actually not freeing things in the improper order. For example Zlib is dependent upon a child stream that you pass it to decompress from, or compress to. If you free the wrong one first then you can have errors while freeing the other.

3) Lost surfaces/canvases. Timed operations and such that hit a losable canvas or surface can cause these, but a simple "timer.enabled := false" at the beginning of your close/destroy event can prevent it.

I know they're all elementary things you've probably thought of, but they are the most common, simplistic, mistakes that you can make. Many times I've shot myself in the foot like this. Maybe if you show the close/destroy event that is called when you close the application I could help, but without source I can't do more than this.