Linux怎么查看进程的各种信号处理
Linux信号处理中,可通过ps命令查看信号捕获或忽略状态,通过/proc/PID/status文件查看SigPnd(待决信号)、SigBlk(阻塞信号)、SigCgt(捕获信号)位图,使用strace命令可实时观察信号递达行为,结合kill-l命令和man7signal手册确认信号编号及默认动作。特别需要注意,当SigPnd与SigBlk同时置位时,表示信
先说一句,信号在Linux进程里是个看似简单、实则容易踩坑的机制。很多人只知道用kill发信号,但真要排查“进程到底有没有收到信号”“它到底怎么处理的信号”,就得翻开工具箱,综合几个命令才能拼出完整图景。
ps命令可查看进程信号注册状态,如sigcatch(捕获)、sigign(忽略),而/proc/PID/status提供SigPnd(挂起)、SigBlk(阻塞)、SigCgt(捕获)等十六进制位图,strace -e signal则实时观察信号是否真正递达。

用 ps 查看进程当前信号处理状态
ps 提供了一个快捷入口,能直接看到进程对哪些信号设置了忽略、捕获,或者干脆没管,走默认处理。不过要注意,它反映的只是当前注册的 handler 状态,无法体现信号是否被屏蔽或挂起。
- 运行
ps -p:其中-o pid,comm,sig,sigcatch,sigign sig是被阻塞(blocked)的信号位图,以十六进制形式呈现;sigcatch列出已注册 handler 的信号,比如2,10,12;sigign则列出被明确忽略的信号,比如17,19 - 这里有个容易搞混的地方:
sig字段是阻塞掩码,不是 pending 信号。它和/proc/中的/status SigBlk对应,只是格式略有不同——ps 用十进制位图,/proc 用十六进制 - 如果一个信号既不在
sigcatch也不在sigign里,那就说明它走的是默认动作。比方说SIGTERM,默认就是终止进程
用 /proc//status 查信号位图细节
要说权威性,还得看 /proc/。内核在这里给出了最原始的信号状态数据,只是需要自己动手解析一下位图。
- 执行
cat /proc//status | grep -E "SigPnd|SigBlk|SigCgt" SigPnd:挂起(pending)信号位图,表示已经发送但还没递达的信号——比如被阻塞的情况SigBlk:当前被屏蔽(blocked)的信号位图,对应sigprocmask()的设置SigCgt:已注册 handler 的信号位图,也就是通过signal()或sigaction()设置过的- 这几个字段都是 64 位十六进制数(比如
0000000000000000),低位对应信号 1(SIGHUP),高位对应信号 64;普通信号只用低 32 位,这一点在解读时需要注意
用 strace -e signal 实时观察信号递达行为
前面几个工具都是看“静态配置”,但信号到底有没有真正递达,还得靠 strace 来抓现场。这对于调试 handler 是否生效、是否被屏蔽拦截,几乎是唯一可靠的方法。
- 运行
strace -p,进程一收到信号就会打印类似-e trace=signal --- SIGUSR1 {si_signo=SIGUSR1, si_code=SI_USER, si_pid=12345, si_uid=1000} ---的输出 - 如果全程没有任何输出,说明信号压根没递达——要么是被屏蔽了(
SigBlk中对应位为 1),要么是发错了 PID,或者权限不足 - 加
-f可以跟踪子进程;用strace -e signal=SIGUSR1可以只过滤特定信号,避免日志刷屏 - 不过有一点必须提醒:strace 本身会干扰信号传递路径,比如某些信号会被它截获。所以 strace 适合做诊断,不适合在生产环境长期挂着
用 kill -l 和 man 7 signal 查信号编号与默认动作
还有一个很容易被忽视的点:信号编号和默认动作,很多人都是凭印象记的,但掉坑往往就是从这里开始的。
kill -l输出信号名与编号的映射关系。注意:SIGUSR1是 10,不是 1;SIGRTMIN起才是实时信号(34+)man 7 signal明确列出每个信号的默认动作,比如Term(终止)、Ign(忽略)、Core(生成 core 文件)、Stop(暂停)等。举个例子:SIGCHLD默认是Ign,SIGPIPE默认是Term- 千万别靠记忆。比如
SIGHUP是 1,但某些旧系统可能有过不同定义。始终以kill -l的输出为准 - 如果自定义 handler 后行为异常,先查手册确认这个信号是否允许被忽略——
SIGKILL和SIGSTOP是既不能捕获也不能忽略的,这一点很多人到翻车时才想起来
可以看到,信号状态分散在好几个地方,ps 看注册,/proc 看位图,strace 看实际递达——几个窗口一对照,真相就清楚了。最容易被忽略的其实是 SigPnd 和 SigBlk 的关系:如果一个信号出现在 SigPnd 中,同时又在 SigBlk 里被置位,那就说明它卡住了,永远无法递达。这才是需要留意的关键点。


































