Read and Filter perf.data with perf script
A raw perf.data file is unreadable until you run it through perf script, and the default dump is usually far more than you wanted. This guide gets you from "wall of text" to a trimmed, time-sliced trace in about fifteen minutes, assuming the recording already exists. Examples follow the perf script interface documented by linux-tools-common 6.8.0-142.142 on this system.
The route
Jump straight to the step you need, or tick off Done means at the end.
You need a shell, a readable recording created by perf record, and enough disk or terminal space for the output. Nothing here changes the kernel, starts a workload, or alters the input file: it is read-only from start to finish.
A recording can contain command names, process IDs, file paths and addresses, so treat it as potentially sensitive before copying or sharing it.
1. Check the local command and recording
Confirm which executable the shell will use and whether the default input file exists:
$ command -v perf
/usr/bin/perf
$ test -r perf.data && echo 'perf.data is readable'
perf.data is readable
- Wrong file name?
perf scriptreadsperf.databy default; point it elsewhere with--input:$ perf script --input=/path/to/recording.data - Wrapper reports a missing package? On this host,
/usr/bin/perfis a wrapper that flags when the executable for the running kernel is not installed. A message naming a package such aslinux-tools-6.8.0-139-genericmeans install that package through your normal system administration process, not a fault in the recording.
Installation needs elevated privileges and sits outside this read-only workflow. The manpage and package version above describe the syntax used here; the examples still need a matching kernel-specific binary to run.
2. Print the recorded trace
With a matching perf executable and a recording in the current directory, run the command with no subcommand:
$ perf script
The output is a detailed trace to standard output: command name, thread or process identifiers, a timestamp, a CPU and event-specific data. Exact lines depend on what was recorded, symbol availability and the kernel.
An empty result or an error is not fixed by adding random display options. Confirm the input path and that the recording actually contains events first.
Checkpoint
Keep the original file and capture output to a new file when you need to search it. The redirection below does not modify perf.data.
$ perf script --input=/path/to/recording.data > trace.txt
$ test -s trace.txt && echo 'trace output was written'
trace output was written
3. Choose only the fields you need
Use -F or --fields with a comma-separated list. These are fields in the decoded output, not shell variables:
$ perf script --input=/path/to/recording.data \
--fields=comm,tid,time,cpu,event,ip,sym
That asks for the command, thread ID, time, CPU, event, instruction pointer and symbol. The installed manpage also lists pid, trace, dso, srcline, period and several branch, instruction-trace and virtual-machine fields.
Without a type prefix, the request applies to software, hardware and trace events, and an unsupported field for one event type is ignored with a diagnostic. Prefix the list for stricter control:
$ perf script --input=/path/to/recording.data \
-F sw:comm,tid,time,ip,sym \
-F trace:time,cpu,trace
- Prefix it and a spelling mistake becomes an error instead of a silent skip, which is exactly what you want in a script.
- Arguments run left to right. A later
-Fcan replace an earlier one, which is handy when building a command incrementally and easy to miss in a wrapper script. - Add or remove instead of replacing:
-F -cpu,+insndrops CPU and adds instruction bytes. Do not mix this add/remove form with a plain replacement list, and note an empty field list is rejected for every event type.
4. Restrict analysis to a time window
Large recordings are easier to inspect in slices. --time takes seconds and nanoseconds as start,stop; leave one side empty for the beginning or end:
$ perf script --input=/path/to/recording.data --time '12.500000000,15.000000000'
$ perf script --input=/path/to/recording.data --time '12.500000000,'
Quote the argument so the shell passes the comma-separated value as one piece. Multiple ranges go inside the same quoted value, separated by spaces. Percentage slices work too, such as --time 10%/2 for the second tenth of the recording or --time 0%-10% for the first tenth. A time window filters the analysis; it never rewrites the recording.
Tip
For a less noisy timestamp column, --reltime prints times relative to the start of the trace and --deltatime prints times relative to the previous event. Keep the original absolute output if another tool downstream needs the recorded timestamps.
5. List and run prepared trace scripts
The installed perf build can ship pre-canned scripts for aggregating or summarising raw events. List the names first:
$ perf script --list
Use the name shown by that list without its language extension: the list is build-specific, so do not guess a script name from another machine. --script processes the recording with a chosen script, and supplying a language name instead shows the supported languages. --gen-script creates a starter script for a given language from the current recording.
There are three related workflows:
perf script record SCRIPT COMMANDrecords the events a prepared script needs.perf script report SCRIPTreads the resultingperf.dataand displays its report.perf script SCRIPT REQUIRED-ARGS COMMANDrecords and runs a script live, with no recording written to disk. The live form places required script arguments before the command, and does not accept optional script arguments the same way, so fall back to separate record and report steps when those are needed.
Warning
These modes can record system-wide data when no command is supplied. That may expose other users' activity and can impose measurable overhead. Confirm you are allowed to observe the host and that the collection window is appropriate before running a system-wide form. Do not reach for sudo by habit: elevated collection is a privilege and privacy decision, not a display requirement.
6. Investigate a confusing result safely
Show the recording header when you need to establish what was actually captured:
$ perf script --input=/path/to/recording.data --header-only
- Need extended host information? Use
--show-infowith report mode only; the manpage warns this can be large and clutter the display. - Want a basic integrity check?
--debug-modeasks perf to check things like sample ordering and lost events. - Missing symbols? The trace can still hold raw addresses.
--vmlinux,--kallsymsand--symfstell perf where to look for kernel or symbol files. Point them at files you trust and verify their paths before sharing the output. A symbol lookup problem is different from an absent event: compare the header and raw fields before touching collection settings. - Doing instruction tracing?
--itracecontrols which synthetic instructions, branches, call chains or other events get decoded. Its default depends on the command; the manpage givesceas the default forperf script. Do not add instruction decoding unless the recording actually contains instruction-trace data, or it will simply produce nothing.
Done means
- Confirmed the input path and used
--inputwhen the file was notperf.data. - Kept the original recording unchanged, redirecting output to a separate destination when needed.
- Used
--fields, and a time window where useful, to cut the noise. - Listed prepared scripts before selecting one, and kept required script arguments separate from the workload command.
- Treated system-wide collection, elevated privileges and trace sharing as explicit security decisions.