blob: 663c8101e871deb7fe1039ba1c16b60f8a70ab8a [file] [log] [blame]
Alexey Ivanovcc01a9c2019-01-16 09:50:46 -08001#!/usr/bin/python
Alexei Starovoitovbdf07732016-01-14 10:09:20 -08002# @lint-avoid-python-3-compatibility-imports
Brendan Greggd9e578b2015-09-21 11:59:42 -07003#
Alexei Starovoitovbdf07732016-01-14 10:09:20 -08004# killsnoop Trace signals issued by the kill() syscall.
5# For Linux, uses BCC, eBPF. Embedded C.
Brendan Greggd9e578b2015-09-21 11:59:42 -07006#
Junli Ou5eee5ff2016-08-13 17:12:45 +08007# USAGE: killsnoop [-h] [-x] [-p PID]
Brendan Greggd9e578b2015-09-21 11:59:42 -07008#
9# Copyright (c) 2015 Brendan Gregg.
10# Licensed under the Apache License, Version 2.0 (the "License")
11#
Alexei Starovoitovbdf07732016-01-14 10:09:20 -080012# 20-Sep-2015 Brendan Gregg Created this.
mcaleavyaf5c40cb2016-02-19 23:02:39 +000013# 19-Feb-2016 Allan McAleavy migrated to BPF_PERF_OUTPUT
Brendan Greggd9e578b2015-09-21 11:59:42 -070014
15from __future__ import print_function
16from bcc import BPF
Brenden Blancoe8001c32018-07-23 08:15:56 -070017from bcc.utils import ArgString, printb
Brendan Greggd9e578b2015-09-21 11:59:42 -070018import argparse
Junli Ou5eee5ff2016-08-13 17:12:45 +080019from time import strftime
Brendan Greggd9e578b2015-09-21 11:59:42 -070020
21# arguments
22examples = """examples:
23 ./killsnoop # trace all kill() signals
Brendan Greggd9e578b2015-09-21 11:59:42 -070024 ./killsnoop -x # only show failed kills
25 ./killsnoop -p 181 # only trace PID 181
synical7cecd792020-05-26 11:16:52 -040026 ./killsnoop -s 9 # only trace signal 9
Brendan Greggd9e578b2015-09-21 11:59:42 -070027"""
28parser = argparse.ArgumentParser(
Alexei Starovoitovbdf07732016-01-14 10:09:20 -080029 description="Trace signals issued by the kill() syscall",
30 formatter_class=argparse.RawDescriptionHelpFormatter,
31 epilog=examples)
Brendan Greggd9e578b2015-09-21 11:59:42 -070032parser.add_argument("-x", "--failed", action="store_true",
Chris Down8ddcbdf2016-07-13 15:18:35 +010033 help="only show failed kill syscalls")
Brendan Greggd9e578b2015-09-21 11:59:42 -070034parser.add_argument("-p", "--pid",
Alexei Starovoitovbdf07732016-01-14 10:09:20 -080035 help="trace this PID only")
synical076a3542020-05-23 12:40:09 -040036parser.add_argument("-s", "--signal",
37 help="trace this signal only")
Nathan Scottcf0792f2018-02-02 16:56:50 +110038parser.add_argument("--ebpf", action="store_true",
39 help=argparse.SUPPRESS)
Brendan Greggd9e578b2015-09-21 11:59:42 -070040args = parser.parse_args()
41debug = 0
42
43# define BPF program
44bpf_text = """
45#include <uapi/linux/ptrace.h>
mcaleavyaf5c40cb2016-02-19 23:02:39 +000046#include <linux/sched.h>
47
48struct val_t {
49 u64 pid;
mcaleavya6262f5d2016-02-19 23:48:20 +000050 int sig;
51 int tpid;
mcaleavyaf5c40cb2016-02-19 23:02:39 +000052 char comm[TASK_COMM_LEN];
53};
54
55struct data_t {
56 u64 pid;
Brendan Gregg12989982016-09-14 08:15:09 -070057 int tpid;
mcaleavyaf5c40cb2016-02-19 23:02:39 +000058 int sig;
59 int ret;
mcaleavyaf5c40cb2016-02-19 23:02:39 +000060 char comm[TASK_COMM_LEN];
61};
Brendan Greggd9e578b2015-09-21 11:59:42 -070062
mcaleavyaf5c40cb2016-02-19 23:02:39 +000063BPF_HASH(infotmp, u32, struct val_t);
64BPF_PERF_OUTPUT(events);
Brendan Greggd9e578b2015-09-21 11:59:42 -070065
yonghong-song2da34262018-06-13 06:12:22 -070066int syscall__kill(struct pt_regs *ctx, int tpid, int sig)
Brendan Greggd9e578b2015-09-21 11:59:42 -070067{
Hengqi Chenf0a0dc72021-05-20 22:49:25 +080068 u64 pid_tgid = bpf_get_current_pid_tgid();
69 u32 pid = pid_tgid >> 32;
70 u32 tid = (u32)pid_tgid;
71
synical076a3542020-05-23 12:40:09 -040072 PID_FILTER
73 SIGNAL_FILTER
Brendan Gregg12989982016-09-14 08:15:09 -070074
75 struct val_t val = {.pid = pid};
mcaleavyaf5c40cb2016-02-19 23:02:39 +000076 if (bpf_get_current_comm(&val.comm, sizeof(val.comm)) == 0) {
mcaleavya6262f5d2016-02-19 23:48:20 +000077 val.tpid = tpid;
78 val.sig = sig;
Hengqi Chenf0a0dc72021-05-20 22:49:25 +080079 infotmp.update(&tid, &val);
mcaleavyaf5c40cb2016-02-19 23:02:39 +000080 }
Brendan Greggd9e578b2015-09-21 11:59:42 -070081
Alexei Starovoitovbdf07732016-01-14 10:09:20 -080082 return 0;
Brendan Greggd9e578b2015-09-21 11:59:42 -070083};
84
Yonghong Song64335692018-04-25 00:40:13 -070085int do_ret_sys_kill(struct pt_regs *ctx)
Brendan Greggd9e578b2015-09-21 11:59:42 -070086{
mcaleavyaf5c40cb2016-02-19 23:02:39 +000087 struct data_t data = {};
88 struct val_t *valp;
Hengqi Chenf0a0dc72021-05-20 22:49:25 +080089 u64 pid_tgid = bpf_get_current_pid_tgid();
90 u32 pid = pid_tgid >> 32;
91 u32 tid = (u32)pid_tgid;
Brendan Greggd9e578b2015-09-21 11:59:42 -070092
Hengqi Chenf0a0dc72021-05-20 22:49:25 +080093 valp = infotmp.lookup(&tid);
mcaleavyaf5c40cb2016-02-19 23:02:39 +000094 if (valp == 0) {
95 // missed entry
96 return 0;
97 }
98
Sumanth Korikkar7f6066d2020-05-20 10:49:56 -050099 bpf_probe_read_kernel(&data.comm, sizeof(data.comm), valp->comm);
mcaleavyaf5c40cb2016-02-19 23:02:39 +0000100 data.pid = pid;
mcaleavya6262f5d2016-02-19 23:48:20 +0000101 data.tpid = valp->tpid;
Naveen N. Rao4afa96a2016-05-03 14:54:21 +0530102 data.ret = PT_REGS_RC(ctx);
mcaleavya6262f5d2016-02-19 23:48:20 +0000103 data.sig = valp->sig;
mcaleavyaf5c40cb2016-02-19 23:02:39 +0000104
105 events.perf_submit(ctx, &data, sizeof(data));
Hengqi Chenf0a0dc72021-05-20 22:49:25 +0800106 infotmp.delete(&tid);
Brendan Greggd9e578b2015-09-21 11:59:42 -0700107
Alexei Starovoitovbdf07732016-01-14 10:09:20 -0800108 return 0;
Brendan Greggd9e578b2015-09-21 11:59:42 -0700109}
110"""
111if args.pid:
synical076a3542020-05-23 12:40:09 -0400112 bpf_text = bpf_text.replace('PID_FILTER',
Alexei Starovoitovbdf07732016-01-14 10:09:20 -0800113 'if (pid != %s) { return 0; }' % args.pid)
Brendan Greggd9e578b2015-09-21 11:59:42 -0700114else:
synical076a3542020-05-23 12:40:09 -0400115 bpf_text = bpf_text.replace('PID_FILTER', '')
116if args.signal:
117 bpf_text = bpf_text.replace('SIGNAL_FILTER',
118 'if (sig != %s) { return 0; }' % args.signal)
119else:
120 bpf_text = bpf_text.replace('SIGNAL_FILTER', '')
Nathan Scottcf0792f2018-02-02 16:56:50 +1100121if debug or args.ebpf:
Alexei Starovoitovbdf07732016-01-14 10:09:20 -0800122 print(bpf_text)
Nathan Scottcf0792f2018-02-02 16:56:50 +1100123 if args.ebpf:
124 exit()
Brendan Greggd9e578b2015-09-21 11:59:42 -0700125
126# initialize BPF
127b = BPF(text=bpf_text)
Yonghong Song64335692018-04-25 00:40:13 -0700128kill_fnname = b.get_syscall_fnname("kill")
yonghong-song2da34262018-06-13 06:12:22 -0700129b.attach_kprobe(event=kill_fnname, fn_name="syscall__kill")
Yonghong Song64335692018-04-25 00:40:13 -0700130b.attach_kretprobe(event=kill_fnname, fn_name="do_ret_sys_kill")
131
Brendan Greggd9e578b2015-09-21 11:59:42 -0700132# header
Junli Ou5eee5ff2016-08-13 17:12:45 +0800133print("%-9s %-6s %-16s %-4s %-6s %s" % (
134 "TIME", "PID", "COMM", "SIG", "TPID", "RESULT"))
Brendan Greggd9e578b2015-09-21 11:59:42 -0700135
mcaleavyaf5c40cb2016-02-19 23:02:39 +0000136# process event
137def print_event(cpu, data, size):
Xiaozhou Liu51d62d32019-02-15 13:03:05 +0800138 event = b["events"].event(data)
Brendan Greggd9e578b2015-09-21 11:59:42 -0700139
Brendan Gregg12989982016-09-14 08:15:09 -0700140 if (args.failed and (event.ret >= 0)):
141 return
Brendan Greggd9e578b2015-09-21 11:59:42 -0700142
yonghong-song1d234802018-10-11 08:32:04 -0700143 printb(b"%-9s %-6d %-16s %-4d %-6d %d" % (strftime("%H:%M:%S").encode('ascii'),
Brenden Blancoe8001c32018-07-23 08:15:56 -0700144 event.pid, event.comm, event.sig, event.tpid, event.ret))
mcaleavyaf5c40cb2016-02-19 23:02:39 +0000145
146# loop with callback to print_event
147b["events"].open_perf_buffer(print_event)
148while 1:
Jerome Marchand51671272018-12-19 01:57:24 +0100149 try:
150 b.perf_buffer_poll()
151 except KeyboardInterrupt:
152 exit()