Es ist möglich, die SIGABRT abzufangen und das Programm zum Beispiel mit einem Longjump fortzusetzen.
Ich frage mich, ob dies zu einem Stapelüberlauf führen kann, wenn ich immer Funktionen aufruft, die abort () aufrufen.
Ich muss das wissen, weil ich das Assert-Makro (tath calls abort) in Unit-Tests verwenden will. Wenn eine Bestätigung fehlschlägt, möchte ich mit dem nächsten Komponententest fortfahren.
abort
muss den Stapel nicht löschen; longjmp
"löscht" es, indem es den Stack-Zeiger zurück auf die Position von setjmp
zurückspult. Wenn alles andere korrekt ist, verursacht das wiederholte Aufrufen von longjmp
und setjmp
keinen Stapelüberlauf.
Allerdings wird longjmp
den normalen Ausführungspfad überspringen, der Ressourcenlecks selbst aufrufen kann. Betrachten Sie diesen Code:
Wenn der Teil "... usse s ..." eine Funktion namens longjmp
s aus dem Code aufruft, wird free
keine Chance erhalten, aufgerufen zu werden, und Sie werden undicht. Dasselbe gilt für das Schließen von geöffneten Dateien, Sockets, das Freigeben von Shared-Memory-Segmenten, das Ernten von geteilten untergeordneten Elementen usw.
Aus diesem Grund wird longjmp
in der C-Programmierung selten verwendet. Mein Rat wäre, assert
zu vermeiden, wenn Sie das Programm nicht zum Beenden meinen. Verwenden Sie einfach ein anderes Makro in Ihren Komponententests oder wechseln Sie zu einem Testframework, das eins bereitstellt.
longjmp löscht den Stapel nicht, aber er ändert den Stapelzeiger:
Wenn die Funktion, in der setjmp aufgerufen wurde, zurückkehrt, ist es nicht mehr möglich, longjmp mit dem entsprechenden jmp_buf-Objekt sicher zu verwenden. Dies liegt daran, dass der Stapelrahmen bei der Funktion ungültig gemacht wird kehrt zurück. Durch den Aufruf von longjmp wird der Stapelzeiger wiederhergestellt Die zurückgegebene Funktion würde auf ein nicht existierendes und potentiell verweisen überschriebener / beschädigter Stapelrahmen.
Bei Annahme von POSIX ist das Aufrufen von longjmp
, um SIGABRT
von abort
aufzuheben, gültig, weil abort
als async-signal-sicher angegeben ist (und auch, weil dieses Signal nicht asynchron ist). (In normalem C ist UB praktisch alles, was von einem Signal-Handler ausgeht, daher ist es normalerweise kein interessanter Fall, darüber zu sprechen.) Es liegt jedoch in Ihrer Verantwortung, sicherzustellen, dass kein eigener Programmstatus inkonsistent bleibt eine Möglichkeit, dass Ihr Programm UB auf andere Weise sofort oder viel später im Programmablauf aufruft.
Damit stimme ich user4815162342 zu, dass Ihr Vorschlag eine sehr schlechte Form der Fehlerbehandlung ist. Wenn Sie nicht abbrechen möchten, rufen Sie nicht abort
auf, sondern schreiben Sie stattdessen eigene Fehlerbehandlungsfunktionen.
Tags und Links c abort stack-overflow