2010-10-12 10 views
5

Einige C++ - Bibliotheken rufen im Fehlerfall die Funktion abort() auf (z. B. SDL). In diesem Fall wird keine hilfreiche Debug-Information bereitgestellt. Es ist nicht möglich, den Abbruch abzubrechen und eine Diagnoseprotokollausgabe zu schreiben. Ich möchte dieses Verhalten global überschreiben, ohne diese Bibliotheken neu schreiben/neu erstellen zu müssen. Ich möchte eine Ausnahme auslösen und damit umgehen. Ist es möglich?C++ Abbruch überschreiben

Antwort

17

Beachten Sie, dass abort das Signal SIGABRT auslöst, als ob es raise(SIGABRT) heißt. Sie können einen Signalhandler installieren, die in dieser Situation, wie so genannt wird:

#include <signal.h> 

extern "C" void my_function_to_handle_aborts(int signal_number) 
{ 
    /*Your code goes here. You can output debugging info. 
     If you return from this function, and it was called 
     because abort() was called, your program will exit or crash anyway 
     (with a dialog box on Windows). 
    */ 
} 

/*Do this early in your program's initialization */ 
signal(SIGABRT, &my_function_to_handle_aborts); 

Wenn Sie die abort Anrufe nicht verhindern können (sagen wir, sie aufgrund von Fehlern sind, die trotz Ihrer besten Absichten einschleichen), Dadurch können Sie möglicherweise weitere Debugging-Informationen sammeln. Das ist tragbares ANSI C, also funktioniert es auf Unix und Windows und anderen Plattformen auch, obwohl, was Sie im Abbruchhandler tun, häufig nicht tragbar ist. Beachten Sie, dass dieser Handler auch aufgerufen wird, wenn assert fehlschlägt, oder sogar durch andere Laufzeitfunktionen - wenn z. B. malloc Heap-Fehler erkennt. Ihr Programm könnte also während dieses Handlers in einem verrückten Zustand sein. Sie sollten keinen Speicher reservieren - verwenden Sie möglichst statische Puffer. Machen Sie nur das Nötigste, um die benötigten Informationen zu sammeln, erhalten Sie eine Fehlermeldung an den Benutzer und beenden Sie.

Bestimmte Plattformen können möglicherweise ihre abort Funktionen weiter angepasst werden. Unter Windows beispielsweise verfügt Visual C++ über die Funktion _set_abort_behavior, mit der Sie auswählen können, ob dem Benutzer eine Nachricht angezeigt wird oder ob Absturzabfragen erfasst werden.

+0

Was passiert, wenn my_function_to_handle_aborts löst?) –

+0

@Pavel: es ist Implementierung definiert, d. H. Nicht tragbar. Grundsätzlich können Sie die Funktionen von C verwenden, aber Sie können möglicherweise keine C++ - Funktionen wie das Deklarieren von Variablen, das Aufrufen von 'new',' delete' oder das Auslösen von Ausnahmen verwenden. In vielen Implementierungen könnte es jedoch funktionieren. Außerdem soll die Funktion C-Verknüpfung haben - ich habe die Antwort bearbeitet, aber es ist unwahrscheinlich, dass sie unter Windows oder Unix einen Unterschied macht. – Doug

+0

Vielen Dank für die ausführliche Antwort. –

0

Sie könnten versuchen, Ihre eigenen zu schreiben und den Linker rufen Sie Ihren anstelle von std :: abort. Ich bin mir nicht sicher, ob es aber möglich ist.

3

Gemäß der man-Seite unter Linux erzeugt abort() eine SIGABRT für den Prozess, die von einem Signal-Handler abgefangen werden kann. EDIT: Ben's bestätigt das ist auch auf Windows möglich - siehe seinen Kommentar unten.

+1

Die Abbruchfunktion von Visual C++ funktioniert auch. void abort() - Abbruch des aktuellen Programms durch Aufrufen von SIGABRT Zweck: Ausdruck einer Abbruchmeldung und Anhebung des SIGABRT-Signals. Wenn der Benutzer keine Abbruchbehandlungsroutine definiert hat, beenden Sie das Programm mit dem Beendigungsstatus 3 ohne Bereinigung.