Linux のセグメンテーション違反ハンドラー内で発生するセグメンテーション違反に対する定義済みの動作はありますか? 同じハンドラーへの別の呼び出しはありますか? もしそうなら、すべてのプラットフォームで、それは定義されていますか?ありがとうございました。
2 に答える
答えは、シグナルハンドラーをどのようにインストールしたかによって異なります。非推奨のsignal()
呼び出しを使用してシグナルハンドラーをインストールした場合は、シグナルハンドラーをデフォルトのハンドラーにリセットするか、シグナルハンドラーを呼び出す前に処理中のシグナルをブロックします。シグナルをブロックした場合は、シグナルハンドラーが戻った後にブロックを解除します。
を使用するsigaction()
と、シグナルハンドラーの呼び出し中にブロックされるシグナルを制御できます。そのように指定すると、無限再帰を引き起こす可能性があります。
sigaction()
次のようなAPIを持つ安全なラッパーを実装することができsignal()
ます。
sighandler_t safe_signal (int sig, sighandler_t h) {
struct sigaction sa;
struct sigaction osa;
sa.sa_handler = h;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if (sigaction(sig, &sa, &osa) < 0) {
return SIG_ERR;
}
return osa.sa_handler;
}
これにより、シグナルハンドラー呼び出しの間、すべてのシグナルがブロックされます。シグナルハンドラー呼び出しは、シグナルハンドラーが戻った後に復元されます。
C-11
標準から7.14.1.1
、、
シグナルが発生し、funcが関数を指す場合、signal(sig、SIG_DFL)と同等かどうかは実装によって定義されます。が実行されるか、実装により、現在の信号処理が完了するまで、実装で定義された一連の信号(少なくともsigを含む)が発生しなくなります。
したがって、Standardは、同じシグナルハンドラーの再帰呼び出しを許可するかどうかは、実装によって定義されると述べています。したがって、動作は定義されていますが、実装は定義されていると結論付けます。
しかし、segfaultハンドラー自体がsegfaultingである場合、それは完全に混乱します:)