Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi TCriticalSection.Enter - seltsames Verhalten (https://www.delphipraxis.net/193381-tcriticalsection-enter-seltsames-verhalten.html)

grl 23. Jul 2017 12:06

Delphi-Version: 7

TCriticalSection.Enter - seltsames Verhalten
 
Tag!

Bin wieder einmal dabei an einem alten D7 Projekt rumzufummeln.

Das Projekt ist multithreaded und verwendet CriticalSections zur synchronisation.

Für verschiedene Zwecke gibts da eine abgeleitete CriticalSection-Klasse die unter gewissen Umständen nicht blocken (und damit einen Deadlock erzeugen) soll sondern das Programm in einen kontrollierten Fehlerzustand bringen.

Diese Klasse (obwohl sehr einfach gestrickt) macht wohl Probleme. Habe sie daher für die Diagnose extrem vereinfacht und bin auf ein seltsames Verhalten draufgekommen.

Hier ist der Quellcode der Klasse (nicht wundern, daß das so aussieht als wäre es ziemlich sinnlos dafür eine eigene Ableitung zu machen - der ganze Kram, wegen dem es eine eigene Klasse wurde ist wegen der Fehlersuche entfernt)
Delphi-Quellcode:
unit uTestCriticalSection;

interface

uses SyncObjs;

type
  TTestCriticalSection=class(TCriticalSection)
  public
    function TryEnter:Boolean;
  end;

implementation

function TTestCriticalSection.TryEnter:Boolean;
begin
  Enter;
  Result:=True;
end;

end.
Im Programm gibts wird sie dann so eingesetzt:
Delphi-Quellcode:
var TestCS:=TTestCriticalSection;
//[...]
if not TestCS.TryEnter then begin
  Log('Could not enter CS - Error');
  //[ErrorHandling]
end;
Durch die extreme Verkürzung der Funktion TryEnter hätte ich erwartet, daß es entweder einen Deadlock geben muss (durch das Enter) oder die Funtion True zurückgeben muss. Die Zeile Log(...) und das Errorhandling dazu sollte eigentlich nie erreicht werden.
Trotzdem passiert das ab und zu.

Ich habe bereits geprüft, daß die TestCS.Klasse zum Zeitpunkt des Aufrufs auch korrekt initiert wurde. Es ist auch die Selbe TestCS für alle Teile des Programms die sie nutzen...

Warum gibt TryEnter also hier ab und zu False zurück? Steh ich hier nur auf der Leitung? Wirklich reproduzieren kann ich's leider nicht - nicht in der eigentlichen Applikation und schon gar nicht in dem Testprogramm das ich mir gebaut hab. Aber es tritt ab und zu auf - wie ich am Fehlerhandlich sehen kann

Jemand eine Idee?

Danke
Luggi

Uwe Raabe 23. Jul 2017 14:24

AW: TCriticalSection.Enter - seltsames Verhalten
 
Zitat:

Zitat von grl (Beitrag 1377279)
Wirklich reproduzieren kann ich's leider nicht - nicht in der eigentlichen Applikation und schon gar nicht in dem Testprogramm das ich mir gebaut hab. Aber es tritt ab und zu auf - wie ich am Fehlerhandlich sehen kann

Wenn du es nicht reproduzieren kannst, wie kannst du dir dann sicher sein, daß der gezeigte Code die Ursache ist? Hat wirklich diese abgespeckte Klasse diese Logs erzeugt?

jaenicke 23. Jul 2017 15:42

AW: TCriticalSection.Enter - seltsames Verhalten
 
Der Grund ist sehr einfach:
In Delphi 7 hatte TCriticalSection noch kein TryEnter, mittlerweile in neueren Versionen aber schon.

Deine Variable, in der du die Instanz gespeichert hast (hier TestCS), ist sicher vom Typ TCriticalSection. Deshalb wird in neueren Versionen die Methode TCriticalSection.TryEnter statt deiner Implementierung aufgerufen. Denn die Methode ist ja nicht überschrieben, weshalb deine Methode nur aufgerufen würde, wenn deine Variable auch deine abgeleitete Klasse als Typ hätte.

grl 23. Jul 2017 15:45

AW: TCriticalSection.Enter - seltsames Verhalten
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1377286)
Wenn du es nicht reproduzieren kannst, wie kannst du dir dann sicher sein, daß der gezeigte Code die Ursache ist? Hat wirklich diese abgespeckte Klasse diese Logs erzeugt?

Ja.
Um das Problem einzukreisen habe ich die im Projekt verwendete Klasse auf das hier gepostete Minimum reduziert.

Einzige Unterschiede zum Original:
Der Name der Klasse wurde geändert, weil im Original der Name des Kunden drinsteckt.
Die entfernten Codeteile sind nicht gelöscht sondern auskommentiert.

Sollte aber beides keinen Einfluss aufs Verhalten haben.

Gruß
Luggi

grl 23. Jul 2017 15:49

AW: TCriticalSection.Enter - seltsames Verhalten
 
Zitat:

Zitat von jaenicke (Beitrag 1377289)
Der Grund ist sehr einfach:
In Delphi 7 hatte TCriticalSection noch kein TryEnter, mittlerweile in neueren Versionen aber schon.

Deine Variable, in der du die Instanz gespeichert hast (hier TestCS), ist sicher vom Typ TCriticalSection. Deshalb wird in neueren Versionen die Methode TCriticalSection.TryEnter statt deiner Implementierung aufgerufen. Denn die Methode ist ja nicht überschrieben, weshalb deine Methode nur aufgerufen würde, wenn deine Variable auch deine abgeleitete Klasse als Typ hätte.

Naja....

Das Projekt wird immer noch mit Delphi 7 kompiliert wie in der Information zum Post angegeben (wie nennt man das, was man beim ersten Post angibt?)

Und nein, die Variable ist nicht TCriticalSection direkt, sondern vom Typ meiner Klasse - steht auch im Code (und ja, da ist ein = zuviel, Typo beim Übertragen hierher):
Zitat:

Zitat von grl (Beitrag 1377279)
Im Programm gibts wird sie dann so eingesetzt:
Delphi-Quellcode:
var TestCS:=TTestCriticalSection;
//[...]
if not TestCS.TryEnter then begin
  Log('Could not enter CS - Error');
  //[ErrorHandling]
end;

Ist der Grund dann immer noch einfach? Mir erschließt er sich nämlich nicht...

Luggi

jaenicke 23. Jul 2017 15:55

AW: TCriticalSection.Enter - seltsames Verhalten
 
Dann hatte ich das falsch verstanden. :oops:

Dann bleibt wohl nur in dem TryEnter selbst ein Log hinzuzufügen. Eine Idee habe ich bei dem Quelltext dann allerdings nicht wie das passieren kann.

Außer dem Standard für wirklich unerklärliche Probleme: Speicher überschrieben, Klasse schon freigegeben, ...
Aber ansonsten gibt es darauf ja keine uns bekannten Hinweise, insofern...

grl 23. Jul 2017 16:09

AW: TCriticalSection.Enter - seltsames Verhalten
 
Zitat:

Zitat von jaenicke (Beitrag 1377292)
Außer dem Standard für wirklich unerklärliche Probleme: Speicher überschrieben, Klasse schon freigegeben, ...
Aber ansonsten gibt es darauf ja keine uns bekannten Hinweise, insofern...

Ich bin ja schon froh, daß ich nicht der einzige bin, der bei diesen Ursachen landet...
Ich zweifle nämlich schon heftig an mir selbst...

Danke!
Luggi


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:04 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz