SIGSEV in inherited --> TObject.destroy

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
MitjaStachowiak
Lazarusforum e. V.
Beiträge: 395
Registriert: Sa 15. Mai 2010, 13:46
CPU-Target: 64 bit
Kontaktdaten:

SIGSEV in inherited --> TObject.destroy

Beitrag von MitjaStachowiak »

Hallo,
ich brauche mal ein paar Tipps. Also ich suche schon seit Tagen nach einem Fehler in diesem Projekt: https://mitjastachowiak.de/?/projects/s ... index.html
Manchmal (bei ~1/20 Versuchen), wenn man ein neues Bild öffnet, gibt es einen SIGSEV. Ich habe also eine Log-Unit geschrieben, die Log-Befehle direkt in eine Datei schreibt und den Fehler bis in das Destroy des alten Bildes zurückverfolgt. Das Komische: er tritt nicht immer an der gleichen Stelle auf :shock:
Eben war es in folgendem Code:

Code: Alles auswählen

destructor TImgdata.Destroy;
begin
  if assigned(ExifObj) then begin
    Log('  ExifObj Free...');
    ExifObj.free;
  end;
 
  if assigned(IptcObj) then begin
    Log('  IPTCObj Free...');
    IptcObj.free;
  end;
  Log('  start TImgData.Destroy:inherited');    // letzter Eintrag im Log, TImgData erbt von tEndInd; tEndInd hat keinen Destruktor und erbt von nichts
  inherited;  // TObject.destroy
  Log('  finished TImgData.Destroy:inherited');
end;
Bei allen Fehlern lande ich im Assembler-Fenster in TObject.Destroy/TObject.Free (nach dem Aufruf von inherited in einem destruktor) :

Code: Alles auswählen

SYSTEM$_$TOBJECT_$__$$_DESTROY 
0040D130 53                       push   %ebx
0040D131 56                       push   %esi
0040D132 89c3                     mov    %eax,%ebx
0040D134 89d6                     mov    %edx,%esi
0040D136 85f6                     test   %esi,%esi
0040D138 7e07                     jle    0x40d141 <SYSTEM$_$TOBJECT_$__$$_DESTROY+17>
0040D13A 89d8                     mov    %ebx,%eax
0040D13C 8b13                     mov    (%ebx),%edx
0040D13E ff5248                   call   *0x48(%edx)
0040D141 85db                     test   %ebx,%ebx
0040D143 740b                     je     0x40d150 <SYSTEM$_$TOBJECT_$__$$_DESTROY+32>
0040D145 85f6                     test   %esi,%esi
0040D147 7407                     je     0x40d150 <SYSTEM$_$TOBJECT_$__$$_DESTROY+32>
0040D149 89d8                     mov    %ebx,%eax
0040D14B 8b13                     mov    (%ebx),%edx
0040D14D ff5238                   call   *0x38(%edx)
0040D150 5e                       pop    %esi
0040D151 5b                       pop    %ebx
0040D152 c3                       ret    
0040D153 0000                     add    %al,(%eax)
0040D155 0000                     add    %al,(%eax)
0040D157 0000                     add    %al,(%eax)
0040D159 0000                     add    %al,(%eax)
0040D15B 0000                     add    %al,(%eax)
0040D15D 0000                     add    %al,(%eax)
0040D15F 00                       add    %cl,0x74c985c1(%ecx)
SYSTEM$_$TOBJECT_$__$$_FREE 
0040D160 89c1                     mov    %eax,%ecx
0040D162 85c9                     test   %ecx,%ecx
0040D164 740c                     je     0x40d172 <SYSTEM$_$TOBJECT_$__$$_FREE+18>
0040D166 89c8                     mov    %ecx,%eax
0040D168 ba01000000               mov    $0x1,%edx
0040D16D 8b09                     mov    (%ecx),%ecx
0040D16F ff5130                   call   *0x30(%ecx)
 
