Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Nicht behandelte Exception in DLL zentral behandeln (https://www.delphipraxis.net/182747-nicht-behandelte-exception-dll-zentral-behandeln.html)

Bernhard Geyer 14. Nov 2014 13:39

Delphi-Version: 6

Nicht behandelte Exception in DLL zentral behandeln
 
Ich habe hier den Fall das ein Exe mit anderen Delphi-Version als eine verwendet DLL compiliert wurde.
Hier bekomme ich bei unbehandelten Exception keine vernünftige Meldung sondern ein "Fehler an Adresse xxx" da Delphi hier bei einer Exception an Windows ein entsprechendes Record übergibt und ein Element davon ein TObject ist.
Und da ja D6.TObject != XE6.TObject ist kracht es da hier wenn die Exception XE6 erzeugt wurde und in D6 versucht wird zu behandeln.

Was brauche ich:

Welche Möglichkeiten gibt es hier einzugreifen das ich bei Auftreten einer Exception erkenne ob es ein try...except/finally gibt oder ob die Exception komplett nach oben "durchläuft". Und im Fall das es kein try...except/finally gibt diese über ein DLL-Schnittstellenmethode an die Exe weitergeben kann?

Sir Rufo 14. Nov 2014 13:49

AW: Nicht behandelte Exception in DLL zentral behandeln
 
Ganz einfach:

Man reicht einfach keine Exceptions über die DLL-Grenzen hinaus. Es gibt Rückgabewerte und die Rückgabewerte können geprüft werden. Zusätzlich kann es noch etwas wie MSDN-Library durchsuchenGetLastError geben.

Die
Delphi-Quellcode:
Exception
selber wirft dann die Anwendung, die die DLL benutzt (z.B. so wie Delphi-Referenz durchsuchenRaiseLastOSError)

Bernhard Geyer 14. Nov 2014 14:31

AW: Nicht behandelte Exception in DLL zentral behandeln
 
Zitat:

Zitat von Sir Rufo (Beitrag 1279828)
Ganz einfach:

Man reicht einfach keine Exceptions über die DLL-Grenzen hinaus. Es gibt Rückgabewerte und die Rückgabewerte können geprüft werden. Zusätzlich kann es noch etwas wie MSDN-Library durchsuchenGetLastError geben.

Die
Delphi-Quellcode:
Exception
selber wirft dann die Anwendung, die die DLL benutzt (z.B. so wie Delphi-Referenz durchsuchenRaiseLastOSError)

Der "normale" läuft ja über Rückgabecodes. Jedoch wurde bei der Schnittstelle das Exceptionhandling vollkommen außer acht gelassen.
Das jetzt nachzubauen (Tritt ja erst auf nachdem wir XE6 verwenden statt bisher D6, Alles auf einen Schlag umstellen geht auch nicht) würde Wochen dauern. Hier muss ein Lösung her die das auf über Hooking oder ähnliches direkt löst.

Wenn jetzt die Exception im D6-Teil erzeugt wird erkennt ja die XE6-Verison das es sich um eine Delphi-Exception handelt. (System._HandleAnyException). Es kracht dann beim Zugriff auf den RaiseListPtr (System.ExceptObject).

Meine Idee wäre jetzt auf dieser Ebene (Vermutlich würde Hooking von TApplication.HandleException reichen) und eine Erkennung einzubauen ob das Exception-Objekt wirklich ein D6.TObject ist. Falls nein dann die Plugins fragen ob dieses Objekt von ihnen kommt und dann über die DLL-Schnittstelle den Exception-Text abfragen.

himitsu 14. Nov 2014 15:49

AW: Nicht behandelte Exception in DLL zentral behandeln
 
Die Exceptionbehandlung ist in der System.pas geht absichtlich auf Pointer und nicht TObject oder gar auf Exception.
In Delphi sind zwar alle Exceptions von Exception abgeleitet, aber dann getrennter RTTI hat die DLL eigene Versionen von TObject/Exception, welche grundsätlich nicht kompatibel mit der EXE sind, vorallem nicht wenn es sich um unterschiedliche Compiler handelt.
Delphi Version X, Delphi Version Y, C++Builder, C++, Free Pascal oder sonstwas.

In der EXE kommt also eine "Exception" an, aber sie wird nicht als Delphi-Exception-Klasse erkannt.
Man könnte jetzt natürlich in der EXE diese Exception behandeln und über blinde Casts oder Zeigergefummele den Klassennamen und die Message auslesen, aber besser ist es das in der DLL zu behandeln und auf anderen Wege (z.B. Fehlercodes) rauszugeben.

Zitat:

Meine Idee wäre jetzt auf dieser Ebene (Vermutlich würde Hooking von TApplication.HandleException reichen) und eine Erkennung einzubauen ob das Exception-Objekt wirklich ein D6.TObject ist. Falls nein dann die Plugins fragen ob dieses Objekt von ihnen kommt und dann über die DLL-Schnittstelle den Exception-Text abfragen.
Könnte man machen, indem man den Speicher analysiert, wichtige Daten ausliest und dann entweder selber die Exception behandelt, oder aus diesen Daten ein neues Exception-Objekt erstellt, welches weitergegeben wird.



Alternativ linkt man halt DLL und EXE gegen die RTL und schon kann man die Exceptions problemlos rausgeben.

Bernhard Geyer 14. Nov 2014 15:53

AW: Nicht behandelte Exception in DLL zentral behandeln
 
Zitat:

Zitat von himitsu (Beitrag 1279848)
In der EXE kommt also eine "Exception" an, aber sie wird nicht als Delphi-Exception-Klasse erkannt.

Eben doch. Sie wir als Dephi-Exception erkannt obwohl sie nicht ausgewertet werden kann.
Liegt an der Magic-Number die hier Delphi verwendet und nicht zwischen den Delphi-Versionen geändert wurde.

Zitat:

Zitat von himitsu (Beitrag 1279848)
Man könnte jetzt natürlich in der EXE diese Exception behandeln und über blinde Casts oder Zeigergefummele den Klassennamen und die Message auslesen, aber besser ist es das in der DLL zu behandeln und auf anderen Wege (z.B. Fehlercodes) rauszugeben.

Mir reicht es ja zu erkennen das es eine Nicht-Kompatible Delphi-Exception ist und dann über selbst entwickeltes DLL-API den Typ+Text rauszukommen.


Zitat:

Zitat von himitsu (Beitrag 1279848)
Alternativ linkt man halt DLL und EXE gegen die RTL und schon kann man die Exceptions problemlos rausgeben.

Diese Alternative gibt es hier nicht. Wir verwenden Absichtlich keine BPL's

Der schöne Günther 20. Jan 2015 14:22

AW: Nicht behandelte Exception in DLL zentral behandeln
 
Rein interessenshalber: Wie hat es sich letztendlich ergeben, wie habt ihr das Problem gelöst?

Bernhard Geyer 20. Jan 2015 14:29

AW: Nicht behandelte Exception in DLL zentral behandeln
 
Bisher gar nicht.

Dejan Vu 20. Jan 2015 15:04

AW: Nicht behandelte Exception in DLL zentral behandeln
 
Und wenn du eine Wrapper-DLL schreibst Und dort den inkompatiblen Fehler abfängst?
Soweit ich das jetzt verstanden habe, nervt dich nur, das die Exception nicht auswertbar ist. Wenn Du sie aber abfangen kannst, dann kapsele das invalide Exception-Objekt in einer 'EIncompatibleDelphiException' Exception und später kannst Du ja probieren, ob Du den Typ/Klasse nicht doch rausbekommst.


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