信号的分类
Linux 信号分为两大类:
- 标准信号(Standard Signals):编号 1~31(如
SIGINT=2
,SIGKILL=9
,SIGSEGV=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
。
获得子进程的信号
宏 | 全名 | 作用 |
---|---|---|
WIFEXITED(status) | Wait If EXITED | 子进程是否正常退出(通过 exit() 或 return )。 |
WEXITSTATUS(status) | Wait EXIT STATUS | 若 WIFEXITED 为真,获取子进程退出状态(低 8 位,即 exit(3) 的 3 )。 |
WIFSIGNALED(status) | Wait If SIGNALED | 子进程是否被信号杀死(如 SIGKILL )。 |
WTERMSIG(status) | Wait TERMinate SIGnal | 若 WIFSIGNALED 为真,获取导致终止的信号编号。 |
WIFCONTINUED(status) | Wait If CONTINUED | 子进程是否因 SIGCONT 从暂停状态恢复(需搭配 WCONTINUED 选项)。 |