Ich lasse das Ganze im Debug mit allen Überprüfungen laufen - sonst scheint alles OK. Was kann diesen Fehler verursachen? Wie kann ich weiter danach suchen?

wp_xyz
Beiträge: 5134
Registriert: Fr 8. Apr 2011, 09:01

Re: SIGSEV in inherited --> TObject.destroy

Beitrag von wp_xyz »

Ich hatte in http://www.lazarusforum.de/viewtopic.ph ... 884#p86884 ein Speicherleck von dEXIF erwähnt. Vielleicht hängt das damit zusammen? Hast du HeapTrc aktiviert, um das Speicherleck zu finden?

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: SIGSEV in inherited --> TObject.destroy

Beitrag von Michl »

Ich habe das Programm mal runtergeladen, gestartet (zuvor Startparameter angepasst) und verschiedene Bilder geladen (angeklickt unterhalb Aktuelle Slideshow). Egal, wieviele Bilder ich nacheinander wähle, einen SIGSEGV bekomme ich nicht (mehrfach getestet Laz 1.6 und 1.7 Trunk). Heaptrc ist an, ein Speicherleck kann ich hier nicht sehen.

Tritt der SIGSEGV nur bei bestimmten Bildern auf?

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

MitjaStachowiak
Lazarusforum e. V.
Beiträge: 395
Registriert: Sa 15. Mai 2010, 13:46
CPU-Target: 64 bit
Kontaktdaten:

Re: SIGSEV in inherited --> TObject.destroy

Beitrag von MitjaStachowiak »

@wp_xyz: Ich habe dEXIF zu großen Teilen überarbeitet, um auch EXIF-Tags mit variabler Länge schreiben zu können. Musste dafür den halben EXIF-Standard implementieren (Der ist ziemlich buggy :roll: ) Naja, jedenfalls habe ich dabei auch irgend ein Speicherleck gestopft, aber solche Speicherlecks führen ja nicht zu Exceptions und es tritt auch nicht unbedingt in dEXIF auf. Ich hatte schon öfter mal Exceptions beim Freigeben von Objekten. Meistens weil irgend ein Objekt schon vorher freigegeben oder nie initialisiert wurde, auch Free und Destroy verwechselt aber dieses mal...

@Michl: Erstmal tausend Dank für's Testen 8)
Es tritt bei mir sehr willkürlich auf. Es gibt kein Bild, bei dem es garantiert passiert; habe auch schon Slideshows mit 40 Bildern erstellt, ohne Fehler, ein andermal schmiert es bei jedem fünften Bild ab. Ich habe das Gefühl, dass wenn man über 5 Bilder durch hat, man irgendwie über'n Berg ist und das Fehler danach noch viel seltener auftritt. Ich habe nicht den Eindruck, dass es an bestimmten Bildern liegt. Ob man ein Bild gespeichert haben muss (mit oder ohne Änderungen), damit es abstürzt, habe ich noch nicht beobachtet; werde ich mal drauf achten/die relevanten Aktionen in's log packen. Ich habe Lazarus 1.6 - wie zieht man eigentlich die Trunk-Version für Windows? Ich hatte das früher mal geschafft, aber jetzt finde ich's irgendwie nicht mehr.

OK, wie's aussieht werde ich einen Weg finden müssen, den Fehler zuverlässig rekonstruieren zu können.

MitjaStachowiak
Lazarusforum e. V.
Beiträge: 395
Registriert: Sa 15. Mai 2010, 13:46
CPU-Target: 64 bit
Kontaktdaten:

Re: SIGSEV in inherited --> TObject.destroy

Beitrag von MitjaStachowiak »

Ich habe einen ersten Verdacht, was es sein könnte: Es gibt einen Fehler, wenn man versucht, im Onclick eines Buttons selbigen freizugeben. Meine Klasse erbt von TFrame, also auch GUI. Auch wenn das TFrame.Free von wo anders aufgerufen wird, könnte ich mir vorstellen, dass es deswegen einen Fehler gibt.
Jetzt teste ich dieses Workarround:

