blob: ea9a843ab1074de158c306c091c172626b1e704c [file] [log] [blame]
Brendan Greggd9e578b2015-09-21 11:59:42 -07001#!/usr/bin/python
2#
3# killsnoop Trace signals issued by the kill() syscall.
4# For Linux, uses BCC, eBPF. Embedded C.
5#
6# USAGE: killsnoop [-h] [-t] [-x] [-p PID]
7#
8# Copyright (c) 2015 Brendan Gregg.
9# Licensed under the Apache License, Version 2.0 (the "License")
10#
11# 20-Sep-2015 Brendan Gregg Created this.
12
13from __future__ import print_function
14from bcc import BPF
15import argparse
16
17# arguments
18examples = """examples:
19 ./killsnoop # trace all kill() signals
20 ./killsnoop -t # include timestamps
21 ./killsnoop -x # only show failed kills
22 ./killsnoop -p 181 # only trace PID 181
23"""
24parser = argparse.ArgumentParser(
25 description="Trace signals issued by the kill() syscall",
26 formatter_class=argparse.RawDescriptionHelpFormatter,
27 epilog=examples)
28parser.add_argument("-t", "--timestamp", action="store_true",
29 help="include timestamp on output")
30parser.add_argument("-x", "--failed", action="store_true",
31 help="only show failed opens")
32parser.add_argument("-p", "--pid",
33 help="trace this PID only")
34args = parser.parse_args()
35debug = 0
36
37# define BPF program
38bpf_text = """
39#include <uapi/linux/ptrace.h>
40
41BPF_HASH(args_pid, u32, int);
42BPF_HASH(args_sig, u32, int);
43
44int kprobe__sys_kill(struct pt_regs *ctx, int tpid, int sig)
45{
46 u32 pid = bpf_get_current_pid_tgid();
47
48 FILTER
49 args_pid.update(&pid, &tpid);
50 args_sig.update(&pid, &sig);
51
52 return 0;
53};
54
55int kretprobe__sys_kill(struct pt_regs *ctx)
56{
57 int *tpidp, *sigp, ret = ctx->ax;
58 u32 pid = bpf_get_current_pid_tgid();
59
60 tpidp = args_pid.lookup(&pid);
61 sigp = args_sig.lookup(&pid);
62 if (tpidp == 0 || sigp == 0) {
63 return 0; // missed entry
64 }
65
66 bpf_trace_printk("%d %d %d\\n", *tpidp, *sigp, ret);
67 args_pid.delete(&pid);
68 args_sig.delete(&pid);
69
70 return 0;
71}
72"""
73if args.pid:
74 bpf_text = bpf_text.replace('FILTER',
75 'if (pid != %s) { return 0; }' % args.pid)
76else:
77 bpf_text = bpf_text.replace('FILTER', '')
78if debug:
79 print(bpf_text)
80
81# initialize BPF
82b = BPF(text=bpf_text)
83
84# header
85if args.timestamp:
86 print("%-14s" % ("TIME(s)"), end="")
87print("%-6s %-16s %-4s %-6s %s" % ("PID", "COMM", "SIG", "TPID", "RESULT"))
88
89start_ts = 0
90
91# format output
92while 1:
93 (task, pid, cpu, flags, ts, msg) = b.trace_fields()
94 (tpid_s, sig_s, ret_s) = msg.split(" ")
95
96 ret = int(ret_s)
97 if (args.failed and (ret >= 0)):
98 continue
99
100 # print columns
101 if args.timestamp:
102 if start_ts == 0:
103 start_ts = ts
104 print("%-14.9f" % (ts - start_ts), end="")
105 print("%-6d %-16s %-4s %-6s %s" % (pid, task, sig_s, tpid_s, ret_s))