awmross
awmross

Reputation: 3839

Delphi app crashing outside debugger but not inside

Our DUnit project is crashing on exit. It crashes if "Run Without Debugging", but doesn't crash if I Run inside the debugger.

If I attach the debugger to the process after starting it, it does not crash on exit.

I suspected a problem in finalization, so I put print statements in all the finalization code I suspected was running. This turned up nothing useful. Finalization for one of our low level Units (with no dependencies on any non-system Units) is running correctly. So it still could be finalization, but it may not be.

The crash produces this dialog:

Problem signature:
  Problem Event Name:   APPCRASH
  Application Name: MCLTesting.exe
  Application Version:  0.0.0.0
  Application Timestamp:    4eb07b50
  Fault Module Name:    kernel32.dll
  Fault Module Version: 6.0.6001.18215
  Fault Module Timestamp:   49953395
  Exception Code:   c0000005
  Exception Offset: 000bf395
  OS Version:   6.0.6001.2.1.0.256.6
  Locale ID:    3081
  Additional Information 1: b37c
  Additional Information 2: 2a7328d8bb40c81c93b4b5f46adb8e10
  Additional Information 3: b37c
  Additional Information 4: 2a7328d8bb40c81c93b4b5f46adb8e10

"Exception Code: c0000005" Does that mean anything?

The main clue I have is the fact that it doesn't crash in the debugger. Has anyone seen that before?

Upvotes: 4

Views: 3920

Answers (2)

awmross
awmross

Reputation: 3839

I finally tracked this down.

The problem was indeed in a finalizer. A user exception was being thrown in a finalizer. The exception was not caught, and the exception itself was being leaked (The Exception and its string were not freed). It seems this memory leak was causing the crash? I'm not sure why I didn't notice this memory leak when I originally posted.

Catching the exception fixed the crash problem.

One interesting thing I found out is that even if an uncaught exception is thrown in a finalizer, subsequent Unit's finalizers will still be run. I was assuming that a problem in one finalizer would stop all subsequent finalizers from running.

The method I used to find the offending Unit was very simple; I removed all units from my project, then reintroduced Units one by one until I got the crash bug. Time consuming but it worked in the end.

Upvotes: 4

Mason Wheeler
Mason Wheeler

Reputation: 84650

Exception code c0000005 is an access violation. This usually means one of two things: either you're attempting to dereference a pointer or object reference that's set to nil, or you're working with corrupted memory.

The other pertinent piece of data in the error report is Exception Offset: 000bf395. That tells you where the error is occurring. Try looking up f395 in your map file and see if you can't find a unit finalization that corresponds to that memory offset. If so, that should give you a good idea as to what's going wrong.

Upvotes: 2

Related Questions