I have a Web Service Server application that uses Aurelius. The application when shutdown had memory leak and access violation. After looking into Aurelius code, I nailed down the cause:
Aurelius has a lot of static global vars that are destroyed in the defining Unit's finalization section, and this may sometime cause problems, for example,
TAureliusModelEvents.Destroy internally will access the global ExplorerManager, which could possibly already been destroyed at the app shutdown
Likewise, TSQLiteDatabase.Destroy internally calls f_sqlite3_close, but the sqlite3.dll may already be unloaded
Again - all these problems are caused by the Delphi system unloading process (calling the finalization section), while at the same time, some Aurelius objects wrapped in interface (hence reference counted) are destroyed after those global vars destruction.
For now, I made the following "fixes" myself, but @wlandgraf probably can come out with some better systematic ways:
Aurelius.Drivers.SQLite.Import.pas
procedure FinalizeSQLiteUnit;
begin
if LibraryHandle <> 0 then begin
FreeLibrary(LibraryHandle);
LibraryHandle := 0; // <------ set this to 0
f_sqlite3_close := nil; // <-----set this to nil
end;
end;
Aurelius.Drivers.SQLite.Classes.pas
destructor TSqliteDatabase.Destroy;
begin
if (FHandle <> nil) and Assigned(f_sqlite3_close) then // <---- check if f_sqlite3_close is nil or not
f_sqlite3_close(FHandle);
inherited;
end;
Aurelius.Comp.ModelEvents.pas
procedure TAureliusModelEvents.UnsubscribeEvents;
begin
if csDesigning in ComponentState then Exit;
OnCollectionItemAdded := nil;
OnCollectionItemRemoved := nil;
OnDeleted := nil;
OnDeleting := nil;
OnInserted := nil;
OnInserting := nil;
OnSQLExecuting := nil;
OnUpdated := nil;
OnUpdating := nil;
{ // Comment these out.
Events.OnInserting.Unsubscribe(FInsertingProc);
Events.OnInserted.Unsubscribe(FInsertedProc);
Events.OnUpdating.Unsubscribe(FUpdatingProc);
Events.OnUpdated.Unsubscribe(FUpdatedProc);
Events.OnDeleted.Unsubscribe(FDeletedProc);
Events.OnCollectionItemAdded.Unsubscribe(FCollectionItemAddedProc);
Events.OnCollectionItemRemoved.Unsubscribe(FCollectionItemRemovedProc);
Events.OnSQLExecuting.Unsubscribe(FSQLExecutingProc);
Events.OnDeleting.Unsubscribe(FDeletingProc);
}
end;