发布于2026-07-01 阅读(0)
扫一扫,手机访问
先说一句,信号在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,19sig 字段是阻塞掩码,不是 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() 设置过的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 可以只过滤特定信号,避免日志刷屏kill -l 和 man 7 signal 查信号编号与默认动作还有一个很容易被忽视的点:信号编号和默认动作,很多人都是凭印象记的,但掉坑往往就是从这里开始的。
kill -l 输出信号名与编号的映射关系。注意:SIGUSR1 是 10,不是 1;SIGRTMIN 起才是实时信号(34+)man 7 signal 明确列出每个信号的默认动作,比如 Term(终止)、Ign(忽略)、Core(生成 core 文件)、Stop(暂停)等。举个例子:SIGCHLD 默认是 Ign,SIGPIPE 默认是 TermSIGHUP 是 1,但某些旧系统可能有过不同定义。始终以 kill -l 的输出为准SIGKILL 和 SIGSTOP 是既不能捕获也不能忽略的,这一点很多人到翻车时才想起来可以看到,信号状态分散在好几个地方,ps 看注册,/proc 看位图,strace 看实际递达——几个窗口一对照,真相就清楚了。最容易被忽略的其实是 SigPnd 和 SigBlk 的关系:如果一个信号出现在 SigPnd 中,同时又在 SigBlk 里被置位,那就说明它卡住了,永远无法递达。这才是需要留意的关键点。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
4
5
6
7
8
9