I had this nasty bug that disappeared in the past but now after quite some time it returned.
I have two TSam objects (derived from TPersistent) created and loaded into an TAsmJob object (derived from TObjectList).
At runtime, a form creates a TStringGrid and then the AsmJob which creates those two SAM objects (and load some data from disk in each of them). The AsmJob is also assigned to the grid. When the form is destroyed, the Grid takes care of the AsmJob by freeing it, which frees the TSam objects. Here is the problem: the first object is freed withot problems but the second one dies when its inherited method (in Destroy destructor) is called.
I use FreeAndNil in the entire program to free the objects. The TSam objects are not NIL!!!!! So, this is the first attempt to free the objects. Even the data inside the objects is consistent.
The backbone of the program looks like this:
**Create:**
Form -> StringGrid
-> AsmJob -> Sam1, Sam2
StringGrid.AsmJob:= AsmJob;
**Free:**
Form -> StringGrid -> AsmJob -> Sam1, Sam2
I really don’t understand where I try to double-free or overwrite the object AFTER it has been released.
edit:
Some of the errors I got:
FastMM has detected an error during a free block scan operation. FastMM detected that a block has been modified after being freed.
FastMM has detected an error during a free block scan operation. The block header has been corrupted.
Detail:
The current thread ID is 0x19C, and the stack trace (return addresses) leading to this error is:
402E77 [System][@FreeMem]
4068DC [System][@DynArrayClear]
405E2D [System][@FinalizeArray]
405D31 [System][@FinalizeRecord]
40432F [System][TObject.CleanupInstance]
404272 [System][TObject.FreeInstance]
404641 [System][@ClassDestroy]
4D313E [UnitSam.pas][TSam.Destroy][297]
4042BF [System][TObject.Free]
4149ED [SysUtils][FreeAndNil]
4D9C0A [UnitAsmJob.pas][UnitAsmJob][TAsmJob.Destroy][180]
I have all "debug" options enabled in the IDE, including the "Range Check". Also, the FastMM4 is set to super aggressive debug mode. Without FastMM or outside of the debugger the program runs just fine - but yet I know it doesn't mean that the bug is not there anymore. Actually it worked (probably) for more than one one year, until I have installed FastMM.
edit:
Thanks to everybody. No I am feeling I am moving a bit in the good direction.
The structure of the program is more complicated I offered only the backbone to keep the original post small. But what the heck, it already got larger :) So, those TSam objects are used to load data from disk. One file in each object. They are doing also some processing and data validation. For each of these TSam I also have a graphical object that shows on the screen (graphically) the data contained in the TSam objects. Each line in the TStringGrid also show the data in TSam, but textually.
One question I have: if I break the program in smaller pieces to find out where the error is, the error will still appear? Or it is possible to appear only in this particular configuration?
Answer to "how does the AsmJob get assigned to TStringGrid so that the TStringGrid destroys the AsmJob, can you show us?"
MyGrid = TStringGrid
public
AsmJob: TAsmJob;
end;
then somewhere in the TForm.Create (the form that holds the Grid), I do
MyGrid.AsmJob=AsmJob;
and in the destructor of the MyGrid I do:
begin
FreeAndNil(AsmJob);
inherited
end;