blob: f73e945accc54a2ccd7f0c6efb911e6060b822ee [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):
Paul Chaignone617bf42017-10-07 11:06:17 +020043 if args.verbosity > 1:
44 print("open %ss:" % typ)
Sasha Goldshtein25933782017-03-09 14:37:50 +000045 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
Paul Chaignone617bf42017-10-07 11:06:17 +020052 if args.verbosity > 1:
53 print(probe.strip())
54 if args.verbosity > 1:
55 print("")
Sasha Goldshtein25933782017-03-09 14:37:50 +000056
57if args.verbosity > 0:
58 parse_probes("kprobe")
59 parse_probes("uprobe")
60
Sasha Goldshtein563af792017-02-14 11:09:13 -050061def 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
73for pdir in os.listdir('/proc'):
74 if re.match('\\d+', pdir):
Nikita V. Shirokov98ee5df2018-04-18 09:41:10 -070075 try:
76 find_bpf_fds(int(pdir))
77 except OSError:
78 continue
Sasha Goldshtein25933782017-03-09 14:37:50 +000079print("%-6s %-16s %-8s %s" % ("PID", "COMM", "TYPE", "COUNT"))
80for (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))