Ftrace lets you trace kernel function calls. Kprobes go further — they let you inject your own code at any point in the kernel, without recompiling and without rebooting.

What Are Kprobes?

Kprobes (Kernel Probes) is a Linux kernel mechanism that lets you dynamically attach a handler to virtually any instruction in the kernel. When the CPU hits the probe point, execution is temporarily redirected to your code, then returns to normal flow.

Three variants:

  • kprobe — fires before the target instruction executes (typically at function entry)
  • kretprobe — fires at function return, gives access to the return value
  • jprobe — deprecated (removed since kernel 4.15), replaced by kprobe with pre_handler

Requirements

The kernel needs:

CONFIG_KPROBES=y
CONFIG_KPROBE_EVENTS=y

Most distros have this enabled by default. Check with:

grep CONFIG_KPROBES /boot/config-$(uname -r)

You also need debugfs mounted:

mount | grep debugfs
# If not mounted:
sudo mount -t debugfs none /sys/kernel/debug

Kprobes via debugfs

The quickest way to set a probe — no module writing, no compilation.

Intercepting Function Entry

We want to know when the kernel opens files — hook into do_sys_openat2:

# Set the probe
echo 'p:myprobe do_sys_openat2 filename=+0(%si):string' > /sys/kernel/debug/tracing/kprobe_events

# Enable it
echo 1 > /sys/kernel/debug/tracing/events/kprobes/myprobe/enable

# Watch
cat /sys/kernel/debug/tracing/trace_pipe

Every file open in the system now shows up in trace_pipe with the filename. +0(%si) is the second function argument (register si on x86_64), cast to string.

Cleanup:

echo 0 > /sys/kernel/debug/tracing/events/kprobes/myprobe/enable
echo '-:myprobe' >> /sys/kernel/debug/tracing/kprobe_events

Intercepting Returns (kretprobe)

We want to know how long vfs_read takes and what it returns:

echo 'r:myretprobe vfs_read ret=$retval' > /sys/kernel/debug/tracing/kprobe_events
echo 1 > /sys/kernel/debug/tracing/events/kprobes/myretprobe/enable
cat /sys/kernel/debug/tracing/trace_pipe

$retval is the function’s return value — for vfs_read that’s the number of bytes read (or an error).

Kprobes via perf

perf can set kprobes without manually touching debugfs:

# Add probe
sudo perf probe --add 'do_sys_openat2 filename=+0(%si):string'

# Record events
sudo perf record -e probe:do_sys_openat2 -a -- sleep 5

# View
sudo perf script

Remove:

sudo perf probe --del do_sys_openat2

Probing a Specific Line in a Function

perf probe can hook not just at entry, but mid-function:

# List available probe points in tcp_sendmsg
sudo perf probe -L tcp_sendmsg

# Probe at specific line
sudo perf probe 'tcp_sendmsg:15 size'

Requires debug symbols (kernel-debuginfo / linux-image-*-dbg).

Kprobes via bpftrace

If you have bpftrace, this is the most convenient way:

# Who opens which files?
sudo bpftrace -e 'kprobe:do_sys_openat2 { printf("%s: %s\n", comm, str(arg1)); }'

# How long does vfs_read take?
sudo bpftrace -e '
kprobe:vfs_read { @start[tid] = nsecs; }
kretprobe:vfs_read /@start[tid]/ {
    @us = hist((nsecs - @start[tid]) / 1000);
    delete(@start[tid]);
}'

# Top 10 most called kernel functions
sudo bpftrace -e 'kprobe:* { @[probe] = count(); } interval:s:5 { print(@, 10); clear(@); }'

That last example can heavily load the system — be careful in production.

Practical Use Cases

Who’s Killing Processes?

sudo bpftrace -e 'kprobe:do_send_sig_info {
    printf("%s (pid=%d) -> signal %d to pid %d\n",
        comm, pid, arg0, ((struct task_struct *)arg2)->pid);
}'

Tracking Memory Allocations >1MB

sudo bpftrace -e 'kprobe:__alloc_pages /arg1 > 8/ {
    printf("%s: alloc order %d (%d KB)\n", comm, arg1, (1 << arg1) * 4);
}'

DNS Latency (udp_sendmsg to Port 53)

sudo bpftrace -e 'kprobe:udp_sendmsg {
    $sk = (struct sock *)arg0;
    $dport = ($sk->__sk_common.skc_dport >> 8) | (($sk->__sk_common.skc_dport & 0xff) << 8);
    if ($dport == 53) {
        printf("%s -> DNS query\n", comm);
    }
}'

Limitations

  • Can’t probe inline functions — the compiler inlines them, they have no address
  • Can’t probe kprobes themselves — recursion
  • Blacklist — some critical functions are blocked (/sys/kernel/debug/kprobes/blacklist)
  • Overhead — each probe is an interrupt, thousands of probes on hot paths cause noticeable slowdown
  • Unstable ABI — kernel function names change between versions, probes are not portable

Kprobes vs ftrace vs eBPF

Kprobes Ftrace eBPF
Target any instruction functions functions + events
Overhead medium low low
Flexibility high medium very high
Ease of use medium easy requires tooling
Safety kernel module safe BPF verifier

Kprobes are the foundation — ftrace and eBPF often use them under the hood. If you need to quickly check something in production, bpftrace with kprobes is the best combination.