たとえば、SIGABRTをキャッチして、ロングジャンプでプログラムを続行することができます。
常にabort()を呼び出す関数を呼び出すと、これがスタックオーバーフローにつながる可能性があるのではないかと思います。
ユニットテストでassertマクロ(taht呼び出しabort)を使用したいので、それを知る必要があります。アサーションが失敗した場合は、次の単体テストを続行します。
たとえば、SIGABRTをキャッチして、ロングジャンプでプログラムを続行することができます。
常にabort()を呼び出す関数を呼び出すと、これがスタックオーバーフローにつながる可能性があるのではないかと思います。
ユニットテストでassertマクロ(taht呼び出しabort)を使用したいので、それを知る必要があります。アサーションが失敗した場合は、次の単体テストを続行します。
abort
スタックをクリアする必要はありません。longjmp
スタックポインタをの位置に巻き戻すという点で「クリア」しますsetjmp
。他のすべてが正しければ、繰り返し呼び出しlongjmp
て、setjmp
スタックオーバーフローを引き起こしません。
ただし、longjmp
通常の実行パスはスキップされます。通常の実行パスは、それ自体でリソースリークを呼び出す可能性があります。このコードを考えてみましょう:
char *s = malloc(...);
... use s ...
free(s);
「...uses ...」の部分がlongjmp
コード外の関数を呼び出すfree
と、呼び出される機会がなく、リークが発生します。同じことが、開いているファイル、ソケットを閉じる、共有メモリセグメントを解放する、分岐した子を刈り取るなどにも当てはまります。
このためlongjmp
、Cプログラミングではめったに使用されません。私のアドバイスはassert
、プログラムを終了するつもりがない場合は避けることです。単体テストで別のマクロを使用するか、マクロを提供するテストフレームワークに切り替えてください。
longjmpはスタックを巻き戻しませんが、スタックポインタを変更します。
setjmpが呼び出された関数が戻った場合、対応するjmp_bufオブジェクトでlongjmpを安全に使用することはできなくなります。これは、関数が戻るときにスタックフレームが無効になるためです。longjmpを呼び出すと、スタックポインターが復元されます。これは、関数が返されるため、存在せず、上書き/破損した可能性のあるスタックフレームを指します。
POSIXを想定すると、は非同期シグナルセーフであると指定されているため(また、このシグナルは非同期ではないため) 、 raisedbylongjmp
から抜け出すための呼び出しは有効です。(プレーンCでは、シグナルハンドラーからほとんどすべてを実行することはUBであるため、通常、話をするのは興味深いケースではありません。)ただし、結果として、自分のプログラムの状態に一貫性がないことを確認するのはユーザーの責任です。プログラムがプログラムフローの直後またはかなり後に他の方法でUBを呼び出すようにする方法。SIGABRT
abort
abort
そうは言っても、あなたの提案は非常に悪い形式のエラー処理であるというuser4815162342に同意します。中止したくない場合は、を呼び出さずabort
に、代わりに独自のエラー処理関数を作成してください。