进程莫名被SIGINT杀死 strace显示si_pid/si_uid为0原因排查
进程异常被SIGINT杀死排查问题
问题背景
- 故障现象:部分进程在无手动按下
CTRL + C操作的前提下,莫名被SIGINT信号杀死 - 排查操作:对PID为61571的异常进程使用
strace追踪信号相关系统调用,捕获到如下日志:
> strace -p 61571 -e trace=signal strace: Process 61571 attached --- SIGINT {si_signo=SIGINT, si_code=SI_USER, si_pid=0, si_uid=0} --- +++ killed by SIGINT +++
- 待确认疑问:
- 已知
SI_USER标记代表信号由kill、sigsend、raise或abort接口发送,该字段是否对本次排查没有参考价值? - 捕获结果中
si_pid和si_uid字段均为0,该取值代表什么含义?是否是信号相关结构体仅做零初始化导致?
- 已知
解答
关于SI_USER字段的参考价值
SI_USER字段有明确的排查指向性,并非无参考价值:
- 该字段首先可以彻底排除一类信号来源:终端驱动触发的
CTRL+C信号、内核自身触发的信号、硬件异常触发的信号对应的si_code都不会是SI_USER,和你确认的“无手动按CTRL+C”的现象完全吻合。 - 它直接把排查范围缩小到用户态程序主动调用信号发送接口的场景,不需要再浪费时间排查终端配置、内核异常类问题。
关于si_pid=0、si_uid=0的含义
该取值不是结构体零初始化导致的,内核在填充siginfo_t结构时会严格按照信号发送上下文赋值,出现这个组合有两类典型场景:
- 信号是进程自己发给自己的:当进程调用
raise(SIGINT)向自身发送信号时,内核填充的si_pid固定为0;如果进程是root权限运行,对应的si_uid就是0。 - 信号来自跨PID命名空间的进程:如果业务运行在容器中,发送信号的进程处于宿主机或其他容器的PID命名空间,且该进程在被杀死进程所在的PID命名空间中没有可见的PID映射,内核就会将
si_pid置为0;如果发送信号的进程是root权限运行,si_uid就会显示为0。
后续排查建议
- 优先排查进程自身逻辑:检查业务代码、依赖的第三方库、嵌入的运行时是否存在主动调用
raise、abort或向自身PID发送SIGINT的逻辑。 - 容器场景优先排查容器1号进程:检查容器init进程(比如tini、业务entrypoint脚本)是否存在异常向子进程发送SIGINT的逻辑,同时排查宿主机上root权限运行的运维脚本、守护进程是否存在误杀逻辑。
- 全链路捕获可以配置
auditd审计规则,监控所有针对目标进程的kill系统调用,可直接拿到发送信号的进程路径、执行用户、命令行信息,定位效率比strace更高。
内容的提问来源于stack exchange,提问作者João Paulo
相关产品推荐
相关产品推荐

