Linux如何找到发出 kill -9 信号的真凶?
2023-03-15 22:45:45 时间
生产环境遇到一个神奇的问题,某个进程运行一段时间后,就莫名其妙地被干掉了。初步怀疑是被操作系统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. ");
- printf("%-9s %-6s %-16s %-4s %-6s %s ", "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 ", 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代表成功。”杀手“和”受害者“都已经成功显示。
最终通过上面的脚本找到了系统上面一个自动清理程序,由于使用了通配符导致误杀的情况。
相关文章
- 金融服务领域的大数据:即时分析
- 影响大数据、机器学习和人工智能未来发展的8个因素
- 从0开始构建一个属于你自己的PHP框架
- 如何将Hadoop集成到工作流程中?这6个优秀实践必看
- SEO公司使用大数据优化其模型的5种方法
- 关于Web Workers你需要了解的七件事
- 深入理解HTTPS原理、过程与实践
- 增强分析:数据和分析的未来
- PHP协程实现过程详解
- AI专家:大数据知识图谱——实战经验总结
- 关于PHP的错误机制总结
- 利用数据分析量化协同过滤算法的两大常见难题
- 怎么做大数据工作流调度系统?大厂架构师一语点破!
- 2019大数据处理必备的十大工具,从Linux到架构师必修
- OpenCV中的KMeans算法介绍与应用
- 教大家如果搭建一套phpstorm+wamp+xdebug调试PHP的环境
- CentOS下三种PHP拓展安装方法
- Go语言HTTP Server源码分析
- Go语言HTTP Server源码分析
- 2017年4月编程语言排行榜:Hack首次进入前五十