Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Exception-Objekt in OnException auswerten (https://www.delphipraxis.net/116597-exception-objekt-onexception-auswerten.html)

taaktaak 2. Jul 2008 21:04


Exception-Objekt in OnException auswerten
 
Moin, Moin.

Ein kleines Problem:

Mein Programm verwendet eine mit ZLibEx V1.2.3 komprimierte Datei. Um das Fehlerverhalten zu testen, habe ich absichtlich die komprimierte Datei "beschädigt". Erwartungsgemäß kann sie nun nicht mehr dekomprimiert werden und in ZLibEx wird eine Exception ausgelöst - so soll es ja auch sein.

Aktiviere ich in den Debugger-Optionen die Auswahl "Bei Delphi-Exceptions stoppen" und starte das Programm, öffnet sich ein Fenster, in dem eine Exception der Klasse EZDecompressionError und der Meldung 'data error' gemeldet wird. Also genau die Informationen, die von ZLibEx abgeschickt werden.

Sehr gut. Nun möchte ich dieses natürlich durch meinen Programmcode auswerten lassen und eine individuelle Meldung anzeigen. Also deaktiviere ich die Option in den Debugger-Optionen und nutze im Code ApplicationEvents.OnException(). Da an dieser Stelle natürlich alle möglichen Exceptions ankommen können, muss ich natürlich prüfen, ob die Exception von der Unit ZLibEx kommt. Nun erwarte ich, dass das übergebene Exception-Objekt die notwendigen Informationen bereitstellt und ich (wie in der Debugger-Meldung) näheres erfahre. Aber diese Informationen kann ich nicht ermitteln - und das ist nun mein Problem:

Delphi-Quellcode:
procedure TfoMain.ApplicationEvents1Exception(Sender:TObject;E:Exception);
begin
  showmessage(e.ClassParent.ClassName); // >> Anzeige : EExternal
  showmessage(e.Message);               // >> Anzeige : Zugriffsverletzung ....
  showmessage(e.ClassName);             // >> Anzeige : EAccessViolation
end;
Die Informationen sind ja nicht schlecht, aber geben mir in dieser Form keine Auskunft, wer die Exception ausgelöst hat.
Wäre über einen Tip sehr dankbar.

Apollonius 2. Jul 2008 21:13

Re: Exception-Objekt in OnException auswerten
 
Ohne Debug-Informationen geht es natürlich nicht, und mit Debug-Information wirst du dein Programm wohl kaum ausliefern.

Bei Exceptions, die von EExternal abgeleitet sind, so auch EAccessViolation, erhältst du über den Windows-Exception-Record auch die Adresse, an der die Exception aufgetreten ist (Zugriffsverletzung an Adresse XYZ...).
Diese kannst du dann versuchen auszuwerten, allerdings können sich die Adressen der Routinen bei jeder Kompilierung ändern.
Außerdem kann es passieren, dass die eigentliche Exception in einer Hilfsroutine geworfen wird, die mit falschen Parametern aufgerufen wurde, zum Beispiel einer Methode mit nil als Self. Um da den Verursacher zu ermitteln, müsstest du einen Callstack erstellen.

taaktaak 2. Jul 2008 21:19

Re: Exception-Objekt in OnException auswerten
 
Danke für deine Antwort Apolonius :hi:
Tja, so etwas hatte ich schon befürchtet. Allerdings - auch wenn ich mit Debug-Informationen übersetzen, bekomme ich keine anderen Informationen. Dann ist es wohl das einfachste, den Quellcode von ZLibEx zu modifizieren. Alles andere ist mit meinen Programmierkenntnissen ohnehin nicht realisierbar.

// edit: Sorry -Apollonius- mit einem P !

Apollonius 2. Jul 2008 21:31

Re: Exception-Objekt in OnException auswerten
 
Wenn du jetzt noch das zweite L einfügst, ist es richtig. :wink:

Zitat:

Allerdings - auch wenn ich mit Debug-Informationen übersetzen, bekomme ich keine anderen Informationen.
Das meinte ich auch nicht. Du könntest dann aber versuchen, zur Laufzeit die Debug-Informationen auszulesen und den Routinennamen zu finden. Dass das alles andere als trivial wäre, sollte trotzdem klar sein.

Du brauchst ohne Debug-Informationen aber auch nicht gleich die Flinte ins Korn zu schmeißen. Du könntest folgendermaßen vorgehen: Die Startadresse einer Funktion erhältst du mit dem @-Operator. Wenn du nun eine grobe Abschätzung der Code-Länge in Byte addierst, erhältst du die Adresse des Funktionenendes (falls du die Reihenfolge der Funktionen in der .pas-Datei kennst, ist es noch einfacher - dann liegt das Ende der Funktion nämlich kurz vor dem Anfang der nächsten). Falls du einen Verdacht hast, welche Funktion genau der Störenfried ist, ist das schon recht nützlich. Andernfalls kannst du deine Schätzung noch etwas gröber machen, um eine ganze Unit zu fassen - ich glaube, dass der Linker Funktionen einer Unit immer nahe zueinander ablegt.
Dann prüfst du einfach, ob die Fehleradresse im gesuchten Bereich ist, und siehst, ob die Exception direkt in einer der gesuchten Funktionen geworfen wurde. Das Problem mit den Hilfsroutinen bleibt natürlich.

taaktaak 2. Jul 2008 21:42

Re: Exception-Objekt in OnException auswerten
 
Mann oh Mann, jooo, APOLLONIUS von Thyana - schwieriger Name!
Aber interessant, was WIKI über ihn schreibt.

Nun, es würde in der Tat genügen herauszufiltern, dass der Fehler in ZLibEx hervorgerufen wurde. In dem speziellen untersuchten Fall, trat er auch tatsächlich in dieser Unit und nicht in Hilfsroutinen innerhalb von SysUtils oder Classes auf. Ich werde versuchen deine Hinweise weiter zu verfolgen, wenn es wieder etwas kühler ist. Vielen Dank noch mal :hi:

marabu 2. Jul 2008 21:50

Re: Exception-Objekt in OnException auswerten
 
Hallo Ralph,

darf ich dir madExcept ans Herz legen?

Freundliche Grüße

mr2 2. Jul 2008 21:53

Re: Exception-Objekt in OnException auswerten
 
Warum denn so kompliziert?

Würde es

Delphi-Quellcode:
try
  DecompressBuf(... // oder irgendein anderer ZLib-Aufruf
except
  on E: EDecompressionError
  do begin
    E.Message = "Die Datei ist beschädigt!";
    raise;
  end;
end;
nicht auch tun?

mr2

taaktaak 3. Jul 2008 08:05

Re: Exception-Objekt in OnException auswerten
 
Moin, Moin.

Tja, ist schon bemerkenswert, wie man manchmal zielstrebig an der naheliegensten Lösung vorbeisteuert.

Die Lösung von mr2, es mit einem Try..Except-Block zu regeln, ist in diesem Fall tatsächlich eine ausreichende Lösungsmöglichkeit. Allerdings wird auch hier die Fehlerklasse EZDecompressionError nicht erkannt. Ist aber nicht so schlimm, da der Block ja gezielt die Dekompressionsprozedur einschließt.

Das madExcept schau ich mir mal an, danke für den Hinweis an marabu!

Wünsche allen noch einen schönen Tag!


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:17 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