考虑以下计划:
void handler(int signum){
printf("handling %d\n", signum);
}
int main() {
signal(SIGINT, handler);
sigset_t *ss;
sigemptyset(ss);
sigaddset(ss, SIGINT);
sigprocmask(SIG_BLOCK, ss, NULL);
for(;;);
return 0;
}
在终端中运行此程序后,当我按下ctrl-c时,我总是得到“处理2”作为输出,但我希望没有输出,因为SIGINT先前被阻止了。我错误地阻止了SIGINT吗?通过假设在从内核模式进入用户模式的过程中不会处理阻塞的信号,我是否误解了阻塞信号意味着什么?
答案 0 :(得分:2)
@Useless正确地回答了这样一个问题,即你通过向sig*
函数传递一个未初始化的指针来调用UB。
至于为什么它可以工作并且没有崩溃或者没有阻止SIGINT可以在你添加行时明确 -
printf("%p", ss);
这很可能会打印(nil)
或0
。
幸运的是,未初始化的变量设置为NULL
,并且来自sigprocmask
的文档
如果
set
是NULL
,则信号掩码不变(即,如何) 忽略),但信号掩码的当前值仍然是 在oldest
中返回(如果不是NULL
)。
因此,您对SIGINT
的阻止实际上被忽略了。但是,如果你不幸运的话,你也可能会看到崩溃或其他一些(甚至是正确的行为)。