为什么忽略 SIGTRAP 对 asm 不起作用?
Why does ignoring SIGTRAP not work with asm?
我试图忽略 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,blocked/ignored 信号在内核代码中被触发时会自动解除阻塞。因此,如果重复发出相同的信号,则不会发生无限循环。相反,应用程序会在第二次发出信号时终止,至少在 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 }
我试图忽略 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,blocked/ignored 信号在内核代码中被触发时会自动解除阻塞。因此,如果重复发出相同的信号,则不会发生无限循环。相反,应用程序会在第二次发出信号时终止,至少在 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 }