AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Verhalten von TFileStream/TBufferedFileStream bei Crash
Thema durchsuchen
Ansicht
Themen-Optionen

Verhalten von TFileStream/TBufferedFileStream bei Crash

Ein Thema von Rollo62 · begonnen am 26. Mai 2020 · letzter Beitrag vom 26. Mai 2020
Antwort Antwort
Rollo62
Online

Registriert seit: 15. Mär 2007
4.116 Beiträge
 
Delphi 12 Athens
 
#1

Verhalten von TFileStream/TBufferedFileStream bei Crash

  Alt 26. Mai 2020, 11:15
Delphi-Version: 10.3 Rio
Hallo zusammen,

ich möchte Log-Files bei Crash aufnehmen, und damit möglichst nah an den Crash-Punkt herankommen.
Das Ganze sollte auch auf allen Platformen laufen, aber mir geht es erstmal um eine grundsätzliche Frage.

Die Klassen hängen wie folgt zusammen:
Delphi-Quellcode:
TStream = class(TObject);
//<-- TStream hat kein explizites Destroy

THandleStream = class(TStream)
  protected
    FHandle: THandle;
//<-- hat kein explizites Destroy, hält nur den Handle

TFileStream = class(THandleStream)
destructor TFileStream.Destroy;
begin
  if FHandle <> INVALID_HANDLE_VALUE then
    FileClose(FHandle);
  inherited Destroy;
end;
//<-- Handle wird hier entsorgt und womöglich erst jetzt in ein physikalisches File geschrieben

TBufferedFileStream = class(TFileStream)
destructor TBufferedFileStream.Destroy;
begin
  SyncBuffer(False); //<-- Der Memory-Buffer wird in das File geschrieben
  FreeMem(FBuffer, FBufferSize);
  inherited Destroy;
end;
//<-- Buffer wird erst geschrieben, und dann mit inhertied in ein physikalisches File geschrieben
Zum Logging halte ich jetzt einen globalen TFileStream offen, in dem die Logs geschrieben werden.

TFileStream
Wenn jetzt irgendwo ein Crash auftritt, wie verhält sich das noch offene File ?
Wer ruft TFileStream.Destroy auf, ist sichergestellt das sich alle Scopes korrekt abbauen ?
Ist es irgenwie garantiert (Delphi/jeweiliges OS) dass das offene File-Handle trotz Crash geschlossen wird ?
Wie verhält sich der OS-Cache in einem solchen Fall, gehen die Daten im Cache verloren (Unterschiede Win/iOS/Android/Mac ...) ?
Kann es sein dass das physikalische File im System offen bleibt (Unterschiede Win/iOS/Android/Mac ...) ?

TBufferedFileStream
Wenn ich jetzt statt TFileStream TBufferedFileStream benutze:
Es kommt noch das FlushBuffer in die Ablaufkette hinzu.
Wird das TBufferedFileStream.Destroy garantiert aufgerufen, oder kann der Buffer verlorengehen ?

Meine Vermutung ist das es sowohl bei TFileStream als auch TBufferedFileStream Datenverluste geben kann, und der letzte Stand verloren gehen kann.
Gibt es vielleicht einen versteckten Mechanismus (Exception-Handler) in Delphi, der den Datenverlust verhindern könnte.

Ist es jetzt besser TFileStream oder TBufferedFileStream für das Loggen zu Verwenden ?

Sorry, viele Fragen, aber vielleicht gibt es ja eine einfache Antwort
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.070 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Verhalten von TFileStream/TBufferedFileStream bei Crash

  Alt 26. Mai 2020, 12:27
Läuft denn das Logging im gleichen Thread, der dann hängen bleibt/abstürzt?

Ein mir bekanntes Vorgehen ist bspw. das Logging über eine Queue in einen eigenen Thread zu machen.
Da könntest du zum Beispiel explizit FlushBuffer aufrufen, wenn alle anstehenden Log-Meldungen im BufferedFileStream sind.
Wenn der VCL-Mainthread dann hängen bleibt, hat man zumindest noch die letzten Logmeldungen weggeschrieben.
  Mit Zitat antworten Zitat
Rollo62
Online

Registriert seit: 15. Mär 2007
4.116 Beiträge
 
Delphi 12 Athens
 
#3

AW: Verhalten von TFileStream/TBufferedFileStream bei Crash

  Alt 26. Mai 2020, 13:00
Läuft denn das Logging im gleichen Thread, der dann hängen bleibt/abstürzt?
Nein, es ist ganz allgemein ein systemweites Logging, es kann im MainThread oder in einem speziellen Thread damit loggen.
Der Zugriff darauf kann natürlich durch CS abgesichert werden, und sollte nicht das Problem sein.

Es könnte wohl ein globaler Exception-Handler eingebaut werden, um das abzusichern.
 Application.OnException := MyExceptionHandler; Aber die Frage ist was passiert eigentlich wenn der eben nicht da ist.
Schliesst Delphi in seinem Exception-Handler alle offenen Files, oder macht dass das OS nach Beenden einer App ?

Worauf kann man sich verlassen, und worauf nicht ?
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.070 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: Verhalten von TFileStream/TBufferedFileStream bei Crash

  Alt 26. Mai 2020, 13:36
Die Applikation (Mainthread) kann ja einfach so hängen bleiben, ohne das eine Exception aufgetreten ist.
  Mit Zitat antworten Zitat
