如果我为 SIGSEGV
设置了信号处理程序,则会生成如下段错误:
int *a = NULL;
*a = 1;
处理程序将被调用,但此信号处理程序只会被调用一次。所以,我猜想 Linux 内核会将信号处理程序重置为 SIG_DFL
,但是什么时候呢?想知道详情,于是查了Linux内核源码,还没有找到头绪。如果您知道详细信息,请告诉我代码。
这取决于您如何注册信号处理程序。使用 sigaction
并且没有 SA_RESETHAND
标志,将不会重置为 SIG_DFL
(尽管从响应 运行的信号处理程序返回>SIGSEGV
由于段错误而交付在技术上是 UB)。使用 SA_RESETHAND
它将被重置,如果您使用 signal
注册处理程序,那么处理程序是否会被重置是未指定的(所以不要使用 信号()
)。
例子:
#include <signal.h>
#include <unistd.h>
int volatile*a;
void h(int Sig) { write(1,"h\n", 2); }
int main()
{
//sigaction(SIGSEGV,&(struct sigaction){.sa_handler=h}, 0); //won't reset the handler, will likely loop
sigaction(SIGSEGV,&(struct sigaction){.sa_handler=h,.sa_flags=SA_RESETHAND}, 0); //will reset the handler
//signal(SIGSEGV,h); //may or may not reset the handler
*a=1;
return 0;
}
我是一名优秀的程序员,十分优秀!