eBPF Observability in WSL 2: Probe the Running Kernel, Not the Marketing Label
Evaluate eBPF tracing in WSL 2 with kernel capability probes, BTF checks, and workload tests without assuming every Linux tool is supported.
The phrase “WSL runs a Linux kernel” is not enough to establish that a particular eBPF observability tool will work. The tool may require a program type, helper, attach point, BTF data, kernel configuration, privilege, capability, tracepoint, or host performance counter that is unavailable in the running environment. A feature visible in a Microsoft kernel source tree is not proof that the same option is enabled in the kernel installed on a given Windows machine.
Treat eBPF support as a capability matrix and test the actual workload. This article is about Linux observability and feature detection, not a security-policy recipe. It avoids blanket claims that all eBPF programs, profilers, or kernel hooks are supported by WSL.
Start with the exact WSL and kernel build
Capture the platform versions before installing tools or changing kernels:
wsl.exe --version
wsl.exe --status
wsl.exe --list --verbose
Inside the target distro:
uname -a
cat /proc/version
test -r /sys/kernel/btf/vmlinux && echo "BTF file present" || echo "BTF file absent"
mount | grep -E 'tracefs|debugfs|bpf' || true
WSL’s Windows package, Linux kernel, and distro userland have separate version identities. A distro package can update bpftool, bpftrace, or libbpf while the WSL kernel remains unchanged. Record both sides. Do not describe a tool package version as the kernel version or assume a Windows feature update automatically means a particular WSL kernel is running.
The Microsoft WSL2-Linux-Kernel repository publishes kernel source and configuration. A configuration file on a maintained branch is useful evidence about that source snapshot, but it is not a guarantee that every machine has that branch’s kernel, architecture, or options. Use it to generate questions for runtime probes, not to skip them.
Probe available features instead of reading a single config flag
If the distro has bpftool installed, ask it about the running kernel:
bpftool version
sudo bpftool feature probe kernel
bpftool feature probe kernel unprivileged
The privileged and unprivileged probes answer different questions. A root probe may show capabilities that an ordinary user cannot access. Record which identity ran the probe, whether it used sudo, and the exact bpftool version. Do not copy a root feature report into a non-root service runbook.
The unprivileged form is not available in every bpftool build; the tool’s documentation notes that this probing mode depends on optional libcap support. If the command rejects the keyword, check bpftool help and package build options before deciding that the kernel lacks the feature. Keep a syntax or packaging failure distinct from a probe result.
Also inspect BTF availability when a CO-RE or type-aware tool requires it. The existence of /sys/kernel/btf/vmlinux can satisfy one prerequisite, but it does not prove a program’s attach type, helper set, or required tracepoint is available. Conversely, missing BTF does not mean every BPF program is impossible; it means a BTF-dependent workflow needs another supported source of type information or will not work as written.
If bpftool is absent, install the distribution’s packaged tool before drawing conclusions. If the probe fails, preserve stderr and check tool/kernel compatibility, permissions, and whether the bpf system call is available. Do not respond to a failed probe by immediately replacing the kernel.
Separate program loading from attachment and useful data
An eBPF workflow has several gates. A program must compile for a compatible target, pass the kernel verifier, load with the needed permissions, attach to a supported hook, and receive events. A success at an earlier gate does not prove later gates. For example, a tool can find the BPF system call but fail to attach to a requested tracepoint or kprobe.
Probe the exact program type and attachment point used by the product. A generic “BPF available” line from bpftool is not a universal compatibility statement. Read the tool’s current support matrix and kernel requirements. Prefer stable tracepoint or documented APIs when the tool supports them, and test against the exact WSL kernel build that will be deployed.
Linux kernel documentation warns that tracing interfaces such as tracepoints can be tied to kernel implementation details and may change across releases. A tracing program that reads internal kernel structures can require adaptation after a kernel update. Pinning an old WSL kernel to preserve an undocumented attachment creates an ongoing maintenance and rollback burden. Include the kernel release and tool version in every reproducibility report.
Validate software requirements without assuming PMU access
Many observability products combine software tracepoints with hardware performance monitoring. These are different sources. A WSL kernel may support a software event while the virtualized environment or host does not expose the hardware performance counter required by another mode. Do not infer PMU availability from a successful syscall trace or from Windows Task Manager CPU data.
Run a short low-impact probe with the intended tool and event. Confirm it attaches, receives the expected event, detaches, and does not leave a background process or pinned map behind. If the tool supports both a tracepoint and a hardware counter, validate them separately. A missing event could mean an unsupported PMU, an unavailable tracepoint, the wrong process filter, or a workload that never triggered the event.
Do not claim that an eBPF profiler is production-ready because it starts. Define the required events, sampling overhead, output completeness, behavior under WSL shutdown, and compatibility across the WSL kernel versions in scope. Measure overhead against a baseline workload and stop if a diagnostic trace causes unacceptable CPU use or latency.
Keep guest and host observability views distinct
Guest-side eBPF observes kernel and process events exposed inside Linux. Windows ETW and Performance Monitor observe host-side components and the virtual machine from the Windows side. Neither view substitutes for the other. A Linux trace can show a process waiting in the guest; a Windows trace may help establish host scheduling or virtualization context. Correlate them by timestamp, workload identifier, and a bounded reproduction window.
Some system resources are shared by multiple WSL distributions within the managed VM. A guest-wide event stream can include other distro work. Filter by process, cgroup, or namespace only when the selected program type and kernel support that filter. Record whether the test ran with one distro or several. A host-level WSL process observation should not be mislabeled as a per-container Linux metric.
When eBPF is unavailable or the needed hook is missing, use a supported fallback: application metrics, procfs counters, systemd accounting, perf events that are actually exposed, or Windows ETW for host-side behavior. State which question the fallback can answer and which it cannot. A partial but clearly scoped measurement is more reliable than claiming unsupported kernel visibility.
Troubleshoot the failure in layers
If the feature probe cannot call BPF, inspect kernel version, installed tool build, permissions, and the running kernel configuration when available. If loading succeeds but attach fails, check the exact program and attach type, tracepoint presence, BTF requirements, and tool compatibility. If the tool attaches but receives no events, verify the workload, filters, namespace, event path, and duration. Preserve verifier output because it often identifies the rejected operation.
Avoid globally granting capabilities or running a vendor agent as root merely to suppress an error. The right access model depends on the tool and Windows/WSL policy. If the product requires a kernel option absent from the supported WSL kernel, decide explicitly whether a custom kernel is operationally acceptable; custom kernel lifecycle, module matching, and rollback are separate concerns. Do not silently make custom kernel use a prerequisite for a general WSL guide.
Control event selection, duration, and teardown
Tracing only the event needed for one bounded question reduces overhead and makes output easier to interpret. A broad process or syscall trace can generate substantial data, obscure the target event, and capture information unrelated to the incident. Use a narrow process filter, a short runtime, and an explicit stop condition. Remove pinned objects or maps only when the responsible tool documents ownership and cleanup; never delete a shared bpffs tree to clear an unexplained attachment.
Capture the baseline workload before attaching a probe and compare it with the trace enabled. Record CPU use, completion time, event count, and any dropped-event counters exposed by the tool. Verify the observer exits and detaches after normal completion and interruption. A probe that works once but remains attached after a service restart is not an operationally complete workflow.
Acceptance criteria for WSL observability
For each supported WSL release, record Windows build, WSL package version, Linux kernel release, distro, architecture, bpftool version, privilege level, BTF state, program type, attach point, event, and measured overhead. Verify the intended event using a minimal reproducible workload, confirm detach and cleanup, and repeat after a normal distro restart. If multiple distributions run concurrently in production, test the expected noise and attribution boundaries.
A support statement should name tested combinations rather than say “eBPF works in WSL.” Re-run capability probes after WSL kernel updates and changes to a custom kernel. A source-tree configuration is useful context; a runtime probe and end-to-end event test are the acceptance evidence.
Related:
- Collecting and Reading WSL Diagnostic Logs with ETW and WPA
- Running a Custom WSL 2 Kernel Without Losing the Supported Rollback Path
Sources: