Read and Filter perf.data with perf script
You will finish with a practical way to inspect a perf.data recording, reduce its output to useful fields or a time window, and choose between raw display and a prepared trace script. Allow about fifteen minutes if the recording already exists. The examples use 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. The commands below read the recording. They do not change the kernel, start a workload, or alter the input file. 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
Start by checking which executable the shell will use and whether the default input exists:
$ command -v perf
/usr/bin/perf
$ test -r perf.data && echo 'perf.data is readable'
perf.data is readable
The command reads perf.data by default. Use a separate path when the file has another name:
$ perf script --input=/path/to/recording.data
On this host, /usr/bin/perf is a wrapper that reports when the executable for the running kernel is not installed. If you see a message naming a package such as linux-tools-6.8.0-139-generic, install that package through your normal system administration process before treating the failure as a problem with the recording. Installation requires elevated privileges and is 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 without a subcommand:
$ perf script
The output is a detailed trace written to standard output. A typical record contains a 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: first confirm the input path and that the recording contains events.
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 names are fields in the decoded output, not shell variables:
$ perf script --input=/path/to/recording.data \
--fields=comm,tid,time,cpu,event,ip,sym
This asks for the command, thread ID, time, CPU, event, instruction pointer and symbol. The available field names in this installed manpage include comm, tid, pid, time, cpu, event, trace, ip, sym, 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. A field that does not make sense for one event type is ignored with a diagnostic. Prefix a list when you want stricter control, for example:
$ perf script --input=/path/to/recording.data \
-F sw:comm,tid,time,ip,sym \
-F trace:time,cpu,trace
A type-specific invalid field is an error, so use the prefix when a spelling mistake should stop a script. The arguments are processed from left to right. A later -F can replace an earlier request, which is useful when building a command incrementally but easy to miss in a wrapper script.
You can also add or remove fields from the defaults. For example, -F -cpu,+insn removes CPU and adds instruction bytes. Do not mix this add/remove form with a normal replacement list. The empty field list is not valid for every event type, and an empty list for all event types is rejected.
4. Restrict analysis to a time window
Large recordings are easier to inspect in slices. The --time option accepts 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 argument. Multiple ranges are separated by spaces inside the quoted value. The option also supports percentage slices, 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 does not rewrite the recording.
For a less noisy timestamp view, --reltime prints times relative to the start of the trace and --deltatime prints times relative to the previous event. Use one when the absolute clock values are distracting, but keep the original output if another tool needs the recorded timestamps.
5. List and run prepared trace scripts
The installed perf build can provide 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 exact list depends on the installed perf build, so do not guess a script name from another machine. The --script option processes the recording with a chosen script; supplying a language name instead displays supported languages. The --gen-script option creates a starter script for a specified language using the current recording.
There are three related workflows. perf script record SCRIPT COMMAND records the events required for a prepared script. perf script report SCRIPT reads the resulting perf.data and displays its report. Finally, perf script SCRIPT REQUIRED-ARGS COMMAND records and runs a script in live mode without writing a recording to disk. The live form places required script arguments before the command. It does not accept optional script arguments in the same way, so use separate record and report steps when those are needed.
These modes can record system-wide data when no command is supplied. That may expose other users' activity and can impose measurable overhead. Before using a system-wide form, confirm that you are allowed to observe the host and that the collection window is appropriate. Do not use 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 captured:
$ perf script --input=/path/to/recording.data --header-only
Use --show-info only with report mode when you need extended host information. The manpage warns that this can be large and clutter the display. For a basic integrity check, --debug-mode asks perf to perform checks such as sample ordering and lost events.
If symbols are missing, the trace can still contain raw addresses. The options --vmlinux, --kallsyms and --symfs tell perf where to look for kernel or symbol files. Point them at files you trust and verify their paths before sharing the resulting output. A symbol lookup problem is different from an absent event: compare the header and raw fields before changing collection settings.
For instruction tracing, --itrace controls which synthetic instructions, branches, call chains or other events are decoded. Its defaults depend on the command, and the manpage gives ce as the default for perf script. Do not add instruction decoding unless the recording contains instruction-trace data; otherwise it will not create information that was never captured.
Done means
- You confirmed the input path and used
--inputwhen the file was notperf.data. - You kept the original recording unchanged and redirected output to a separate destination when needed.
- You used
--fieldsand, where useful, a time window to reduce noise. - You listed prepared scripts before selecting a name and kept required script arguments separate from the workload command.
- You treated system-wide collection, elevated privileges and trace sharing as explicit security decisions.