当前位置: 首页 > 科技观察

Linux如何找到发出kill-9信号的真凶?

时间:2023-03-12 05:03:45 科技观察

生产环境遇到了一个神奇的问题。某个进程运行一段时间后,就莫名其妙的被kill掉了。开始怀疑是被操作系统的OOMkiller杀掉了,后来查看dmesg日志和系统内存监控数据,发现内存足够,没有达到cgrouplimit,又是OMMkiller排除了操作系统。应该是被其他进程kill掉了,但是系统中进程那么多,怎么知道是哪个进程发出了kill信号呢?我们知道无法屏蔽sigkill(kill-9),不允许handler注册。今天给大家介绍一个神器bpftrace。上一篇BPF入门文章介绍了通过bpf拦截sys_clone系统调用。原理类似,我们可以通过bpftrace拦截kill系统调用,从而找出杀死进程的罪魁祸首。脚本很简单,如下图,主要是在进入系统调用sys_enter_kill注册和结束系统调用sys_exit_kill时获取并打印信号的pid和信号号。BEGIN{printf("Tracingkill()信号...HitCtrl-Ctoend.\n");printf("%-9s%-6s%-16s%-4s%-6s%s\n","TIME","PID","COMM","SIG","TPID","RESULT");}tracepoint:syscalls:sys_enter_kill{@tpid[tid]=args->pid;@tsig[tid]=args->sig;}跟踪点:系统调用:sys_exit_kill/@tpid[tid]/{time("%H:%M:%S");printf("%-6d%-16s%-4d%-6d%d\n",pid,comm,@tsig[tid],@tpid[tid],args->ret);delete(@tpid[tid]);delete(@tsig[tid]);}我们可以先开始sleepDemo测试#sleep444之后执行上面的脚本,使用“kill-9”杀死上面的sleep任务,脚本输出如下:信号,COMM代表发送信号OK的进程命令,由于kill-9是在bash环境下执行的,所以这里显示bash,SIG代表信号编号,本例中为kill-9信号,TPID为睡眠任务的线程ID,RESULT代表execution结果,0代表成功。“杀手”和“受害者”都已成功上映。最后通过上面的脚本找到了系统上的一个自动清理程序,由于使用通配符导致误杀。