Skip to main content
RunBook Academy

LinuxXLIII · eBPF and Advanced Observabilitybpftrace bcc

bpftrace and bcc - sysadmin use cases and examples

Advanced⏱ ~10 minbpftracebcc

What you'll learn

  • Write a bpftrace one-liner
  • Use bcc tools for common tasks, allowing for per-distribution tool naming
  • Trace latency at a syscall
  • Find the source of network drops

Prerequisites

Verified against Ubuntu 24.04 LTS · Debian 12 (Bookworm) · RHEL 9.x · Rocky Linux 9.x · AlmaLinux 9.x · Linux kernel 6.1 LTS / 6.6 LTS · systemd 255+ · OpenSSH 8.7p1 (RHEL 9) / 9.6p1 (Ubuntu 24.04) · nftables 1.0.x · chrony 4.x · Pacemaker 2.1.x · Corosync 3.1.x · 2026-08-09

Not yet marked complete on this device.

bpftrace and bcc are the practical tools for sysadmin eBPF work. This lesson covers the most useful patterns.

bpftrace one-liners

# Count syscalls by process
bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[comm] = count(); }'

# Histogram of read() latency, in microseconds.
# nsecs is nanoseconds - divide, or the bucket labels lie by 1000x.
bpftrace -e '
tracepoint:syscalls:sys_enter_read { @start[tid] = nsecs; }
tracepoint:syscalls:sys_exit_read /@start[tid]/ {
    @usecs = hist((nsecs - @start[tid]) / 1000);
    delete(@start[tid]);
}'

# Top 10 files by open count
bpftrace -e '
tracepoint:syscalls:sys_enter_openat { @[str(args->filename)] = count(); }'

bcc tools

bcc ships pre-built tools. The catch is that no distribution installs them under their upstream names, so every example you find online fails on a stock host with command not found - usually mid-incident.

Common ones:

# Block I/O latency histogram
sudo biolatency

# Per-I/O tracing, one line per block request
sudo biosnoop

# TCP connection attempts
sudo tcpconnect

# New process execution
sudo execsnoop

# File open tracing
sudo opensnoop

# Syscall counts, system-wide or per process (-P)
sudo syscount
sudo syscount -P

# TCP retransmits
sudo tcpretrans

# DNS and other name-resolution latency (traces getaddrinfo/gethostbyname)
sudo gethostlatency

syscount and syscount-bpfcc are not two tools. They are the same tool under two packaging names - the second is simply what Debian and Ubuntu call the first.

Common use cases

“Where is latency coming from?”

# Substitute your own values before running:
PID=1234

# Block I/O latency histogram, in milliseconds
sudo biolatency -m

# Which files and processes are driving that I/O
sudo filetop -p "$PID"

# Syscall latency, not just counts
sudo syscount -L
sudo syscount -L -p "$PID"

biolatency measures block device latency, not syscall latency. If it looks clean, the delay is above the block layer - in the filesystem, in a lock, or in the application - and syscount -L is the tool that narrows it down.

“Why are packets being dropped?”

# Where in the kernel the skb was freed. Not a bcc tool: dropwatch
# uses the kernel dropmon netlink interface, and it is interactive -
# type 'start' at its prompt, and 'stop' to end.
sudo dropwatch -l kas

# Same question with bpftrace, non-interactive and scriptable
sudo bpftrace -e 'tracepoint:skb:kfree_skb { @[kstack] = count(); }'

# Interface-level counters first - they are free and often enough
ip -s link show dev eth0
nstat -az | grep -i drop

Start with ip -s link. If the drops are counted on the NIC itself, the answer is ring-buffer sizing or offload behaviour, and no amount of kernel stack tracing will show it.

“What is process X doing?”

# Substitute your own values before running:
PID=1234

# Files opened by one process
sudo opensnoop -p "$PID"

# Syscalls it is making, with latency
sudo syscount -L -p "$PID"

# Outbound connections it is attempting
sudo tcpconnect -p "$PID"

Note the space in -p <pid>. opensnoop-p is not a tool; it is a typo that produces command not found, which is easy to misread as “bcc is not installed” when you are under pressure.

“Why is the system slow?”

# Substitute your own values before running:
PID=1234

# Scheduler run-queue latency: how long runnable tasks wait for CPU
sudo runqlat 2 5          # 2-second intervals, 5 samples

# Off-CPU time: where processes are blocked rather than running
sudo offcputime -p "$PID"

# Which syscalls dominate, by count and by time
sudo syscount
sudo syscount -L

runqlat reports waiting for CPU, not CPU usage - a high run-queue latency means you have more runnable work than cores, whereas a slow process with an idle run queue is blocked on something else, which is what offcputime answers. For plain CPU usage, top and pidstat are still the right tools.

bpftrace cookbook

The bpftrace repository has many examples. Some favourites:

# Bytes read per process. sum(args->count), not count():
# count() tallies how many read() calls were made, which is a very
# different number from how many bytes they asked for.
bpftrace -e 'tracepoint:syscalls:sys_enter_read { @bytes[comm] = sum(args->count); }'

# read() calls per process, when that is what you actually want
bpftrace -e 'tracepoint:syscalls:sys_enter_read { @calls[comm] = count(); }'

# TCP connect attempts by process. args->uservaddr is a POINTER into
# userspace to a struct sockaddr - it is not a string, so %s on it
# prints garbage. Count the attempts by process instead, and use
# tcpconnect (bcc) when you need the destination addresses.
bpftrace -e 'tracepoint:syscalls:sys_enter_connect { @connects[comm] = count(); }'

# Disk I/O size histogram
bpftrace -e 'tracepoint:block:block_rq_issue { @bytes = hist(args->bytes); }'

# TCP retransmits
bpftrace -e 'tracepoint:tcp:tcp_retransmit_skb { @[args->sport] = count(); }'

Knowledge check

Knowledge check · 5 questions

  1. Q1. Which bcc tool traces new processes?

  2. Q2. bpftrace one-liners can trace per-process syscalls.

  3. Q3. Which of the following are valid bcc tools? Select all that apply.

  4. Q4. You are on a Ubuntu host during an incident. sudo biolatency returns "command not found", but bpfcc-tools is installed. What is happening?

  5. Q5. Running sudo dnsdist is a safe, passive way to observe DNS queries on a host.

Passing score: 75%. Answers are checked in this browser.