Skip to content

Commit

Permalink
bpflist: Display processes with running BPF programs and maps
Browse files Browse the repository at this point in the history
This tool displays processes with running BPF programs and maps,
and also optionally kprobes and uprobes. This is a poor-man's version
that snoops BPF file descriptors, as proposed by @brendangregg.

Example:

```
PID    COMM             TYPE     COUNT
4058   fileslower       prog     4
4058   fileslower       map      2
4106   bashreadline     map      1
4106   bashreadline     prog     1
```

Resolves iovisor#1036.
  • Loading branch information
goldshtn committed Mar 9, 2017
1 parent 8968737 commit 2593378
Show file tree
Hide file tree
Showing 4 changed files with 198 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ pair of .c and .py files, and some are directories of files.
- tools/[biotop](tools/biotop.py): Top for disks: Summarize block device I/O by process. [Examples](tools/biotop_example.txt).
- tools/[biosnoop](tools/biosnoop.py): Trace block device I/O with PID and latency. [Examples](tools/biosnoop_example.txt).
- tools/[bitesize](tools/bitesize.py): Show per process I/O size histogram. [Examples](tools/bitesize_example.txt).
- tools/[bpflist](tools/bpflist.py): Display processes with active BPF programs and maps. [Examples](tools/bpflist_example.txt).
- tools/[btrfsdist](tools/btrfsdist.py): Summarize btrfs operation latency distribution as a histogram. [Examples](tools/btrfsdist_example.txt).
- tools/[btrfsslower](tools/btrfsslower.py): Trace slow btrfs operations. [Examples](tools/btrfsslower_example.txt).
- tools/[capable](tools/capable.py): Trace security capability checks. [Examples](tools/capable_example.txt).
Expand Down
60 changes: 60 additions & 0 deletions man/man8/bpflist.8
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
.TH bpflist 8 "2017-03-09" "USER COMMANDS"
.SH NAME
bpflist \- Display processes currently using BPF programs and maps.
.SH SYNOPSIS
.B bpflist [-v]
.SH DESCRIPTION
This tool displays processes currently using BPF programs and maps, and
optionally also kprobes and uprobes on the system. This is useful to understand
which BPF programs are loaded on the system.

Currently, for lack of a better alternative, this tool pipes into 'ls' and
parses its output to snoop for BPF file descriptors in all running processes.
In the future, when BPF accounting is provided by the kernel, this tool should
use these accounting features.

Only the root user can use this tool, because it accesses debugfs.
.SH REQUIREMENTS
bcc, debugfs
.SH OPTIONS
\-h
Print usage message.
.TP
\-v
Count kprobes and uprobes as well as BPF programs. Repeating verbose mode twice
also prints the kprobe and uprobe definitions in addition to counting them.
.SH EXAMPLES
.TP
Display processes currently using BPF programs:
#
.B bpflist
.TP
Also count kprobes and uprobes:
#
.B bpflist -v
.SH FIELDS
.TP
PID
Process ID.
.TP
COMM
Process comm.
.TP
TYPE
The type of the data displayed: BPF program, BPF map, kprobe, or uprobe.
.TP
COUNT
The number of items of this type that belong to the specified process.
.SH SOURCE
This is from bcc.
.IP
https://github.com/iovisor/bcc
.PP
Also look in the bcc distribution for a companion _examples.txt file containing
example usage, output, and commentary for this tool.
.SH OS
Linux
.SH STABILITY
Unstable - in development.
.SH AUTHOR
Sasha Goldshtein
71 changes: 71 additions & 0 deletions tools/bpflist.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#!/usr/bin/python
#
# bpflist Display processes currently using BPF programs and maps,
# pinned BPF programs and maps, and enabled probes.
#
# USAGE: bpflist [-v]
#
# Idea by Brendan Gregg.
#
# Copyright 2017, Sasha Goldshtein
# Licensed under the Apache License, Version 2.0
#
# 09-Mar-2017 Sasha Goldshtein Created this.

from bcc import BPF, USDT
import argparse
import re
import subprocess

