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

发表于:2021-7-13 09:14

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:云技术趣谈    来源:今日头条

  生产环境遇到一个神奇的问题,某个进程运行一段时间后,就莫名其妙地被干掉了。初步怀疑是被操作系统OOM killer干掉的,但查看了dmesg日志以及系统内存监控数据,发现内存充足也没有达到cgroup限制,排除了操作系统OMM killer干的。
  应该是被其他进程干掉了,但系统里面进程这么多,怎么知道是哪个进程发出的kill信号呢?我们知道,sigkill(kill -9)是无法屏蔽并且不允许注册handler的。
  今天给大家介绍一个神器bpftrace,之前介绍BPF入门的文章里面已经介绍了通过bpf拦截sys_clone系统调用了。原理类似,我们可以通过bpftrace拦截kill系统调用,从而找出杀死进程的罪魁祸首。
  脚本非常简单,如下所示,主要就是在进入系统调用sys_enter_kill注册 以及 结束系统调用sys_exit_kill的时候获取并打印发出信号的pid和信号编号。
  BEGIN 
  { 
      printf("Tracing kill() signals... Hit Ctrl-C to end.\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; 
  } 
   
  tracepoint:syscalls: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]); 
  } 
  我们可以先启动一个sleep的Demo测试
  # sleep 444 
  执行上面的脚本后,通过 ”kill -9 “杀死上面启动sleep 任务,可以脚本输出如下:
  TIME      PID    COMM             SIG  TPID   RESULT 
  11:38:43  2837583 bash             9    2837548 0 
  其中,TIME代表执行时间,PID代表发出信号的进程ID,COMM代表发出信号进程命令行,由于是在bash环境中执行的kill -9 所以这里显示bash,SIG代表信号编号,本例中是kill -9 信号,TPID是sleep任务的线程ID,RESULT代表执行结果,0代表成功。”杀手“和”受害者“都已经成功显示。
  最终通过上面的脚本找到了系统上面一个自动清理程序,由于使用了通配符导致误杀的情况。

      本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号