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