examples = """examples:
bpflist # display all processes currently using BPF
bpflist -v # also count kprobes/uprobes
bpflist -vv # display kprobes/uprobes and count them
"""
parser = argparse.ArgumentParser(
description="Display processes currently using BPF programs and maps",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog=examples)
parser.add_argument("-v", "--verbosity", action="count", default=0,
help="count and display kprobes/uprobes as well")
args = parser.parse_args()

def comm_for_pid(pid):
try:
return open("/proc/%d/comm" % pid).read().strip()
except:
return "[unknown]"

counts = {}

def parse_probes(typ):
if args.verbosity > 1: print("open %ss:" % typ)
for probe in open("/sys/kernel/debug/tracing/%s_events" % typ):
# Probes opened by bcc have a specific pattern that includes the pid
# of the requesting process.
match = re.search('_bcc_(\\d+)\\s', probe)
if match:
pid = int(match.group(1))
counts[(pid, typ)] = counts.get((pid, typ), 0) + 1
if args.verbosity > 1: print(probe.strip())
if args.verbosity > 1: print("")

if args.verbosity > 0:
parse_probes("kprobe")
parse_probes("uprobe")

cmd = "ls -l /proc/*/fd/* | grep bpf"
p = subprocess.Popen(cmd, shell=True,
stderr=subprocess.PIPE, stdout=subprocess.PIPE)
for line in p.stdout:
match = re.search('/proc/(\\d+)/fd/\\d+.*bpf-(\\w+)', line)
if match is None:
continue
pid = int(match.group(1))
t = match.group(2)
counts[(pid, t)] = counts.get((pid, t), 0) + 1

print("%-6s %-16s %-8s %s" % ("PID", "COMM", "TYPE", "COUNT"))
for (pid, typ), count in sorted(counts.items(), key=lambda t: t[0][0]):
comm = comm_for_pid(pid)
print("%-6d %-16s %-8s %-4d" % (pid, comm, typ, count))
66 changes: 66 additions & 0 deletions tools/bpflist_example.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
Demonstrations of bpflist.


bpflist displays information on running BPF programs and optionally also
prints open kprobes and uprobes. It is used to understand which BPF programs
are currently running on the system. For example:

# bpflist
PID COMM TYPE COUNT
4058 fileslower prog 4
4058 fileslower map 2
4106 bashreadline map 1
4106 bashreadline prog 1

From the output above, the fileslower and bashreadline tools are running.
fileslower has installed 4 BPF programs (functions) and has opened 2 BPF maps
(such as hashes, histograms, stack trace tables, and so on).

In verbose mode, bpflist also counts the number of kprobes and uprobes opened
by the process. This information is obtained heuristically: bcc-based tools
include the process id in the name of the probe. For example:

# bpflist -v
PID COMM TYPE COUNT
4058 fileslower prog 4
4058 fileslower kprobe 4
4058 fileslower map 2
4106 bashreadline uprobe 1
4106 bashreadline prog 1
4106 bashreadline map 1

In double-verbose mode, the probe definitions are also displayed:

# bpflist -vv
open kprobes:
p:kprobes/p___vfs_read_bcc_4058 __vfs_read
r:kprobes/r___vfs_read_bcc_4058 __vfs_read
p:kprobes/p___vfs_write_bcc_4058 __vfs_write
r:kprobes/r___vfs_write_bcc_4058 __vfs_write

open uprobes:
r:uprobes/r__bin_bash_0xa4dd0_bcc_4106 /bin/bash:0x00000000000a4dd0

PID COMM TYPE COUNT
4058 fileslower prog 4
4058 fileslower kprobe 4
4058 fileslower map 2
4106 bashreadline uprobe 1
4106 bashreadline prog 1
4106 bashreadline map 1


USAGE:
# bpflist -h
usage: bpflist.py [-h] [-v]

Display processes currently using BPF programs and maps

optional arguments:
-h, --help show this help message and exit
-v, --verbosity count and display kprobes/uprobes as well

examples:
bpflist # display all processes currently using BPF
bpflist -v # also count kprobes/uprobes
bpflist -vv # display kprobes/uprobes and count them

0 comments on commit 2593378

Please sign in to comment.