try catch und Release Version



  • Aloha,

    ich habe folgende Basicfrage.

    Ich erzwinge mit der folgende Zuweisung eine wunderbare Fehlermeldung

    int *test;
    *test = 13;
    

    Nun möchte ich per try/catch Block diese abfangen, kann dies aber nicht im Release Mode realisieren. Im Debug Modus, alles kein Thema.

    try 
    { 
       int *test;
       *test = 13;
    } 
    catch(...) 
    { 
       AfxMessageBox("Fehler");
    }
    

    Geht das prinzipiell nicht oder gibt es eine Lösung, die mir einfach nicht bekannt ist ?
    Wenn das tatsächlich nicht möglich ist, mit was für Einschränkungen muss ich rechnen, wenn ich bis zum Fehlerfund die Debug.exe anstatt der Release.exe laufen lasse ?

    Danke und Grüße

    BOA



  • Solche Exceptions laufen in Windows unter SEH (Structured Exception Handling).
    Dazu müssen __try / __except benutzt werden.


  • Mod

    Ich würde aber zu so etwas nicht greifen sondern lieber einen default exception handler installieren, einen Crashdump schreiben und anschließend das Programm beenden.

    Siehe MiniDumpWriteDump
    http://msdn2.microsoft.com/en-us/library/ms680360(VS.85).aspx
    und diverse Artikel in Codeproject und der MSDN...

    Und nicht zu vergessen den "Bugslayer Utilities" (John Robbins)



  • Hi Ihr beiden,

    danke für die schnellen Antworten.

    @simon.gysi
    Auch mit __try / __except funktioniert es nicht im Release Mode.

    @Martin Richter
    Brauche ich Systemzugriffsrechte, wenn ich diese Minidumps auswerten will ?
    Was meinst Du mit "einem Default Exception Handler definieren". Was soll denn da der Standard sein ?

    Die andere Frage, auf was für Einschränkungen ich mich gefaßt machen muss, wenn ich statt der Release compilierten exe, die Debug compilierte laufen lasse, interessiert mich immer noch. Klingt für mich nach der schnellsten und unkompliziertesten Lösung...

    Danke und Grüße

    BOA


  • Mod

    Nein man braucht keine speziellen Rechte.
    Siehe Doku zu Dumps:
    http://msdn2.microsoft.com/en-us/library/bb204861(VS.85).aspx

    Siehe SetUnhandledExceptionFilter
    http://msdn2.microsoft.com/en-us/library/ms680634.aspx

    Siehe Thread in diesem Forum:
    http://www.c-plusplus.net/forum/viewtopic-var-p-is-1418318.html



  • Hallo Martin,

    noch mal Dank für die Antowrt.

    Ich habe mir nun mal den Code aus dem C-plusplus Forum Beitrag einverleibt und den Fehler noch einmal erzwungen.

    Ich kann mit der Ausgabe, die dumpchk.exe in Verbindung mit der erzeugten dmp auswirft, nichts anfangen.

    Da steht nichts drin, was irgendwie einen Sinn mit meinem momentanen Wissensstand gibt...

    Dass ich nen Speicherfehler erzeuge ist mir ja auch klar, aber woher der rührt unter welchen Umständen, ist zumindest für mich nicht lesbar in der Ausgabe...

    Ich komme noch mal auf meine ursprüngliche Frage zurück.

    Was für Einschränkungen habe ich, wenn ich die Debug compilierte exe laufen lasse, anstatt der Release Modus kompilierten ? Hier kann ich mit try and catch wunderbar reagieren, das Programm sauber schließen und auch eine Logdatei beschreiben. Sprich alles, was ich benötige, um den Fehler auf die Schliche zu kommen...

    Die Frage ist nur, was für Konsequenzen habe ich noch, außer dass ich Fehler behandeln kann ? 🙂

    Grüße

    BOA



  • Das Problem, dass try-catch nicht im Release-Build funktioniert, liegt wahrscheinlich an der Optimierungseinstellung des Compilers (MS Visual C++).
    Stelle mal im Projekt die C++ Compiler Optimierung auf Standard und nicht auf Geschwindigkeit/Größe optimieren (/O1 /O2).
    Dann klappt try-catch auch im Release-Build.

    siehe auch http://members.cox.net/doug_web/eh.htm

    Der Compiler schmeisst bei Optimierung anscheined den try-catch-Mechanismus raus, weil kein throw() im try-block ist.

    Update:
    oder einfach vor und nach der Funktion die Optimierung aus-/einschalten:

    #pragma optimize("", off)
    void UnsichereFunktion()
    {
     try{}
     catch(...){}
    }
    #pragma optimize("", on)
    

  • Mod

    Warum so kompliziert und DUMPCHK verwenden.

    Nimm VS.
    Öffne die DMP Datei als Projekt und sage einfach F5 (Start Debug) und staune... 🕶



  • @Softwaremaker
    Ich denke nicht, dass es etwas mit der Optimierung zu tun hat.

    Ich denke es ist viel eher so, dass es eben "Zufall" ist, ob eine Access Violation stattfindet oder nicht, da test (im Release Mode) nicht initialisiert ist.

    int *test;
    *test = 13;
    

    So würde auch im Release Mode eine Access Violation stattfinden.

    int *test(0);
    *test = 13;
    

    Im Debug Mode initialisiert der Debugger test automatisch mit 0, desshalb "funktioniert" im Debug Mode auch das try/catch.

    Dies nur zum Verständnis, ansonsten ist die Variante von Martin Richter vorzuziehen.

    Grüsse Simon



  • Softwaremaker schrieb:

    Das Problem, dass try-catch nicht im Release-Build funktioniert, liegt wahrscheinlich an der Optimierungseinstellung des Compilers (MS Visual C++).
    Stelle mal im Projekt die C++ Compiler Optimierung auf Standard und nicht auf Geschwindigkeit/Größe optimieren (/O1 /O2).
    Dann klappt try-catch auch im Release-Build.

    siehe auch http://members.cox.net/doug_web/eh.htm

    Der Compiler schmeisst bei Optimierung anscheined den try-catch-Mechanismus raus, weil kein throw() im try-block ist.

    Update:
    oder einfach vor und nach der Funktion die Optimierung aus-/einschalten:

    #pragma optimize("", off)
    void UnsichereFunktion()
    {
     try{}
     catch(...){}
    }
    #pragma optimize("", on)
    

    👍 Nun klappt es auch im Release Modus...
    Danke!!! Das hilft mir sehr....

    @Martin
    Auf die Gefahr hin, dass Du mich künftig meidest. Wie soll ich das Ding als Projekt öffnen ? Das ist ja eine dmp-Datei.
    Ich würde gerne staunen...

    Grüße und Danke

    BOA



  • simon.gysi schrieb:

    @Softwaremaker
    Ich denke nicht, dass es etwas mit der Optimierung zu tun hat.

    Ich denke es ist viel eher so, dass es eben "Zufall" ist, ob eine Access Violation stattfindet oder nicht, da test (im Release Mode) nicht initialisiert ist.

    int *test;
    *test = 13;
    

    So würde auch im Release Mode eine Access Violation stattfinden.

    int *test(0);
    *test = 13;
    

    Im Debug Mode initialisiert der Debugger test automatisch mit 0, desshalb "funktioniert" im Debug Mode auch das try/catch.

    Dies nur zum Verständnis, ansonsten ist die Variante von Martin Richter vorzuziehen.

    Grüsse Simon

    Hi,

    danke für die Ergänzung, allerdings kommt beim deinem Quälcode ne Fehlermeldung, sprich das Programm läuft gar nicht erst los... 😉

    Die Lösung von Softwaremaker ist schon genau, was ich gesucht habe, nun isses nicht mehr so optimiert, aber bis zur Fehlerfindeung kann ich in allen erdenkliche Variationen reagieren.

    Danke und Grüße

    BOA



  • Quälcode

    ui.. schon so gequält..

    Nein, ernsthaft. Meinst Du ein Compiler Fehler?
    Dann versuchts mit:

    int *test = 0;
    *test = 13;
    

    Gruss Simon



  • Ergänzung zum Dump (finde ich auch eine super Sache!): Auf welchem Warnlevel arbeitest du? Wenn du den Warnlevel höher setzt, hätte der Compiler dir bestimmt gesagt, das test nicht korrekt initialisert wurde. Das hindert dich zwar nicht das Ding trotzdem auszuführen, aber er hat dich schon beim Kompilieren auf eine potenzielle Gefahrenquelle hingewiesen. Damit kann man schon mal Ärger minimieren.



  • simon.gysi schrieb:

    Quälcode

    ui.. schon so gequält..

    Nein, ernsthaft. Meinst Du ein Compiler Fehler?
    Dann versuchts mit:

    int *test = 0;
    *test = 13;
    

    Gruss Simon

    Genau,

    Compilerfehler, war schlecht ausgedrückt von mir...

    Grüße

    BOA



  • Artchi schrieb:

    Ergänzung zum Dump (finde ich auch eine super Sache!): Auf welchem Warnlevel arbeitest du? Wenn du den Warnlevel höher setzt, hätte der Compiler dir bestimmt gesagt, das test nicht korrekt initialisert wurde. Das hindert dich zwar nicht das Ding trotzdem auszuführen, aber er hat dich schon beim Kompilieren auf eine potenzielle Gefahrenquelle hingewiesen. Damit kann man schon mal Ärger minimieren.

    Hi,

    ja das mit dem Dump würde ich auch gerne nutzen und verstehen. Da bin ich gerade dran, eventuell erbarmt sich Martin noc einmal, mir zu antworten... 😉

    Ja, klar, bei dem jetzigen Code warnt er natürlich. Ich wollte mit dem Beispielcode nur einen Abbruch erzwingen, um prinzipiell mein try catch Problem in Verbindung mit Release hier darzustellen...

    Danke und Grüße

    BOA



  • Also wenn ich bei eingeschalteter Optimierung /O2 folgendes ausführe:

    try
    {
       int *test=NULL;
    
       *test = 31;
    }
    
    catch(...)
    {
       AfxMessageBox("try-catch ok");
    }
    

    Release: Windows-Fehlermeldung erscheint (catch wird nicht aufgerufen)
    Debug: MsgBox "try-catch ok" (catch wird aufgerufen)
    Im Debug ist Optimierung deaktiviert!

    Release ohne Optimierung: MsgBox "try-catch ok" (catch wird aufgerufen)

    -> Optimierung entfernt try-catch-Mechanismus

    siehe auch: http://members.cox.net/doug_web/eh.htm
    "...If you were to examine the assembly language emitted for this program, you would find the compiler has optimized all the exception handling machinery out of the function, because the optimizer can determine the tried code cannot throw a C++ exception."

    (WinXP, VC++ 6.0)

    Update:
    aber wenn man nach
    int *test=NULL;
    ein "CString msg;" einfügt kommt catch auch bei Release mit Optimierung.
    -> Sehr merkwürdiger Optimierer



  • "...If you were to examine the assembly language emitted for this program, you would find the compiler has optimized all the exception handling machinery out of the function, because the optimizer can determine the tried code cannot throw a C++ exception."

    Ja, aber die __try / __except (SEH) wird dann nicht weg optimiert.

    catch(...) ist ein mix zwischen C++ Exception Handling und SEH.

    Edit: Ist das Verhalten bei VS2005 / VS2008 dasselbe? VC++6.0 ist doch schon sehr in die jahre gekommen und nicht sehr ISO Compliant.


  • Mod

    Martin Richter schrieb:

    Warum so kompliziert und DUMPCHK verwenden.

    Nimm VS.
    Öffne die DMP Datei als Projekt und sage einfach F5 (Start Debug) und staune... 🕶

    Wie ich es gesagt habe.
    Einfach auf Projekt Öffnen gehen. Dort alle Dateien (inkl. .dmp) anzeigen lassen. Die dmp Datei öffnen (ja das geht!), F5 drücken und jetzt Staunen... 🕶



  • OMFG.
    Dashier ist schlimmer als wenn man dem Fleischer beim Wurst-Machen zusieht.
    Ich werde nie wieder ein Programm anfassen welches ich nicht selbst geschrieben habe!

    @BOA: Verwende doch bitte einfach _set_se_translator oder __try/__except.
    z.B. so:

    int poese()
    {
    	int volatile*p = 0;
    	*p = 0;
    	return 0;
    }
    
    int main()
    {
    	__try
    	{
    		return poese();
    	}
    	__except(EXCEPTION_EXECUTE_HANDLER)
    	{
    		printf("poese!!!\n");
    		return 1;
    	}
    }
    

    Und sag bitte nicht nochmal das funktioniere nicht. Das funktioniert! (Und _set_se_translator funktioniert auch)



  • hustbaer schrieb:

    OMFG.
    Dashier ist schlimmer als wenn man dem Fleischer beim Wurst-Machen zusieht.
    Ich werde nie wieder ein Programm anfassen welches ich nicht selbst geschrieben habe!

    @BOA: Verwende doch bitte einfach _set_se_translator oder __try/__except.
    z.B. so:

    int poese()
    {
    	int volatile*p = 0;
    	*p = 0;
    	return 0;
    }
    
    int main()
    {
    	__try
    	{
    		return poese();
    	}
    	__except(EXCEPTION_EXECUTE_HANDLER)
    	{
    		printf("poese!!!\n");
    		return 1;
    	}
    }
    

    Und sag bitte nicht nochmal das funktioniere nicht. Das funktioniert! (Und _set_se_translator funktioniert auch)

    Hehe,

    dann wirst Du viele gute und hilfreiche Programme nicht kennen lernen...
    Vor allen Dingen so ohne Betriebssystem auf Deinem Rechner, viel Spass beim entwickeln... 😃

    Danke für Deinen Code, teste ich mal und berichte...

    @Martin Richter
    Ich glaube wir arbeiten mit verschiedenen Versionen, Martin.

    Ich habe das VS 6, da kann ich nen Arbeitsbereich öffnen, aber kein Projekt, oder, ja schlagt mich, ich weiß net wo...

    Ich weiß, ist ne schwere Geburt, aber das Kind scheint gesund, bitte hilf ihm... 😉

    Grüße und Danke

    BOA


Anmelden zum Antworten