View Issue Details

IDProjectCategoryView StatusLast Update
0032168FPCRTLpublic2018-07-25 20:59
ReporterAfrican Wild DogAssigned ToMichael Van Canneyt 
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Product Version3.0.2Product Build 
Target Version3.2.0Fixed in Version3.1.1 
Summary0032168: TInterfacedObject destructor reentrance bug
DescriptionI have found a bug in the TInterfacedObject.

Better than explaining is to examine and execute the code below.
When executing the code below the destructor of the class TCustomDestructorClass is called infinitely.
This is due to calling the procedure Foo inside the destructor of TCustomDestructorClass, whhich causes the _addRef and _Release methods to be called again. As the reference count reaches zero again, this triggers the calling of the destructor again e and so the cycle will repeat infinitely.

I think one solution would be the _Release method to check if the instance is already being destroyed before calling the destructor of the class (Destroy method). Currently the method only checks if the reference count reaches zero.



==== CODE BEGIN =========

program interfaced_object_error_2;

type

  { TCustomDeestructorClass }

  TCustomDestructorClass = class(TInterfacedObject)
  public
    destructor Destroy; override;
  end;

var
  DestrcutorCount: Integer = 0;
  CustomRef: IInterface;

procedure Foo(Value: IInterface);
begin
  if Value <> nil then
    Inc(DestrcutorCount);
end;

{ TCustomDeestructorClass }

destructor TCustomDestructorClass.Destroy;
begin
  Foo(Self);
  inherited Destroy;
end;

begin
  CustomRef := TCustomDestructorClass.Create;
  CustomRef := TCustomDestructorClass.Create; // Forces execution of destructor
end.



=== END ===========
Steps To ReproduceCompile and run the snippet of code attached in description
TagsNo tags attached.
Fixed in Revision36757
FPCOldBugId
FPCTarget
Attached Files

Activities

Serge Anvarov

2017-07-19 19:46

reporter   ~0101794

Delphi 7 has the same bug.
Delphi 10.2, protected with "_RefCount or $80000000" after it is reset. Thus, a maximum of two DestructorCount or DestrcutorCount :)

Thaddy de Koning

2017-07-19 21:20

reporter   ~0101796

That's correct (The D7 part), but come on.. Foo(Self);?? in this scenario is indeed infinite.

Michael Van Canneyt

2017-07-21 18:10

administrator   ~0101841

Fixed, thanks for reporting.

Issue History

Date Modified Username Field Change
2017-07-19 15:36 African Wild Dog New Issue
2017-07-19 19:46 Serge Anvarov Note Added: 0101794
2017-07-19 21:20 Thaddy de Koning Note Added: 0101796
2017-07-20 09:39 Michael Van Canneyt Assigned To => Michael Van Canneyt
2017-07-20 09:39 Michael Van Canneyt Status new => assigned
2017-07-21 18:10 Michael Van Canneyt Fixed in Revision => 36757
2017-07-21 18:10 Michael Van Canneyt Note Added: 0101841
2017-07-21 18:10 Michael Van Canneyt Status assigned => resolved
2017-07-21 18:10 Michael Van Canneyt Fixed in Version => 3.1.1
2017-07-21 18:10 Michael Van Canneyt Resolution open => fixed
2017-07-21 18:10 Michael Van Canneyt Target Version => 3.2.0
2018-07-25 20:59 African Wild Dog Status resolved => closed