Question

We have a Delphi app that has been running for a few years and now suddenly we get weird access violations. We used Eurekalog to trace where it comes from and this is even more weird. They are so far all on the Free call of an object, but inside a try except block. One of them is even in 2 try except blocks and still when the Access Violation occurs it jumps totally out of the program and ignores the try excepts, nothing excepts EurekaLog catches it at the end. Really confused on why this is suddenly happening (both instances are old code that has not been touched for years and also other codes changes is not related to it).

A example of the code is

      try
    if Assigned(ClientCommunication) then   begin
      if ClientCommunication.isConnected then  begin
        if ClientCommunication.closeServerConnection then   begin
          try
            ClientCommunication.Free;
            ClientCommunication := nil;
          Except
            on e:Exception do begin
             ClientCommunication := nil; //suppress weird AV error.. get read for new object
            end
          end;

Now the last try except was added later to try and suppress the AV as we just want the object cleared to be restarted if required, but this is mostly called when closing the app. But it still just jumps out of that and I can’t catch it at all.

It works on our developers PCs and not at the client.

Was it helpful?

Solution

If this line: ClientCommunication.Free; is causing an exception. There are a few things you can do here.

FreeAndNil
Replace calls to AObject.free with calls to freeandnil(AObject).
If you just do the free, the old pointer will still have a non-nil reference and Assigned(AObject) will not be able to tell a freed and active object apart.

Beware of clones
Another mistake you may make is that you've cloned the object like so:

Object1:= TObject1.Create;
//.... lots of code
Object2:= Object1;
//.... lots of code
FreeAndNil(Object2);  <<-- freeing the clone-reference is a mistake
//.... lots of code
Object1.Free; <<-- exception: it's already freed

FastMM4 options
Download the latest FastMM4 from http://sourceforge.net/projects/fastmm/
It has a few extra bells and whistles from the one included with Delphi.(*)
Among those whistles is an extra diagnostic mode that makes your program dead slow, but also catches out a lot of those heap corruption bugs you seem to be suffering from.

Open up defines.inc and change this:

{$ifdef DEBUG}
  {.$define EnableMemoryLeakReporting}
  {.$define FullDebugMode}
  {.$define RawStackTraces}
{$endif DEBUG}

Into this

{$ifdef DEBUG}
  {$define EnableMemoryLeakReporting}
  {$define FullDebugMode}
  {$define RawStackTraces}
  {$define CatchUseOfFreedInterfaces}  <<-- very useful
  {$define LogMemoryLeakDetailToFile}
  {$define LogErrorsToFile}
  {$define CheckHeapForCorruption}  <<-- :-) 
{$endif}

There's a nice article here: http://wiert.me/2009/07/29/delphi-fastmm-using-fastmm4-for-debugging-your-memory-allocations-part-1-introduction/
If you don't feel like mucking about with the inc file, there a little utility that will do it for you at: http://jedqc.blogspot.com/2007/07/new-fastmm4-options-interface.html

(*) I think the Delphi one has most of the debug stuff as well, but not 100% sure. Regardless can't hurt to get the latest (greatest) version.

Or buffer overflow
If your ClientCommunication object has some internal structure free will do extra work.

Imagine the following code:

TUnrelatedObject = class
   buffer: array[0..99] of integer;
   procedure DoWork;
end;

TUnrelatedObject.DoWork;
var
  i: integer;
begin
  for i:= 0 to 100 do buffer[i]:= maxint;  <<-- buffer overrun
end;  

Imagine that ClientCommunication is right next to UnrelatedObject in the heap.
The call to DoWork will overwrite data of ClientCommunication as well.
This may or may not trigger an access violation in DoWork. If it doesn't then the error will be very hard to trace, because it will show up in a different and totally unrelated places.

Enable range checking {$R+} in your application.

Warning
Remember to not ship the debug version to your clients.
With all the debugging your program will be dead slow.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top