Ausnahmebehandlung: Unterschiedliches Verhalten in Runtime und Release
-
Hallo,
je nachdem, ob ich als Debug oder als Release kompiliere erhalte ich unterschiedliche Ergebnisse in Sachen Fehlerbehandlung:
void CBsp01Dlg::OnBtnExFile() { try { CFile fileNotOpen; fileNotOpen.SeekToBegin(); } catch(CFileException* e) // Dateiausnahmen abfangen (catch) { if (e->m_cause == CFileException::fileNotFound) AfxMessageBox("Vergessen Datei zu öffnen!"); e->Delete(); } }
In der Release-Version funktionier es wie erwartet, in der debug
kommt die Assertion box dazwischen, die kann ich wegklicken.
D.h., das funktioniert wie erwaret.Bei reinen "C-Fehlern" wird catch aber nur in der DEBUG-Version aufgerufen:
void CBsp01Dlg::OnBtnExDiv0Save() { int i = 1, j = 0, k = 0; try { k = i/j; } //hier werden alle bis dahin nicht aufgefangenen MFC Fehler //auf die andere catch-Routinen nicht greifen, abgefangen catch (...) //Fehlerauffangroutine für Fehler aller art (...) { AfxMessageBox("Allgemeiner Fehler (nicht MFC) ist aufgetreten"); } }
selbiges gilt bei nicht initialisierten Pointern:
CObList* m_pObjektZeiger; //ein Zeiger um viele Fehler zu machen! try { m_pObjektZeiger->GetTail(); } catch (...) //Fehlerauffangroutine für Fehler aller art (...) { AfxMessageBox("Allgemeiner Fehler (nicht MFC) ist aufgetreten"); }
D.h., ich bekomme die Msgbox nur in der Debug-Version zu sehen. In der Release passiert nichts.
FRAGE:
Welche Compilerschalter/Einstellungen muß man setzen, damit Fehler, die nicht von CException stammen auch in der Release Version per AfxMessagebox gemeldet werden (in der der Debug-Version klappt es)?
Meine Einstellungen:
Debug:
/nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /FR"Debug/" /Fp"Debug/Bsp01.pch" /Yu"stdafx.h" /Fo"Debug/" /Fd"Debug/" /FD /GZ /cRelease:
/nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /FR"Release/" /Fp"Release/Bsp01.pch" /Yu"stdafx.h" /Fo"Release/" /Fd"Release/" /FD /cDanke Euch
-
Du solltest vermeiden Zugriffsfehler bei ungültigen Speicherzugriffen zu behandeln. (Das ist jedenfalls meine Meinung).
catch(...) kann auch nicht alles abfangen.Hier kommen Betriebssystem Exceptions ins Spiel. Die sogenannten SEH Exceptions.
Die Behandle ich in einem Unhandled Exception Filter und schreibe einen Dump und beende die Software.Das echte Behandeln von Excpetions wie Speicherzuwesiungsfehlern, falschen Zeigern etc., ist fatal und davon kann ich nur abraten, weil Du die eine Aussage treffen kannst wie kaputt Dein System nicht schon ist...
Ansonsten lies dazu:
http://www.codeproject.com/KB/cpp/seexception.aspxSiehe auch die folgende Diskussion:
http://social.msdn.microsoft.com/forums/en-US/vclanguage/thread/84806adb-4343-4553-a924-be5db41497a4/Weitere Quellen:
http://msdn.microsoft.com/en-us/library/x057540h.aspx
http://msdn.microsoft.com/en-us/magazine/cc301714.aspx
http://www.microsoft.com/msj/0197/exception/exception.aspx
http://blogs.msdn.com/b/jaredpar/archive/2008/01/11/mixing-seh-and-c-exceptions.aspx