我试图忽略SIGTRAP。我有以下概念验证代码:

#include <signal.h>
#include <stdlib.h>
int main(){
    signal(SIGTRAP, SIG_IGN);
    write(1, "A", 1);
    asm("int3");
    write(1, "B", 1);
    return 0;
}

当我运行它时,我希望看到“AB”,但是我看到了
ATrace/breakpoint trap (core dumped)

为什么我的程序尽管忽略了SIGTRAP还是终止了?

最佳答案

根据this site,当被引发时,阻塞/忽略的信号会在内核代码中自动解除阻塞。因此,如果反复发出相同的信号,则不会发生无限循环。相反,至少在Linux内核实现中,应用程序在第二次信号上升时终止。

因此,当使用raise()时,SIGTRAP仅会被引发一次,不会造成任何问题。但是,通过asm("int3"),处理器将重新执行引发信号的指令。围绕此第二次导致进程终止。

相关的内核源代码(对于旧的2.6.27)在此处(函数force_sig_info):

939        if (blocked || ignored) {
940                action->sa.sa_handler = SIG_DFL;
941                if (blocked) {
942                        sigdelset(&t->blocked, sig);
943                        recalc_sigpending_and_wake(t);
944                }
945        }

10-08 16:10