SIGFPE、SIGILL、SIGSEGV 等信号的处理函数不可返回
15.3 ID_sig_illReturn
与计算异常相关的信号由不可恢复的错误引起,相关信号处理函数应终止程序的执行,否则会导致标准未定义的行为。
示例:
#include <signal.h>
void handler(int signum) {
....
return; // Non-compliant
}
int main() {
signal(SIGFPE, handler);
....
}
当发生除 0 等计算异常时,程序会收到 SIGFPE 信号,在这种信号的处理函数中应使用 abort、_Exit 等函数终止程序的执行,不可正常返回,否则可能会造成更严重的错误。
应改为:
void handler(int signum) {
....
_Exit(1); // Compliant
}
或使用 sigsetjmp 和 siglongjmp 使流程跳转到主程序中的预定位置:
sigjmp_buf buf;
void handler(int x) {
siglongjmp(buf, 1); // Compliant
}
int main() {
signal(SIGFPE, handler);
if (sigsetjmp(buf, 1)) {
.... // #1, normal procedure
return 0; // Normal exit
} else {
.... // #2, handle error
return 1; // Abnormal exit
}
}
在这种模式下,#1 实现程序的功能,如果收到了 SIGFPE 信号,流程就会跳转到 #2。
依据
ISO/IEC 9899:1999 7.14.1.1(3)-undefined
ISO/IEC 9899:2011 7.14.1.1(3)-undefined