Reinigt die Funktion abort () in C den Stapel?

8

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.

    
osiris81 23.01.2013, 13:21
quelle

3 Antworten

2

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:

%Vor%

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.

    
user4815162342 23.01.2013, 13:29
quelle
1

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.

    
Dark Falcon 23.01.2013 13:28
quelle
1

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.

    
R.. 23.01.2013 13:41
quelle

Tags und Links