信号的分类

Linux 信号分为两大类:

  • ​标准信号(Standard Signals)​​:编号 1~31(如 SIGINT=2SIGKILL=9SIGSEGV=11)。
  • ​实时信号(Real-time Signals)​​:编号 32~64(SIGRTMIN 到 SIGRTMAX),支持排队和携带数据。

信号的传递

信号传递指内核将信号传递给目标进程的过程,涉及一下机制:

信号掩码

每一个线程有一个信号掩码 sigset_t 决定哪些信号被阻塞。被阻塞的信号会保持 pending,直到解除阻塞。

可以通过 sigprocmask() 或者 pthread_sigmask() 修改掩码

信号处理

进程可以给信号注册处理函数,通过 signal() 或者 sigcation()

void handler(int sig) { ... }
struct sigaction sa = { .sa_handler = handler };
sigaction(SIGINT, &sa, NULL);

信号队列

  • 标准信号:不排队,多次发送同一个信号可能丢失
  • 实时信号:排队,能够保证每次的信号都被处理

信号与调试

SIGTRAP 的特殊用途​​

  • ​断点触发​​:int3 指令(brk #0)(0xCC)会生成 SIGTRAP
  • ​单步执行​​:PTRACE_SINGLESTEP 会让每条指令后触发 SIGTRAP
  • ​系统调用拦截​​:PTRACE_SYSCALL 在进入/退出系统调用时触发 SIGTRAP

获得子进程的信号

waitpid 函数

全名作用
WIFEXITED(status)​W​​ait ​​I​​f ​​EXITED​子进程是否正常退出(通过 exit() 或 return)。
WEXITSTATUS(status)​W​​ait ​​EXIT STATUS​若 WIFEXITED 为真,获取子进程退出状态(低 8 位,即 exit(3) 的 3)。
WIFSIGNALED(status)​W​​ait ​​I​​f ​​SIGNALED​子进程是否被信号杀死(如 SIGKILL)。
WTERMSIG(status)​W​​ait ​​TERM​​inate ​​SIG​​nal若 WIFSIGNALED 为真,获取导致终止的信号编号。
WIFCONTINUED(status)​W​​ait ​​I​​f ​​CONTINUED​子进程是否因 SIGCONT 从暂停状态恢复(需搭配 WCONTINUED 选项)。