2010-11-22 9 views
3

Also mein C++ Programm gerade abgestürzt ist, und die Fehler, die ich bekam, war:Intercepting C++ Ausnahmen

terminate called after throwing an instance of 'std::length_error' 
    what(): basic_string::_S_create 
Aborted 

Nun, was ich habe vor kurzem meinen Code hinzugefügt ist ein SIGSEGV Handler, also wenn es ein Segmentierungsfehler war , würde es fortfahren, die Stapelspur zu drucken.

Wie gehe ich vor, um einen Exit-Handler für uncaught (oder mehr wie uncatchable) Ausnahmen in C++ zu machen?

Antwort

5

Verwenden set_terminate Funktion, die die Handler-Funktion beenden setzt:

A-Handler-Funktion beenden ist eine Funktion automatisch aufgerufen, wenn die Ausnahmebehandlung Prozess sein für einige aufgegeben hat Grund. Diese passiert, wenn ein Handler nicht gefunden werden kann für eine geworfene Ausnahme oder für einige andere außergewöhnliche Umstände, die macht unmöglich, die Handhabung Prozess fortzusetzen.

+0

Ah, danke. Wird es in der Lage sein, auf den Stack-Trace zuzugreifen, wo auch immer die Ausnahme herkommt? Ich denke, ich werde es bald herausfinden. – kamziro

+0

@kamziro: Sie werden wahrscheinlich den Stack-Trace im Debugger sehen können, aber ich denke nicht, dass es einen Weg gibt, ihn aus dem Code zu holen. – vitaut

+0

Ah, es funktioniert, ich habe gerade meinen SIGSEGV-Handler wiederverwendet, der backtrace und addr2line (linux) benutzt, um Dinge in einen schön formatierten Stack-Trace umzuwandeln. – kamziro

0

Setzen Sie einfach try - catch(...) auf die Ebene Ihres Programms. Etwas wie folgt aus:

try { 
    doStuff(); 
} catch(std::exception& e) { 
    //handle std::exception-derived exceptions 
} catch(...) { 
    //handle all other exceptions 
}  
0

Sie können Ihren eigenen Terminierungshandler mit set_terminate installieren.

Sie können alle C++ - Ausnahmen mit einer Catch-All-Klausel catch (...) {} abfangen.

1

Wenn Sie zur Antwort von @vitaut hinzufügen, können Sie, wenn Sie C++ 11 verwenden, nach der aktuellen Ausnahme in der von std::set_terminate angegebenen Prozedur suchen und diese abrufen.

According to Daniel Krügler, die auf den Standard unten angegebenen beziehen, gibt es einen impliziten Exception-Handler aktiv während des Anrufs std::terminate, was bedeutet, dass wir std::current_exception verwenden beide können prüfen, ob es eine aktive Ausnahme ist und es auch untersuchen.

Die 11 C++ Standard working draft N3242, Abschnitt 15.3.7 (emphasis mir): ist

Ein Handler aktiv betrachtet, wenn die Initialisierung für den formalen Parameter (falls vorhanden) des Mitnehmers abgeschlossen ist Klausel. [Hinweis: Der Stapel wurde zu diesem Zeitpunkt abgewickelt. - Endnote]Außerdem wird ein impliziter Handler als aktiv betrachtet, wenn std :: terminate() oder std :: unexpected() aufgrund eines throw eingegeben wird. Ein Handler wird nicht mehr als aktiv betrachtet, wenn die catch-Klausel beendet wird oder wenn std :: unexcepted() beendet wird, nachdem aufgrund eines Wurfs eingegeben wurde.


Stealing from Andrzej's C++ blog, hier ist ein Beispiel dafür, wie dies geschehen kann:

[[noreturn]] void onTerminate() noexcept 
{ 
    if(auto exc = std::current_exception()) { 
     // we have an exception 
     try{ 
      rethrow_exception(exc); // throw to recognize the type 
     } 
     catch(MyException const& exc) { 
      // additional action 
     } 
     catch(MyOtherException const& exc) { 
      // additional action 
     } 
     catch(std::exception const& exc) { 
      // additional action 
     } 
     catch(...) { 
      // additional action 
     } 
    } 

    std::_Exit(EXIT_FAILURE); 
} 
Verwandte Themen