Extract a Stopped Ftrace Buffer with trace-cmd

trace-cmd extract turns an existing Ftrace ring buffer into a portable trace.dat file that trace-cmd report can read. It earns its keep whenever tracing was started separately from collection, for instance with trace-cmd start or by writing directly to the Ftrace pseudo-filesystem.

Allow about 10 minutes for a first run. You need the installed trace-cmd package, a kernel with Ftrace available, and enough privileges to control tracing. The examples use trace-cmd 3.2.0 from Ubuntu package 3.2-1ubuntu2, and follow the installed 4 April 2024 manpage.

Before you start

extract does not start a trace. It reads the kernel's internal ring buffer and writes a trace file. The normal sequence is start, let events occur, stop, extract, report. Stopping prevents further writes, but it does not remove the tracing overhead, and resetting later disables tracing and clears the captured data, so do not reset before you extract.

Most tracing control changes the running kernel, so use an elevated shell for the commands that fail as an ordinary user on your system. The output file itself is ordinary data, so pick a directory you can write to and make its name explicit.

1. Check the local tracers and events

Check what this kernel exposes first. These are read-only commands and do not start tracing:

trace-cmd --version
sudo trace-cmd list -t
sudo trace-cmd list -e '^sched_.*'

Expect a version such as trace-cmd version 3.2.0, followed by the available tracer names and matching events. The exact list depends on the kernel configuration, so do not copy a tracer from another machine without checking it here first.

2. Start and stop a small trace

Start only the event or tracer you need. This example records scheduler events without creating trace.dat yet:

sudo trace-cmd start -e sched_switch

Reproduce the behaviour you are investigating, then stop writes to the ring buffer:

sudo trace-cmd stop

At this checkpoint the data is still sitting in the kernel buffer. If you stop and then wait too long before extracting, remember that another process or tracing configuration may change the state in the meantime, so keep the interval short.

3. Extract the top-level buffer

Write the buffer to a new path. This avoids accidentally overwriting an existing file named trace.dat:

mkdir -p "$HOME/traces"
sudo trace-cmd extract -o "$HOME/traces/sched-switch.trace.dat"

On success, the command returns to the shell and the file exists. Verify both the path and that trace-cmd can actually read its metadata:

test -s "$HOME/traces/sched-switch.trace.dat" && +trace-cmd dump "$HOME/traces/sched-switch.trace.dat" | sed -n '1,25p'

The default output name is trace.dat; -o changes it. If the output path ends up owned by root because extraction ran under sudo, read it with sudo or move it to a user-owned directory using an explicit path. Do not reach for a broad recursive ownership change to fix that.

4. Read and filter the result

report converts the binary file into readable text. Give it the file as the final argument:

sudo trace-cmd report "$HOME/traces/sched-switch.trace.dat" | sed -n '1,40p'

Expect timestamped trace records when the buffer contained matching events. An empty report can still mean extraction succeeded: the event may never have occurred, the buffer may have wrapped, or the wrong buffer may have been selected.

To narrow a large file to scheduler switch records, use the report event filter:

sudo trace-cmd report --event sched:sched_switch "$HOME/traces/sched-switch.trace.dat"

The filter is applied while reporting, so it never alters the saved file. Keep the original around in case you need a different filter later.

5. Extract named buffer instances

Systems with multiple Ftrace buffers need an explicit choice. List the defined instances first:

sudo trace-cmd list -B

Extract one instance with -B:

sudo trace-cmd extract -B INSTANCE_NAME -o "$HOME/traces/instance.trace.dat"

Replace INSTANCE_NAME with a name the previous command printed. You may repeat -B for several instances at once.

Tip: when -B or -a is used, the top-level buffer is left out unless -t is also present:

sudo trace-cmd extract -a -t -o "$HOME/traces/all-buffers.trace.dat"

Here -a requests all existing buffer instances and -t adds the top-level one. On an older kernel without multiple buffers, these options may fail or add nothing useful. Treat that as a capability check, not as proof the original extraction was broken.

6. Handle latency tracers and snapshot data

Latency tracers use a separate internal buffer. For wakeup, wakeup-rt, irqsoff, preemptoff and preemptirqsoff, pass the plugin the trace actually used:

sudo trace-cmd extract -p wakeup -o "$HOME/traces/wakeup.trace.dat"

For other traces, omit -p entirely; adding an unrelated plugin does not make an ordinary ring-buffer extraction any more complete. If the kernel supports a snapshot buffer and that is the data you actually need, use -s:

sudo trace-cmd extract -s -o "$HOME/traces/snapshot.trace.dat"

The snapshot option reads a different buffer entirely. Check the kernel supports it and that a snapshot was actually taken before you treat an empty result as a command failure.

7. Finish safely and recover from mistakes

Extraction itself does not disable Ftrace. Once the file has been checked and you no longer need the tracing configuration, reset it:

sudo trace-cmd reset

Warning: reset disables tracing and clears the ring buffers. It is destructive to any data that has not already been extracted, and it also removes the options used by the trace. If another person or service owns the tracing session, coordinate with them first. Reset too early, and the ring-buffer data cannot be recovered from trace-cmd; you will have to start a new capture.

The --date option is another boundary worth remembering: it makes extraction disable all tracing at the end, similar to a reset. Use it only when that side effect is genuinely intended:

sudo trace-cmd extract --date -o "$HOME/traces/final.trace.dat"

Common traps

Done means