- attached Spring.HazardEra.patch
Access Violation when destroying a TEvent with handlers after the finalization of Spring.HazardEra
With the latest develop version (9bc9edc) i get an access violation in Spring.HazardEra.EraArrayClear/Retire when aquiring the criticalsection after the finalization of Spring.HazardEra. In my specific case this is due to the DUnit-TestFramework clearing its registry and all ITestSuite/Case which seem to still hold an instance of TEvent.
At first I thought this is always (destroying event after finalization) the case but the TEvent also has to have at least one handler remaining.
A small example:
program Project41;
uses
Unit17 in 'Unit17.pas',
Spring;
type
TEvent = procedure(aArg: Integer) of object;
type
TC = class
public
Event: Event<TEvent>;
procedure EventHandler(aArg: Integer);
procedure InvokeEvent();
end;
procedure TC.EventHandler(aArg: Integer);
begin
aArg := aArg;
end;
procedure TC.InvokeEvent;
begin
Event.Invoke(2031);
end;
begin
var c := TC.Create;
c.Event.Add(c.EventHandler);
//c.Event.Remove(c.EventHandler); this "solves" it
Unit17.x := c;
end.
unit Unit17;
interface
var
x: TObject;
implementation
initialization
finalization
x.Free;
end.
Comments (11)
-
repo owner -
repo owner -
assigned issue to
- changed milestone to 2.0
-
assigned issue to
-
repo owner - changed status to open
-
reporter - attached Spring4D_359_FastMM_Log.txt
memory leaks with the patch applied
-
repo owner Then please provide the project
Edit: nevermind, I can repro with a TTestCase class containing a Mock
-
repo owner I just created a branch for this to make it easier to test the changes - I had the scenario you posted initially and some TTestCase with a Mock in it which was being initialized during the test and thus was still allocated until TestFramework.pas finalizes which might be after Spring. I could reproduce the issue there but not after the fix.
I tested with FastMM4, FastMM5 and LeakCheck and could not find any exceptions nor memory leaks.
Please let me know if you can confirm these results.
-
repo owner - marked as blocker
-
reporter The actual project is way too massive to share but I found that the cause is a event notifying destruction of the instance (after the whole finalization part). So i tried adding a destructor like this to the project in the description
destructor TC.Destroy; begin InvokeEvent; inherited; end;
This does cause an error with FastMM4.FullDebugMode (access on freed memory) which I can’t reproduce in the actual project but I still think it might be the same issue.
-
repo owner I am not sure what to do with that latest message - does the error still exist with the change in https://bitbucket.org/sglienke/spring4d/branch/issues/359, did it change to something else or is it gone?
-
reporter Ok, I mistakenly assumed the branch only contains the changes from the patch. I tested all my scenarios again with the current state of the branch and everything looks fine. No memory leak or exception.
Good job
-
repo owner - changed status to resolved
Merging to develop once you confirm
#361is also fixed. - Log in to comment
Seems because of unit in uses order the finalization of Spring is being executed before the destruction of the object holding the event.
Please try this change and let me know if that also fixes the issue in your unit test and does not leave any memory leaks.