Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Division durch Null ... externe Exception behandeln

35 views
Skip to first unread message

Ole Jansen

unread,
Mar 11, 2013, 11:51:05 AM3/11/13
to
Moin Moin,

unter Delphi 6 stehe ich vor folgendem Problem:

- es wird ᅵber eine Import-Unit eine externe Funktion in einer DLL
aufgerufen, die einen kleinen Dialog zeigt.
(Die DLL mit dem Dialog ist closed source.)

- Auf diesem Dialog gibt es einen Bug. Wenn ein bestimmter Reiter
gewᅵhlt wird gibt es eine "Gleitkommadivision durch Null"
Exception.
Der selbe Dialog macht keine sichtbaren Probleme wenn er direkt von
C++ aus aufgerufen wird.

Nun zu dem Teil, wo ich nicht weiter komme:

- Wenn ich das mein Programm unter dem IDE Debugger ausfᅵhre und
bei den Debugger Optionen die Gleitkomma Exception $C000008E
auf "Behandelt starten" setze funktioniert der Dialog
anstandslos (so wie bei C++)

- Wenn ich die EXE ohne Debugger ausfᅵhre bleibt der modale Dialog
an der Stelle hᅵngen und das Programm wird unbedienbar.
Die Behandlung der Exception findet anscheinend nicht statt,
auch wenn ich das Programm mit allem mᅵglichen Debugfunktionen,
Bereichsᅵberprᅵfung usw. kompiliere.

Hat jemand einen Tip wie ich das eventuell doch noch
geregelt bekomme?
(Eigener Exception handler in meinem Hauptprogramm? Andere Ideen?
gibt es irgendwelche Compilerschalter? Import-Unit ᅵberprᅵfen?)

viele Grᅵᅵe,

O.J.



Peter

unread,
Mar 11, 2013, 2:13:02 PM3/11/13
to
Ole Jansen wrote:

> Moin Moin,
>
> unter Delphi 6 stehe ich vor folgendem Problem:
>
> - es wird ᅵber eine Import-Unit eine externe Funktion in einer DLL
> aufgerufen, die einen kleinen Dialog zeigt.
> (Die DLL mit dem Dialog ist closed source.)
>
> - Auf diesem Dialog gibt es einen Bug. Wenn ein bestimmter Reiter
> gewᅵhlt wird gibt es eine "Gleitkommadivision durch Null"
> Exception.
> Der selbe Dialog macht keine sichtbaren Probleme wenn er direkt von
> C++ aus aufgerufen wird.

Das liegt mit Sicherheit an verschiedenen Settings des
FPU-Controlwords. Man kann damit FPU-Exceptions maskieren (was im
Prinzip normalerweise eine schlechte Idee ist) und die DLL scheint zu
erwarten, dass die Host-Application das macht. Die verwendeten Defaults
hᅵngen vom Compiler ab, der zum Erzeugen der Host-Applikation verwendet
wird.

Geh mal nach www.codenewsfast.com und suche nach Set8087CW, das sollte
massenhaft Posts zu ᅵhnlichen Problemen geben. Du muᅵt vermutlich nur
vor Aufruf der DLL-Funktion die Exception-Mask so setzen, wie die DLL
das erwartet und nach dem Aufruf wieder zurᅵck. Sowas wie

Set8087CW(Default8087CW or $3f); // nicht sicher ob das richtig ist
...DLL aufruf
ClearFPUInterrupts;
Set8087CW(Default8087CW);


procedure ClearFPUInterrupts;
// Clear any pending interrupts.
asm
FNCLEX
end;



--
Peter Below

Stefan Graf

unread,
Mar 11, 2013, 2:12:12 PM3/11/13
to
try
dll aufrufen ();
except
end;

Das geht nicht?

--
Stefan Graf

Ole Jansen

unread,
Mar 12, 2013, 5:18:26 AM3/12/13
to
Moin Peter,

Am 11.03.2013 19:13, schrieb Peter:
> Das liegt mit Sicherheit an verschiedenen Settings des
> FPU-Controlwords. Man kann damit FPU-Exceptions maskieren (was im
> Prinzip normalerweise eine schlechte Idee ist) und die DLL scheint zu
> erwarten, dass die Host-Application das macht. Die verwendeten Defaults
> hᅵngen vom Compiler ab, der zum Erzeugen der Host-Applikation verwendet
> wird.

Ja, Volltreffer.
>
> Geh mal nach www.codenewsfast.com und suche nach Set8087CW, das sollte
> massenhaft Posts zu ᅵhnlichen Problemen geben. Du muᅵt vermutlich nur
> vor Aufruf der DLL-Funktion die Exception-Mask so setzen, wie die DLL
> das erwartet...

Ich habe mal spasseshalber selbst eine DLL geschrieben, die mir
anzeigt, mit welcher Exception-Mask der C++ Demo Code des Herstellers
DLLs aufruft. Der verwendet $133F (alles maskieren... mhh)

Nur neugierig: Muss / darf das bei WHQL zertifizierter Software
denn so sein? In der Doku steht dazu nichts.

Danke nochmal fᅵr die Hilfe!

O.J.

Ole Jansen