Code: Alles auswählen

 
type
  TEditCodec = class(TFrame)
   public
    procedure Free; reintroduce;
  end;
 
[...]
 
procedure TEditCodec.Free;
begin
 if (self = nil) then exit;
 Application.ReleaseComponent(self);
end;
Mal sehen, ob's das war :?:

wp_xyz
Beiträge: 5134
Registriert: Fr 8. Apr 2011, 09:01

Re: SIGSEV in inherited --> TObject.destroy

Beitrag von wp_xyz »

Es gibt einen Fehler, wenn man versucht, im Onclick eines Buttons selbigen freizugeben
Wenn der Button nach dem Ende des Eventhandler, in dem der Button zerstört wurde, wieder in seinen eigenen Code gelangt, aber die Instanz nicht mehr existiert, ist klar, dass das nicht gut gehen kann.
Wenn das TFrame.Free von wo anders aufgerufen wird, könnte ich mir vorstellen, dass es deswegen einen Fehler gibt.
Wieso denn? In dieser Allgemeinheit ist das sicher falsch, denn sonst könnte ein Formular nie eingefügte Frames zerstören. Oder ist das eine ähnliche Kontruktion wie oben, dass der Frame in einem seiner Events freigegeben wird? Wenn ja, dann hast du hier ein massives Problem in der Architektur deiner Units, Klassen und Abhängigkeiten. Ohne weitere Informationen kann ich dazu aber nicht mehr sagen.

MitjaStachowiak
Lazarusforum e. V.
Beiträge: 395
Registriert: Sa 15. Mai 2010, 13:46
CPU-Target: 64 bit
Kontaktdaten:

Re: SIGSEV in inherited --> TObject.destroy

Beitrag von MitjaStachowiak »

Das mit dem Button ist mir schon klar, ich erinnere mich aber, dass das auch so ein schwer auffindbarer Fehler beim Destroy war. Mein Frame wird in einem Event freigegeben, das zwar nicht vom Frame ausgeht, aber von einem Element, dass über Anker mit dem Frame verknüpft ist ... Ich glaube nicht, dass es das war, aber es ist jetzt eine ganze Weile nicht abgeschmiert. Mal sehen.

wp_xyz
Beiträge: 5134
Registriert: Fr 8. Apr 2011, 09:01

Re: SIGSEV in inherited --> TObject.destroy

Beitrag von wp_xyz »

Das mit dem Anchor wäre meiner Meinung nach denkbar, zumal hier erst vor kurzen noch einige Fehler behoben worden sind und gelegentlich immer noch Abstürze vorkommen. Allerdings konnte ich mit einem Edit und einem Button, der mit dem Edit verankert war und bei einem Click das Edit zerstört hat, keine Problem feststellen, auch nicht zurück bis Laz 1.44.

MitjaStachowiak
Lazarusforum e. V.
Beiträge: 395
Registriert: Sa 15. Mai 2010, 13:46
CPU-Target: 64 bit
Kontaktdaten:

Re: SIGSEV in inherited --> TObject.destroy

Beitrag von MitjaStachowiak »

Mir wäre es wichtig, dass Lazarus Werkzeuge zum Finden solcher Fehler bekommt - mit einem gelegentlichen SIGSEV irgendwo im inherited-Teil kann man einfach nichts anfangen. :idea:

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10: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

Re: SIGSEV in inherited --> TObject.destroy

Beitrag von mse »

Benutzt du heaptrace? Falls heaptrace nicht reicht ist Valgrind oft lebensrettend. Du wirst dich wundern was so alles nur per Zufall läuft in den Programmen. ;-)

MitjaStachowiak
Lazarusforum e. V.
Beiträge: 395
Registriert: Sa 15. Mai 2010, 13:46
CPU-Target: 64 bit
Kontaktdaten:

Re: SIGSEV in inherited --> TObject.destroy

Beitrag von MitjaStachowiak »

Heaptrace ja, Valgrind noch nicht. Werde ich mir bei Gelegenheit ansehen.

Antworten