Rollo62
Online

Registriert seit: 15. Mär 2007
4.116 Beiträge
 
Delphi 12 Athens
 
#5

AW: Verhalten von TFileStream/TBufferedFileStream bei Crash

  Alt 26. Mai 2020, 14:34
Ok, wenn aber eine Exception kommt wird dann aufgeräumt ?

Es geht hier mehr um iOS, ist aber generell die Frage wie Exception mit offenen Files umgehen.
Natürlich gibt es auch verschiedene Exceptions (Div0, Speicherfehler, AV, ...), ich denke mache sind kritisch für das File-Sichern, manche nicht.
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.070 Beiträge
 
Delphi 10.4 Sydney
 
#6

AW: Verhalten von TFileStream/TBufferedFileStream bei Crash

  Alt 26. Mai 2020, 15:50
Schliesst Delphi in seinem Exception-Handler alle offenen Files, oder macht dass das OS nach Beenden einer App ?
Es geht hier mehr um iOS, ist aber generell die Frage wie Exception mit offenen Files umgehen.
Ich kann nicht für iOS sprechen, in Windows ist halt so, dass alle Handles und etc. freigegeben werden, wenn der Prozess terminiert ist.
Wird wohl da so ähnlich sein.

Das von dir gewünschte Verhalten musst du selber implementieren, dass heißt im TApplication.OnException selber dafür sorgen, dass deine Logging-Komponente sauber verarbeitet und ggf. beendet wird. Es gibt kein Automatismus.
Wobei grundsätzlich etwas schief läuft, wenn so Sachen wie Div0-Exceptions bis soweit oben hochbubbeln.

Wirklich sicher bist du nur mit einer abgesetzten Lösung (siehe oben), weil Anwendungskritische Vorfälle auch ohne Exceptions auftreten können (Deadlock, Endlosschleifen, hartes Terminieren durch das Betriebssystem).
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#7

AW: Verhalten von TFileStream/TBufferedFileStream bei Crash

  Alt 26. Mai 2020, 16:02
Bei TFileStream kann nichts verloren gehen, selbst wenn man vergisst das Streamobjekt freizugeben.
Es wurden ja bereits alle Schreibvorgänge ausgeführt und warten vielleicht noch im WindowsFileCache, bis es auf der Platte landet.
Spätestens wenn das Programm dann beendet wird, schließt Windows das FileHandle und die Datei ist entgültig zu
Und so lange nicht das komplette Windows abstürzt, wird auch irgendwann das noch auf die Platte geschrieben, was noch im FileCache hing.

Beim TBufferedFileStream ist es wie mit dem guten alten Delphi-Referenz durchsuchenAssignFile+Rewrite auf einer Delphi-Referenz durchsuchenText/TextFile, wenn dort das CloseFile fehlt oder das Programm abstürzt, dann sind die Daten weg, welche noch im Buffer des Delphi (TTextRec.Buffer) warteten.
$2B or not $2B
  Mit Zitat antworten Zitat
Rollo62
Online

Registriert seit: 15. Mär 2007
4.116 Beiträge
 
Delphi 12 Athens
 
#8

AW: Verhalten von TFileStream/TBufferedFileStream bei Crash

  Alt 26. Mai 2020, 16:47
Zitat:
... in Windows ist halt so, dass alle Handles und etc. freigegeben werden, wenn der Prozess terminiert ist.
Wird wohl da so ähnlich sein.
Das wäre ja das gewünschte Verhalten

Ich versuche im Moment mit einem class destruktor zu Testen,
der sollte so einigermaßen am Schluss gefeuert werden (hoffentlich auch beim Crash).

Delphi-Quellcode:
class destructor TLog_Base.Destroy;
begin
    DestroyFileBuffer;
end;

class procedure TLog_Base.DestroyFileBuffer;
begin
    if Assigned( FFileStream ) then
    begin
        SendViaFile( '<==== FILE BUFFER DESTROYED' );

        FFileStream.FlushBuffer;

        FFileStream.Free;
    end;
end;
Sehe ich das '<==== FILE BUFFER DESTROYED' im Log hats funktioniert.
So weiss ich wenigstens ob ich bis zum ende gelogged habe.

Geändert von Rollo62 (26. Mai 2020 um 16:49 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#9

AW: Verhalten von TFileStream/TBufferedFileStream bei Crash

  Alt 26. Mai 2020, 18:01
Wenn das Programm hängen bleibt und vom System oder Taskmanager abgeschossen wird (TerminateProcess), weil es nicht mehr reagiert, dann wird dieser Code nicht ausgeführt.

Knalles es im Programm, aber es kann sich noch "ordentlich" beenden, dann ja.
$2B or not $2B
  Mit Zitat antworten Zitat
mytbo

Registriert seit: 8. Jan 2007
472 Beiträge
 
#10

AW: Verhalten von TFileStream/TBufferedFileStream bei Crash

  Alt 26. Mai 2020, 18:39
In der mORMot Library Unit SynLog.pas findest du umfangreiche Funktionen zum Loggen. Vielleicht kannst du in der Unit für dein eigenes Logging einige Anregungen finden. Die ausführliche Hilfe ist hier:
https://synopse.info/files/html/Syno...8.html#TITL_16

Bis bald...
Thomas
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:47 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