Practical Applications of eBPF for Linux System Tracing and Debugging
eBPF enables real-time, low-overhead system tracing by running sandboxed programs directly in the Linux kernel, allowing developers to audit syscalls, profile performance, and debug production systems without recompiling the kernel or modifying application code.
The trimstray/the-book-of-secret-knowledge repository curates essential resources for system administrators and security engineers, including definitive guides on eBPF for Linux system tracing and debugging. According to the repository's README.md, line 306 references bpftrace—a high-level tracing language for writing kernel and user-space probes—while line 1026 points to awesome-ebpf, a comprehensive collection of eBPF tools and tutorials. The repository's .github/CONTRIBUTING.md further outlines how community members can expand these curated lists with additional tooling examples.
System Call Auditing
eBPF programs attach to sys_enter_* and sys_exit_* tracepoints to monitor every interaction between user-space processes and the kernel. This capability allows administrators to track which binaries are executed, which files are opened, or which network sockets are bound in real time.
According to the source guides, you can trace execve system calls with a single bpftrace one-liner to see process command lines instantly:
bpftrace -e 'tracepoint:syscalls:sys_enter_execve { printf("%s %s\n", comm, str(args->filename)); }'
This captures the process name (comm) and the target binary path (args->filename) without requiring static instrumentation of the monitored applications.
Performance Profiling
By sampling CPU stacks at high frequencies and filtering by specific process identifiers, cgroups, or namespaces, eBPF identifies hot functions and latency spikes that traditional profilers miss. The kernel aggregates stack traces in efficient BPF maps, minimizing the performance penalty of observation.
To profile a specific binary and generate flamegraph-compatible output, use:
bpftrace -e 'profile:hz:99 /comm == "myapp"/ { @[stack] = count(); }'
This collects user-space and kernel stacks at 99 Hz, storing counts in the @ map for visualization with stackcollapse.pl and flamegraph.pl.
Network Visibility
eBPF hooks into XDP (eXpress Data Path), socket buffers, and TCP tracepoints to provide packet-level visibility without modifying network drivers. Administrators can trace packet drops, monitor connection latency, or analyze TLS handshake delays by attaching programs to tcp:tcp_probe tracepoints.
Monitor TCP connection attempts by source address with:
bpftrace -e 'tracepoint:tcp:tcp_probe { @[args->saddr] = count(); }'
This aggregates connection counts by source IP, helping identify unexpected network traffic patterns or port scanning activity.
Security and Forensics
Security teams use eBPF to detect suspicious behavior patterns such as unexpected execve calls from temporary directories, unauthorized access to sensitive files like /etc/passwd, or anomalous kernel function invocations. The verifier-enforced sandbox ensures these detection programs cannot crash the kernel, making them safe for 24/7 intrusion detection.
Detect unauthorized file permission checks with:
bpftrace -e 'kprobe:security_inode_permission /strcmp(args->name, "/etc/passwd")==0/ { @alert = count(); }'
This raises an alert counter whenever a process attempts to access the password file, enabling real-time forensics without third-party kernel modules.
Container and VM Observability
Modern infrastructure relies on eBPF to correlate kernel events with specific cgroups or namespaces. By filtering tracepoints using cgroupid or namespace identifiers, operators can isolate resource usage per container, trace container startup sequences, or detect breakout attempts.
Track process forks within a specific cgroup using:
bpftrace -e 'tracepoint:sched:sched_process_fork /cgroupid == 0x1234/ { @forks[pid] = 1; }'
This monitors only processes within the target container, providing accurate telemetry in multi-tenant environments where traditional system-wide tools produce noise.
Dynamic Debugging of User-Space Applications
Uprobes allow eBPF programs to attach to user-space function entry points without modifying source code or restarting binaries. This enables debugging of third-party libraries, tracking of memory allocation patterns in libc, or monitoring of database query execution inside proprietary applications.
Count malloc invocations per process in the C standard library:
bpftrace -e 'uprobe:/usr/lib/libc.so.6:malloc { @[pid] = count(); }'
This reveals memory pressure and allocation hotspots in production binaries where recompilation is impossible.
How eBPF Tracing Works
The guides in trimstray/the-book-of-secret-knowledge outline a consistent architectural pattern for all eBPF tracing applications. Understanding these four components ensures efficient, low-overhead instrumentation:
- Hook Selection – Choose the appropriate kernel event source: tracepoints for stable kernel interfaces, kprobes for dynamic kernel function instrumentation, uprobes for user-space functions, or perf events for hardware counters.
- Filtering – Apply BPF predicates (e.g.,
/comm == "myapp"/or/args->len > 1500/) inside the kernel to discard irrelevant events before they consume CPU cycles in user-space. - Aggregation – Use built-in BPF maps (denoted by
@in bpftrace) to accumulate counts, histograms, or stack traces in-kernel, reducing the data transfer volume to user-space. - Output – bpftrace prints human-readable summaries or exports JSON/CSV for integration with monitoring stacks like Prometheus or Elasticsearch.
Because the eBPF verifier checks all programs for safety before execution, these tracing tools run in a sandboxed environment that prevents kernel panics or infinite loops, distinguishing eBPF from traditional loadable kernel modules.
Complete bpftrace Scripts for Production Debugging
The following three scripts, derived from the repository's referenced tutorials, illustrate complete debugging workflows. Save each as a .bt file and execute with sudo bpftrace <file>.bt.
Trace Process Execution with Arguments
This script logs every execve call with the process name, PID, and command-line arguments:
// execve.bt
tracepoint:syscalls:sys_enter_execve
{
printf("%s (%d) execve: %s %s %s\n",
comm, pid,
str(args->filename),
str(args->argv[0]),
str(args->argv[1]));
}
Runs on any Linux system with bpftrace installed; instantly reveals which binaries are launched and their parameters.
Profile CPU Usage for Flamegraph Generation
Collect user-space stack traces for a specific application to identify performance bottlenecks:
// cpu_profile.bt
profile:hz:99 /comm == "myapp"/
{
@[ustack()] = count();
}
Sample at 99 Hz to avoid lockstep with scheduler ticks; pipe output to stackcollapse.pl and flamegraph.pl to generate visual heatmaps.
Detect Network Packet Drops
Monitor oversized packets on specific interfaces to diagnose MTU misconfigurations:
// net_drop.bt
tracepoint:net:net_dev_queue
/args->dev == "eth0" && args->len > 1500/
{
@drops[args->dev] = count();
}
Counts packets exceeding standard MTU queued on eth0, helping identify fragmentation issues or jumbo frame configuration errors.
Summary
- eBPF provides real-time visibility into Linux kernel and user-space activity without kernel recompilation or application modification.
- bpftrace one-liners enable instant system call auditing, CPU profiling, and network analysis using stable tracepoints and dynamic probes.
- Safety is guaranteed by the eBPF verifier, which sandboxes programs to prevent kernel crashes, making the technology suitable for 24/7 production monitoring.
- Container-aware filtering using cgroup and namespace IDs allows precise observability in modern orchestrated environments.
- The
trimstray/the-book-of-secret-knowledgerepository references these capabilities atREADME.mdlines 306 and 1026, pointing to bpftrace and awesome-ebpf as the definitive starting points for implementation.
Frequently Asked Questions
What is the difference between eBPF and traditional BPF?
Traditional BPF (Berkeley Packet Filter) was originally designed for packet filtering in network capture tools like tcpdump. eBPF (extended BPF) expands this into a general-purpose virtual machine capable of running sandboxed programs attached to kernel hooks, tracepoints, and user-space functions. While traditional BPF supported only simple packet matching, eBPF enables complex system tracing, performance profiling, and security monitoring with full access to kernel data structures.
Is eBPF safe to run in production environments?
Yes. The Linux kernel verifier inspects every eBPF program before loading it, checking for null pointer dereferences, infinite loops, and out-of-bounds memory access. Programs that fail these checks are rejected. This sandboxing ensures that even buggy tracing scripts cannot crash the kernel or destabilize the system, distinguishing eBPF from traditional kernel modules or patches.
How does bpftrace simplify eBPF development?
bpftrace abstracts the complexity of writing raw eBPF C code and loading it with libbpf. It provides a high-level, awk-like syntax where one-liners can attach to kernel tracepoints, filter events, and aggregate data using built-in maps. For example, bpftrace -e 'tracepoint:syscalls:sys_enter_open { @[comm] = count(); }' requires no compilation or kernel headers, making advanced system tracing accessible to system administrators without C programming expertise.
What are the performance overhead considerations for eBPF tracing?
eBPF incurs minimal overhead because programs run in-kernel and filter events before exporting data to user-space. By aggregating statistics in BPF maps (using @ variables in bpftrace) rather than printing every event, CPU usage typically remains below 1% even on high-traffic servers. However, attaching kprobes to extremely high-frequency kernel functions or sampling at rates above 1000 Hz can introduce measurable overhead, so production deployments should test probes in staging environments first.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →