If we are not fine manually closing the lobs instead of throwing an exception, I don't know if I'll find where the missing closing statement should be. I removed the exception so I have a nice stack of the leak:
System.TObject.NewInstance Line 17836 000000000040d5d0 System.pas, line 17836
System.TInterfacedObject.NewInstance Line 39917 0000000000419e54 System.pas, line 39917
System._ClassCreate Line 19214 000000000040e21e System.pas, line 19214
Zdbcoracleresultset.TZOracleClob.TZOracleClob Line 3424 0000000000c65fec ZDbcOracleResultSet.pas, line 3424
Zdbcoracleresultset.TZOracleAbstractResultSet_A.GetBlob Line 2284 0000000000c60c96 ZDbcOracleResultSet.pas, line 2284
Zdbccache.TZRowAccessor.FillFromFromResultSet Line 1347 00000000008bcc25 ZDbcCache.pas, line 1347
Zdbcoracleresultset.TZOracleRowAccessor.FillFromFromResultSet Line 3866 0000000000c67e51 ZDbcOracleResultSet.pas, line 3866
Zdbccachedresultset.TZCachedResultSet.Fetch Line 2418 00000000008d70c6 ZDbcCachedResultSet.pas, line 2418
Zdbccachedresultset.TZCachedResultSet.MoveAbsolute Line 2648 00000000008d7a57 ZDbcCachedResultSet.pas, line 2648
Zdbcresultset.TZAbstractResultSet.Next Line 2567 00000000008ad351 ZDbcResultSet.pas, line 2567
Zabstractrodataset.TZAbstractRODataset.FetchOneRow Line 1997 0000000000d58078 ZAbstractRODataset.pas, line 1997
Zabstractrodataset.TZAbstractRODataset.FetchRows Line 1970 0000000000d57f61 ZAbstractRODataset.pas, line 1970
Zabstractrodataset.TZAbstractRODataset.GetRecordCount Line 3790 0000000000d5ebe6 ZAbstractRODataset.pas, line 3790
Usearchinfirxmlsform.TSearcherThread.Execute Line 169 00000000010da6e2 uSearchInFirXMLsForm.pas, line 169
System.Classes.ThreadProc Line 15509 00000000004c69d0 System.Classes.pas, line 15509
System.ThreadWrapper Line 25370 00000000004108ba System.pas, line 25370
The problematic (I think) will be procedure TZRowAccessor.FillFromFromResultSet(const ResultSet: IZResultSet;{$IFDEF AUTOREFCOUNT}const {$ENDIF}IndexPairList: TZIndexPairList);
Code: Select all
stAsciiStream, stUnicodeStream, stBinaryStream: begin
PIZLob(Data)^ := ResultSet.GetBlob(ResultSetIndex);
if FCachedLobs then
PIZLob(Data)^ := GetAsCachedLob(PIZLob(Data)^);
end;
Data is a PPointer, which is initialized like this:
Code: Select all
P := @FBuffer.Columns[FColumnOffsets[ColumnIndex{$IFNDEF GENERIC_INDEX} - 1{$ENDIF}]];
{$IFDEF RangeCheckEnabled}{$R+}{$ENDIF}
Data := Pointer(PAnsiChar(P)+1);
So I suspect FBuffer.Columns does not get freed up somewhere? I also made the observation that the exception is raised when I close my TZQuery. In the AFTERCLOSE event it looks like this:
Code: Select all
procedure TZCachedResultSet.AfterClose;
begin
inherited AfterClose;
If Assigned(FResultset) then begin
FResultset.Close;
FResultSet := nil;
end;
end;
And the exception is raised when FResultSet is being closed, not the main ZQuery object.
I will attempt to debug it further but I do believe that if we know that something needs to be freed, we should free it instead of throwing an exception.