globaler exception handler



  • hallo,

    wir (das CTeam2005) arbeiten momentan an einem ... naja, doch etwas größerem Projekt.
    jedenfalls wollten wir am Ende dem Nutzer die Möglichkeit geben, im Falle eines Absturzes,
    uns eine E-Mail zu schicken.
    Soll heißen:

    Programm stürzt ab -> Fenster erscheint mit Fehlermeldung -> Button "E-Mail an die Entwickler"

    das Programm würde an der Stelle gleich noch nen Screenshot machen und verschiedene Informationen (Registerbelegung usw.)
    mitschicken. Der Nutzer kann unter Umständen eine eigene Nachricht noch mitgeben.

    Jetzt das Problem:
    kann ich den Exception Handler global machen?
    oder muss ich überall try-catch-Blöcke setzen um das Vorhaben zu realisieren?

    und die nächste Frage:
    wie kann ich bei catch(...) herausfinden, was genau passiert ist?
    denn wenn ich einen anderen Typ angebe, wird die exception ja nur gefangen, wenn diese auch von diesem Typ ist.

    schonmal danke für Hilfe,

    MfG DrakoXP



  • als "globalen" exceptionhandler wuerde ich es bezeichnen, wenn du alles, was innerhalb der main() passiert, in einen try-block schiebst und jedwede exception abfaengst. Fuer die Behandlung wuerde ich mir dann ne Klasse schreiben die moeglichst exceptionsafe ist. Wenn du noch mehr abfangen willst, schau dir mal die Doku zu set_unexpected() und set_termiante() an.



  • Hallo,

    Du kannst einen Exception-Handler in deine main-Funktion einbauen. Dann landen da alle exceptions die nicht gefangen werden. Deswegen kannst du ja trotzdem noch weiter try/catch-Blöcke in dein Programm einfügen. Wenn du willst kannst du ja nach Abarbeitung mit throw die Exception weiter werfen.
    Bei catch(...) kannst du eben nichts rausbekommen. Deswegen solltest du wenigstens eine catch(std::exception& e) machen. Dann fängst du hier alles was von std:.exception abgeleitet ist. Darunter kannst du dann ja noch weitere catch-Blöcke anlegen für den Rest.



  • Also eine typische Vorgehensweise ist folgende, dass man alle Exceptions nach oben weitergibt. Ein Projekt besteht ja aus verschiedenen Modulen, und jedes Modul gibt dabei seine Excetions mittels throw dem Aufrufer weiter. Meistens ist es dann so, dass diese dann (in mehreren try/catch-Blöcken) von dem "obersten" Modul gefangen wird, welches diese dann z.B. entsprechend "ausgibt" (das könnte z.B. die GUI sein). D.h. dann treten auch mehrere try/catch-Blöcke auf. Da könnt ihr dann ja eine zentrale Funktion aufrufen mit der jeweiligen Exception als Übergabeparameter, welche dann diese Fehlermeldung mit EMail-Versand usw. anzeigt.

    So damit zum catch(...): Oft hat man tatsächlich mehrere catch-Blöcke in denen man eben die verschiedenen Exception-Typen fängt. Wenn man aber schon ganz genau weiß, dass man immer dasselbe machen will (in eurem Fall z.B. diese Funktion aufrufen), dann könnte man auch einfach ein catch()-Block machen, in dem man die oberste Exception-Klasse abfängt (das hat zur Folge, dass auch alle vererbten Exceptions gefangen werden... sollte auch in C++ so sein, hoffe dass ich da jetzt nix falsches sage).
    Hintergrund ist der, dass ja normalerweise jede Exception "gleich" ist (sprich sie hat ne message, evtl. eine root-Exception, evtl. StackTrace, usw...). Sie unterschieden sich eigentlich nur durch ihren Klassentyp, d.h. man hat eine Hierachie von Exceptions, normalerweise alle von einer Oberklasse (z.b. std::exception) abgeleitet.



  • die Frage ist jetzt, welchen Datentyp haben exceptions, die von Ansi-C Funktionen
    oder WinAPI-Funktionen thrown?

    denn in C gab es ja noch kein std::exception.
    werfen die dann zahlen, deren Bedeutung irgendwo dokumentiert ist?



  • *grübel* mir war nicht bekannt, dass es in ANSI C schon exceptions gegeben haben soll. Dachte immer die sind erst mit C++ eingeführt worden.



  • -.- ok...

    und wie kann ich dann Speicherzugriffsverletzungen von C-Funktionen abfangen?



  • Hallo

    Entweder verarbeiten C-Funktionen Speicherzugriffsfehler intern und geben den Mißerfolg per Rückgabe bekannt oder Windows kümmert sich mit einer Allgemeinen Schutzverletzung drum.

    bis bald
    akari



  • Mal was allgemeines @Drako:
    Speicherzugriffsverletzungen resultieren im Prinzip immer aus Programmierfehlern heraus. Das hat mit Exceptions eigentlich null zu tun. Exceptions sind, wie der Name schon sagt, eben für Ausnahmen da, und NICHT zum Abfangen von Programmierfehlern. D.h. hier sind Exceptions fehl am Platz.

    Ansonsten:
    Wenn ihr von eurem C++-Projekt aus mit älteren C Frameworks/APIs oder sonst was arbeiten müsst (wie z.B. der WinAPI), dann könnt ihr in euren Funktionen, in denen ihr z.B. auf WinAPI-Funktionen zugreift die Rückgabewerte auswerten und anhanddessen selbst entsprechende Exceptions nach außen schmeissen.
    Mal ein abstraktes Beispiel:

    //Read ist eine reine C-Funktion und gibt die Anzahl gelesener Zeichen zurück.
    //Wenn irgendwas schief ging beim Lesen, dann wird -1 zurückgegeben
    //Ist natürlich kein tolles Beispiel, aber viele alte C Funktionen geben oft //irgendwelche int's für mögliche Fehlerzustände zurück, deshalb doch ganz //brauchbar als Beispiel
    int read(char* buffer) 
    {
       ...
    }
    

    In eurer eigenen Funktion könntet ihr jetzt z.B. sowas machen:

    void myfunc()
    {
       int ret = read(...);
       if (ret == -1) {
            throw eReadException(); 
       }
    }
    

    eReadException wäre dann natürlich eine eigens von euch erstellte Exception-Klasse.



  • wie man sowas macht weiß ich auch xD

    es geht viel mehr darum, dass (vor allem beim Umgang mit Zeigern) C-Funktionen überhaupt keine Überprüfung durchführen.
    Somit stürzt das Programm ab, bevor man den Rückgabewert prüfen kann.

    Außerdem soll das ganze ja Debug-Zwecken dienen, falls eben ein Programmierfehler
    (ein falscher Zeiger oder was weiß ich) aufgetreten ist,
    damit man diesen recht schnell findet.

    -> ich weiß auch, was ein Debugger ist,
    aber es geht viel mehr darum, dass wir auch nicht auf allen möglichen PCs testen können.
    und im schlimmsten Fall hat irgendein Nutzer einen PC mit einem Windows, bei dem
    irgendeine Funktion nicht funktioniert, dann könnte er uns das komfortabel mitteilen.


Anmelden zum Antworten