1 #!/usr/bin/python 2 # 3 # bpflist Display processes currently using BPF programs and maps, 4 # pinned BPF programs and maps, and enabled probes. 5 # 6 # USAGE: bpflist [-v] 7 # 8 # Idea by Brendan Gregg. 9 # 10 # Copyright 2017, Sasha Goldshtein 11 # Licensed under the Apache License, Version 2.0 12 # 13 # 09-Mar-2017 Sasha Goldshtein Created this. 14 15 from bcc import BPF, USDT 16 import argparse 17 import re 18 import os 19 import subprocess 20 21 examples = """examples: 22 bpflist # display all processes currently using BPF 23 bpflist -v # also count kprobes/uprobes 24 bpflist -vv # display kprobes/uprobes and count them 25 """ 26 parser = argparse.ArgumentParser( 27 description="Display processes currently using BPF programs and maps", 28 formatter_class=argparse.RawDescriptionHelpFormatter, 29 epilog=examples) 30 parser.add_argument("-v", "--verbosity", action="count", default=0, 31 help="count and display kprobes/uprobes as well") 32 args = parser.parse_args() 33 34 def comm_for_pid(pid): 35 try: 36 return open("/proc/%d/comm" % pid).read().strip() 37 except: 38 return "[unknown]" 39 40 counts = {} 41 42 def parse_probes(typ): 43 if args.verbosity > 1: 44 print("open %ss:" % typ) 45 for probe in open("/sys/kernel/debug/tracing/%s_events" % typ): 46 # Probes opened by bcc have a specific pattern that includes the pid 47 # of the requesting process. 48 match = re.search('_bcc_(\\d+)\\s', probe) 49 if match: 50 pid = int(match.group(1)) 51 counts[(pid, typ)] = counts.get((pid, typ), 0) + 1 52 if args.verbosity > 1: 53 print(probe.strip()) 54 if args.verbosity > 1: 55 print("") 56 57 if args.verbosity > 0: 58 parse_probes("kprobe") 59 parse_probes("uprobe") 60 61 def find_bpf_fds(pid): 62 root = '/proc/%d/fd' % pid 63 for fd in os.listdir(root): 64 try: 65 link = os.readlink(os.path.join(root, fd)) 66 except OSError: 67 continue 68 match = re.match('.*bpf-(\\w+)', link) 69 if match: 70 tup = (pid, match.group(1)) 71 counts[tup] = counts.get(tup, 0) + 1 72 73 for pdir in os.listdir('/proc'): 74 if re.match('\\d+', pdir): 75 try: 76 find_bpf_fds(int(pdir)) 77 except OSError: 78 continue 79 print("%-6s %-16s %-8s %s" % ("PID", "COMM", "TYPE", "COUNT")) 80 for (pid, typ), count in sorted(counts.items(), key=lambda t: t[0][0]): 81 comm = comm_for_pid(pid) 82 print("%-6d %-16s %-8s %-4d" % (pid, comm, typ, count)) 83