Abweichung von Freepascal zu Delphi bei Interfaces

Für Fehler in Lazarus, um diese von anderen verifizieren zu lassen.

Abweichung von Freepascal zu Delphi bei Interfaces

Beitragvon Michl » 8. Jan 2018, 22:40 Abweichung von Freepascal zu Delphi bei Interfaces

Servus,

folgender kleiner Test läuft bei Delphi problemlos durch, bei Freepascal gibt es einen SIGSEGV. Wenn man vorher die Interface-Variable auf nil setzt, funktioniert dies auch bei Freepascal. Welches Verhalten ist das richtigere? Ich sehe Argumente für beide Features:
Code: Alles auswählen
program Project1;
 
{$APPTYPE CONSOLE}
 
{$R *.res}
 
uses
  SysUtils, Classes;
 
type
  ITestInterface = interface
    ['{DC209DB2-6E2D-4680-93D6-5D9B3983C0D3}']
    function OnlyDummy: integer;
  end;
 
  TFoo = class
  public
    Intf: ITestInterface;
  end;
 
  { TBar }
 
  TBar = class(TComponent, ITestInterface)
  public
    function OnlyDummy: integer;
  end;
 
{ TBar }
 
function TBar.OnlyDummy: integer;
begin
  Result := -1;
end;
 
var
  Foo: TFoo;
  Bar: TBar;
 
begin
//  ReportMemoryLeaksOnShutdown := true;
  Foo := TFoo.Create;
  Bar := TBar.Create(nil);
  Foo.Intf := Bar;
//  Foo.Intf := nil;
  Bar.Free;
  Foo.Free;
end.

PS.: Kann mir jemand erklären, warum man die interfaced Klasse extra aufräumen muss? Dies ist bei Delphi und Freepascal gleich. Leite ich nicht von TComponent (welches andere Interfaces implementiert) ab, funktioniert die Referenzzählung und man braucht "Bar" nicht selber frei zu geben.
Code: Alles auswählen
type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 
Michl
 
Beiträge: 2260
Registriert: 19. Jun 2012, 11:54
OS, Lazarus, FPC: Win7 Laz 1.7 Trunk FPC 3.1.1 Trunk | 
CPU-Target: 32Bit/64bit
Nach oben

Beitragvon theo » 9. Jan 2018, 10:25 Re: Abweichung von Freepascal zu Delphi bei Interfaces

Ich kann den Fehler nicht reproduzieren.

Lazarus 1.9.0 r56988M FPC 3.0.2 x86_64-linux-gtk2
theo
 
Beiträge: 8058
Registriert: 11. Sep 2006, 18:01

Beitragvon Michl » 9. Jan 2018, 10:40 Re: Abweichung von Freepascal zu Delphi bei Interfaces

Oh, ich habe vergessen zu erwähnen, daß Heaptrc aktiviert sein muss.
Code: Alles auswählen
type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 
Michl
 
Beiträge: 2260
Registriert: 19. Jun 2012, 11:54
OS, Lazarus, FPC: Win7 Laz 1.7 Trunk FPC 3.1.1 Trunk | 
CPU-Target: 32Bit/64bit
Nach oben

Beitragvon Socke » 9. Jan 2018, 10:59 Re: Abweichung von Freepascal zu Delphi bei Interfaces

Die Exception ist korrekt.

In Foo.Intf hast du noch eine Referenz auf das Objekt Bar gespeichert.
Im Dekonstruktor werden alle verwalteten Typen (insbesondere Strings und Interfaces) aufgeräumt. Für COM-Interfaces wird die Methode _Release aufgerufen.
Zeigt Foo.Intf auf einen ungültigen Speicherbereich, tritt die SIGSEGV auf.
Die Unit heaptrc kann solche fehler durchaus häufiger auftreten lassen, auch wenn sie selbst nicht die Ursache ist.

Wird vor dem Freigeben von Bar, die Variable Foo.Intf auf nil gesetzt, wird bereits dann die Methode _Release aufgerufen.
Hier wird der Aufruf aber problemlos ausgeführt, da das Objekt noch existiert.

In Delphi könnte hier auch eine Exception auftreten, ob dies der Fall ist, hängt aber davon ab, ob der Speicherbereich, in dem Bar gespeichert ist, bereits an das Betriebssytem zurückgegeben wurde.
Falls der Speicherbereich dem Programm noch zugewiesen ist, könnte auch vollkommen ungewollter Code ausgeführt werden.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Socke
 
Beiträge: 2546
Registriert: 22. Jul 2008, 18:27
Wohnort: Köln
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 8.1/Debian GNU/Linux/Raspbian/openSUSE | 
CPU-Target: 32bit x86 armhf
Nach oben

Beitragvon mse » 9. Jan 2018, 11:02 Re: Abweichung von Freepascal zu Delphi bei Interfaces

mse
 
Beiträge: 1986
Registriert: 16. Okt 2008, 09:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0) | 
CPU-Target: x86,x64,ARM
Nach oben

Beitragvon theo » 9. Jan 2018, 11:06 Re: Abweichung von Freepascal zu Delphi bei Interfaces

Was ich nicht ganz verstehe ist, warum ich so ein MemLeak produziere (keine Zugriffsverletzung).

Code: Alles auswählen
  Foo := TFoo.Create;
  Foo.Intf := TBar.Create(nil);
  Foo.Free;   


EDIT: So wird der Speicher korrekt freigegeben.
Code: Alles auswählen
 
  { TBar }
 
  TBar = class(TInterfacedObject, ITestInterface)
  public
    function OnlyDummy: integer;
  end;   
theo
 
Beiträge: 8058
Registriert: 11. Sep 2006, 18:01

Beitragvon Socke » 9. Jan 2018, 11:24 Re: Abweichung von Freepascal zu Delphi bei Interfaces

TComponent leitet die Aufrufe von _AddRef und _Release an ein VCLComObject weiter; das wird vermutlich nur für COM-Controls verwendet.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Socke
 
Beiträge: 2546
Registriert: 22. Jul 2008, 18:27
Wohnort: Köln
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 8.1/Debian GNU/Linux/Raspbian/openSUSE | 
CPU-Target: 32bit x86 armhf
Nach oben

• Themenende •

Zurück zu Lazarus - Bugs



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 3 Gäste

porpoises-institution
accuracy-worried