专栏首页专注网络研发揭开服务程序“被杀”之谜

揭开服务程序“被杀”之谜

在日常工作中,服务程序(daemon)意外退出,一般是由以下几个原因导致的:

  1. 程序自身bug;
  2. 被OS oom killer杀掉;
  3. 操作人员误杀;
  4. 被第三方程序杀掉;

对于第一种情况,一般可以通过coredump看出。第二个种情况,也可以通过dmesg找到线索(一般是被oom killer杀掉)。但是当后两种情况出现时,往往是大家最抓瞎最手足无措的时候。

本文将介绍多种方法来帮助大家揭开服务(daemon)被杀之谜。

首先先创建一个daemon

#!/bin/bash
while : ; do    sleep 1done

然后在后台运行这个daemon.sh。

第一个方法:ftrace

使用命令

echo 1 > /sys/kernel/tracing/events/signal/enable

使用命令killall daemon.sh杀掉daemon.sh。

然后查看ftrace的输出,cat /sys/kernel/tracing/trace

如红色箭头所指,可以清晰的看出killall命令,给进程daemon.sh(pid为3615)发送了SIGTERM(即sig=15)。

第二个方法:systemtap

编写systemtap脚本,来探测kill调用。

probe syscall.kill{    if (pid2execname(u32_arg(1)) == @1)            printf("%s(%d) kill %s with (%s)\n", execname(), pid(), pid2execname(u32_arg(1)), argstr);}

简单介绍一下脚本。

  1. 该脚本接受一个参数@1,表示要监视的服务进程名称。
  2. u32_arg(1)获得kill系统调用的第一个参数,也就是目标pid。然后调用systemtap的函数pid2execname得到该pid的进程名。
  3. 当条件为真时,表明kill要发送的目标pid就是我们要监视服务进程。 然后打印调用者的进程名称(execname)和其pid。最后使用通过systemtap的argstr,打印kill的完整参数

看一下执行效果

第三个方法:bpftrace

bpftrace是Brendan Gregg使用bpf开发的一套trace工具。对于当前问题,我们选择其中的killsnoop来trace kill调用。

重复之前的操作,可以看到killsnoop侦测到了killall发送了SIG 15也就是SIGTERM给TPID 9216,也就是我们的daemon.sh。

第四个方法:bcc

bcc与systemtap类似,是一个可以编写ebpf的工具集。除了可以直接编写ebpf程序外,它也提供了一套与bpftrace相似的现成工具,并提供了更多的选项。

对于当前的问题,也只能使用默认行为,监控所有的kill调用。但bcc的killsnoop可以trace指定pid,来追踪指定pid进程的kill调用。

第五个方法:直接编写bpftrace代码

在第三个方法中,我们直接使用bpftrace提供的现成工具,实际上我们也可以编写bpftrace来完成这个任务。

#!/usr/bin/bpftrace
tracepoint:syscalls:sys_enter_kill {    if ($1 == args->pid) {        printf("process %s send signal%d to pid %d\n", comm, args->sig, args->pid);    }}

在上面的代码中,我们根据kill这个系统调用,然后打印发送信号的进程名,信号值,以及目标pid。当目标pid与第一个参数,即我们要监控的process,就进行打印。

虽然会有一个告警,但我们这里可以忽略到。

其实除了上面的5种方法外,还会有其它方案来搞定这个问题,比如直接编写ebpf程序,等等。不过我认为上面5种方法,基本上已经可以覆盖绝大部分的场景了。

如果大家还有更好的方法,欢迎留言分享~~~

本文分享自微信公众号 - LinuxerPub(LinuxerPub),作者:glinuxer

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-06-02

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Linux内核数据包skb的流程图(1)

    最近要给团队做一个长期的内部分享,主题就是Linux内核中数据包的处理流程。

    glinuxer
  • 系统编程语言Rust特点介绍(1)

    最近在学习Rust语言,感觉这门语言有点意思,因此写一篇文章分享。我不会去介绍Rust的基本语法,什么变量声明,if..else..,循环等等。这些东西,文档介...

    glinuxer
  • TCP的MTU Probe和MSS(2)

    在上一篇《TCP的MTU Probe和MSS(1)》介绍了TCP使用MTU Probe来避免PMTU变小而导致发送失败的方法。其主要思想是在TC...

    glinuxer
  • Glimmer:识别微生物中的蛋白编码基因

    Glimmer软件采用马尔科夫模型识别微生物中的蛋白编码基因,主要是针对细菌,古菌和病毒。该软件由The Institute for Genomic Resea...

    生信修炼手册
  • jinfo Java配置信息工具

      jinfo 还可以使用 -sysprops 选项把虚拟机进程的 System.getProperties() 的内容打印出来。在运行期修改参数使用-flag...

    GreizLiao
  • ​业务双活的数据切换思路设计(下)

    在完成数据迁移,数据同步之后,目前的流量是在“已有数据服务”侧,如果要实现服务的平滑迁移,我们可以按照这个流程来进行设计。

    jeanron100
  • 决战9小时,产品上线的危机时刻

    ? 游戏公司正在经历异常凛冽的寒冬,对于专注于游戏行业攻击的黑客们而言,同样也是隐匿于黑暗的潜伏期。随着版号的开放,黑客如同伺机而动的毒蛇开始发动DDoS勒索...

    腾讯技术工程官方号
  • 系统负载能力浅析

    系统负载能力浅析 互联网时代,高并发是一个老生常谈的话题。无论对于一个web站点还是app应用,高峰时能承载的并发请求都是衡量一个系统性能的关键标志。像阿里双十...

    小小科
  • kubernete编排技术四:Job和CronJob

    这篇文章我们学习一下kubernete对Job的编排。不同于前面讲的Deployment、StatefulSet的编排,Job是一个执行一次就结束的pod,并不...

    jinjunzhu
  • Sentinel——自定义URL限流异常

    目标:Sentinel的基本应用 工具:IDEA--2020.1、Sentinel Maven 学习目标:学习Sentinel的自定义URL限流异常 本次学习的...

    背雷管的小青年

扫码关注云+社区

领取腾讯云代金券