TDelphiWebScript.Destroy inconsistent behavior
Issue #24
closed
in the destructor the inherited Destroy is invoked before self-destructions. Firstly, this is not usual practice to do so: usual are -- in ctors call inherited in first place, to ensure initialization of inherited members, and in destructors -- call inherited after finalization of of self members. Is TDelphiWebScript.Destroy designed against the rule on a purpose? -- because if not, I've spent several hours investigating AV-usage of freed object on the simple case:
procedure exscript();
var myUnit:TdwsUnitA;//symadd override
begin
dwsc:=TDelphiWebScript.Create();
myUnit:=TdwsUnitA.Create(dwsc);//dwsc owned this unit, let him manage lifetime
dwsc.AddUnit(myUnit);
//do stuff
FreeAndNil(dwsc);//And here is problem!
//althought TDelphiWebScript stores it's unit list
//as list of interfaces, but because of TdwsUnit is TComponent descendant -- reference
//counting does not work! So calling inherited destructor in first place decommits all
//owned objects, including myUnit! Subsecquent FConfig.Free; causes AV, since it calls
// _intfClear on freed myUnit object, while derefencing IdwsUnit links in the unit list.
end;
so, let the code looks like this
destructor TDelphiWebScript.Destroy;
begin
FCompiler:=nil;
FConfig.Free;
FExtensions.Free;
inherited;
FLock.Free;
end;
Comments (3)
-
repo owner -
repo owner Also inherited as to be called before FConfig is freed to support the following scenario where the TdwsUnit is bound to the Script (and similar variants in the design-time editor).
s:=TDelphiWebScript.Create(nil); try u:=TdwsUnit.Create(s); u.Script:=s; finally s.Free; end;
-
repo owner - changed status to closed
Fixed by commit 67f27b3
- Log in to comment
Hmm, using AddUnit directly for a TdwsUnit will result in an incoherent internal state (Script reference will not be defined or may even reference another TDelphiWebScript instace), you should be using "myUnit.Script := dwsc;" instead.
I will see about locking down that usage.