unread,
Mar 12, 2013, 5:20:19 AM3/12/13
to
Moin Stefan

Am 11.03.2013 19:12, schrieb Stefan Graf:
> try
> dll aufrufen ();
> except
> end;
>
> Das geht nicht?
>

Negativ.
Das führt dazu, dass der Message Ballon mit der Meldung weg bleibt,
aber der Dialog friert weiterhin ein.

O.J.

Soeren Muehlbauer

unread,
Mar 12, 2013, 5:44:05 AM3/12/13
to
Hi,

> Ich habe mal spasseshalber selbst eine DLL geschrieben, die mir
> anzeigt, mit welcher Exception-Mask der C++ Demo Code des Herstellers
> DLLs aufruft. Der verwendet $133F (alles maskieren... mhh)

Nahezu alle von Microsoft verᅵffentlichte DLL's gehen davon aus, dass
die Exceptions maskiert werden. Manche von denen setzen das dann beim
Laden auch um. Wir haben hier auch ein mit Delphi entwickeltes Programm,
welches WPF Inhalte hostet. Dort haben wir auch dieses Problem gehabt.

> Nur neugierig: Muss / darf das bei WHQL zertifizierter Software
> denn so sein? In der Doku steht dazu nichts.

Ich glaube dazu gibt es keine Vorgabe. Wᅵre auch nicht in Ordnung. Deine
Anwendung muss dafᅵr Sorge tragen, dass es mit allen von ihr geladenen
Modulen korrekt funktioniert. BTW, fᅵr eine DLL gibt es auch IIRC keine
WHQL Zertifizierung.

Sᅵren.

Hans-Peter Diettrich

unread,
Mar 12, 2013, 6:00:16 AM3/12/13
to
Ole Jansen schrieb:
> Moin Moin,
>
> unter Delphi 6 stehe ich vor folgendem Problem:
>
> - es wird ᅵber eine Import-Unit eine externe Funktion in einer DLL
> aufgerufen, die einen kleinen Dialog zeigt.
> (Die DLL mit dem Dialog ist closed source.)
>
> - Auf diesem Dialog gibt es einen Bug. Wenn ein bestimmter Reiter
> gewᅵhlt wird gibt es eine "Gleitkommadivision durch Null"
> Exception.
> Der selbe Dialog macht keine sichtbaren Probleme wenn er direkt von
> C++ aus aufgerufen wird.

Verkᅵufer fragen.

> Nun zu dem Teil, wo ich nicht weiter komme:
>
> - Wenn ich das mein Programm unter dem IDE Debugger ausfᅵhre und
> bei den Debugger Optionen die Gleitkomma Exception $C000008E
> auf "Behandelt starten" setze funktioniert der Dialog
> anstandslos (so wie bei C++)
>
> - Wenn ich die EXE ohne Debugger ausfᅵhre bleibt der modale Dialog
> an der Stelle hᅵngen und das Programm wird unbedienbar.
> Die Behandlung der Exception findet anscheinend nicht statt,
> auch wenn ich das Programm mit allem mᅵglichen Debugfunktionen,
> Bereichsᅵberprᅵfung usw. kompiliere.

Die Debug-Optionen sind nur wirksam, wenn das Programm mit Debugger
lᅵuft, nicht wenn es direkt gestartet wird.

> Hat jemand einen Tip wie ich das eventuell doch noch
> geregelt bekomme?
> (Eigener Exception handler in meinem Hauptprogramm? Andere Ideen?
> gibt es irgendwelche Compilerschalter? Import-Unit ᅵberprᅵfen?)

So wie ich das sehe wird die Exception in der DLL nicht behandelt, wie
das eigentlich der Fall sein sollte, und Application kommt damit auch
nicht zurecht, sonst wᅵrde die Standard-Behandlung mit einer MessageBox
auftauchen.

Da es sich um eine Gleitkomma-Exception handelt, kᅵnnte es helfen, das
FPU Kontrollwort zumindest wᅵhrend des Aufrufs so zu ᅵndern, daᅵ eine
Division durch Null keine Exception auslᅵst. Wie das in Delphi genau
heiᅵt, und welches Flag darin wie gesetzt werden muᅵ, kann ich aus dem
Kopf nicht sagen.

DoDi

Hans-Peter Diettrich

unread,
Mar 12, 2013, 6:10:37 AM3/12/13
to
Ole Jansen schrieb:

> Ich habe mal spasseshalber selbst eine DLL geschrieben, die mir
> anzeigt, mit welcher Exception-Mask der C++ Demo Code des Herstellers
> DLLs aufruft. Der verwendet $133F (alles maskieren... mhh)
>
> Nur neugierig: Muss / darf das bei WHQL zertifizierter Software
> denn so sein? In der Doku steht dazu nichts.

Da sieht man mal wieder, wie hilfreich die Zertifizierung von Software,
Bio-Eiern etc. ist :-]

DoDi

Stefan Graf

unread,
Mar 12, 2013, 2:40:37 PM3/12/13
to
Dann ist es eindeutig die FPU-Thematik, das wurde ja schon erwähnt. Gibt
inzwischen leider auch schon bei Drucktreibern bzw. deren
Einstellungs-Dialogen.

--
Stefan Graf
0 new messages