Commit 3da7b4a3 authored by Brendan Gregg's avatar Brendan Gregg Committed by GitHub

Merge pull request #1043 from goldshtn/bpflist

bpflist: Display processes with running BPF programs and maps
parents d5d37b2c 25933785
......@@ -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).
......
.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
#!/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))
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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment