安全ではありません。
シグナル ハンドラは非常に単純で、単純に間違っています。SEGV ハンドラは次のとおりです。
void default_segv()
{
throw std::runtime_error("Segmentation fault");
}
少なくとも POSIX では、これはかなり違法です。シグナルハンドラー内から例外をスローすることは、非常に悪い考えです。
補遺
では、なぜこれが悪い考えなのでしょうか?
SIGALRM を使用すると、悪い考えよりも悪いことになります。アラームは非同期であるため、未定義の動作です。SIGSEGV と SIGBUS を使用するのは非常に悪い考えです。他の信号では、それは単に悪い考えです。うまくいくかもしれません。また、そうでない場合もあります。魔法が効かないと、結果は非常に悲惨なものになる可能性があります。
最初に SEGV を見ていきます。セグメンテーション違反とバス エラーの一般的な原因の 1 つは、スタックの破壊です。これがシグナルの原因である場合、アンワインドするスタックはありません。はthrow
、別の SEGV を発生させるスタックを巻き戻そうとします。それで?私のコンピューターでは、それは惨事です。
シグナルに関係なく、シグナル ハンドラー内でのスローは RAII に関して安全ではありません。これはfree()
(したがってdelete
) ハンドラーのコンテキスト内での呼び出しが安全ではないためです。シグナル ハンドラーのコンテキスト内から安全に呼び出せない関数が多数あります。はハンドラーから返されないため、ハンドラー内の の後に発生するすべてのことthrow
は、シグナル ハンドラーのコンテキスト内から行われます。throw
はthrow
リターンをバイパスします。
これらの安全でない呼び出しと安全でない巻き戻しは、古いシグナルを処理しながら新しいシグナルを発生できることを意味します。この再帰シグナルは非常に問題があります。たとえば、私のコンピューターでは、シグナルが SIGSTOP に変更されます。プログラムは終了せず、コアもドロップしません。それはそこにハングアップし、-9 で強制終了するか、マシンを再起動するまで永久にフリーズします。