blob: b2d75d06030b7341776d3e1d05f178030bbb4c8a [file] [log] [blame]
Sasha Goldshtein25933782017-03-09 14:37:50 +00001#!/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
15from bcc import BPF, USDT
16import argparse
17import re
Sasha Goldshtein563af792017-02-14 11:09:13 -050018import os
Sasha Goldshtein25933782017-03-09 14:37:50 +000019import subprocess
20
21examples = """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"""
26parser = argparse.ArgumentParser(
27 description="Display processes currently using BPF programs and maps",
28 formatter_class=argparse.RawDescriptionHelpFormatter,
29 epilog=examples)
30parser.add_argument("-v", "--verbosity", action="count", default=0,
31 help="count and display kprobes/uprobes as well")
32args = parser.parse_args()
33
34def comm_for_pid(pid):
35 try:
36 return open("/proc/%d/comm" % pid).read().strip()
37 except:
38 return "[unknown]"
39
40counts = {}
41
42def parse_probes(typ):
43 if args.verbosity > 1: print("open %ss:" % typ)
44 for probe in open("/sys/kernel/debug/tracing/%s_events" % typ):
45 # Probes opened by bcc have a specific pattern that includes the pid
46 # of the requesting process.
47 match = re.search('_bcc_(\\d+)\\s', probe)
48 if match:
49 pid = int(match.group(1))
50 counts[(pid, typ)] = counts.get((pid, typ), 0) + 1
51 if args.verbosity > 1: print(probe.strip())
52 if args.verbosity > 1: print("")
53
54if args.verbosity > 0:
55 parse_probes("kprobe")
56 parse_probes("uprobe")
57
Sasha Goldshtein563af792017-02-14 11:09:13 -050058def find_bpf_fds(pid):
59 root = '/proc/%d/fd' % pid
60 for fd in os.listdir(root):
61 try:
62 link = os.readlink(os.path.join(root, fd))
63 except OSError:
64 continue
65 match = re.match('.*bpf-(\\w+)', link)
66 if match:
67 tup = (pid, match.group(1))
68 counts[tup] = counts.get(tup, 0) + 1
69
70for pdir in os.listdir('/proc'):
71 if re.match('\\d+', pdir):
72 find_bpf_fds(int(pdir))
Sasha Goldshtein25933782017-03-09 14:37:50 +000073
74print("%-6s %-16s %-8s %s" % ("PID", "COMM", "TYPE", "COUNT"))
75for (pid, typ), count in sorted(counts.items(), key=lambda t: t[0][0]):
76 comm = comm_for_pid(pid)
77 print("%-6d %-16s %-8s %-4d" % (pid, comm, typ, count))