TRACE-CMD.DAT.V(5)
๐ TRACE-CMD.DAT.V(5) ๐
okay bestie, so this page is literally called TRACE-CMD.DAT.V(5) in the manual index, but plot twist โ the page itself is all about trace-cmd.dat.v6, the version 6 file format. yes, the numbering is giving chaotic. anyway, buckle up ๐
โจ NAME โจ
trace-cmd.dat.v6 โ the file format of trace-cmd version 6, no cap.
๐ธ SYNOPSIS ๐ธ
trace-cmd.dat ignore
๐ฆ DESCRIPTION ๐ฆ
So trace-cmd(1) produces a "trace.dat" file. It might also be named literally anything else if the user passes a different output name โ the name is not the moment, the binary format is. This file is what trace-cmd uses to save kernel traces into, so it can scoop the trace back out later (see trace-cmd-report(1)). iconic behavior honestly โจ
๐ INITIAL FORMAT ๐
The first three bytes are the magic value, and yes she's magic:
0x17 0x08 0x44
Then the next 7 bytes hold these characters:
"tracing"
Then comes a null '\0' terminated string with the version of the file:
"6\0"
Next, 1 byte of flags for the file's endianness:
0= little endian1= big endian
Then the next byte tells you the number of bytes per "long" value:
4โ 32-bit long values8โ 64-bit long values
๐ซถ Note: this is the long size of the target's userspace, not the kernel space size. important distinction, don't mix them up bestie.
[ Now all numbers are written in file defined endianess. ]
Then the next 4 bytes are a 32-bit word defining what the traced host machine page size was. cute.
๐ HEADER INFO FORMAT ๐
Right after the initial format comes the info about the trace headers recorded from the target box.
The next 12 bytes contain this string:
"header_page\0"
The next 8 bytes are a 64-bit word holding the size of the page header info stored next.
Then the actual data, sized by that previous 8 bytes, containing what was retrieved from debugfs/tracing/events/header_page.
๐ Note: the size of the second fieldcommitcontains the target kernel long size. for example:field: local_t commit; offset:8; size:8; signed:1;shows the kernel has a 64-bit long. slay, we love a self-describing field.
The next 13 bytes contain this string:
"header_event\0"
The next 8 bytes are a 64-bit word holding the size of the event header information stored next.
Then the data itself โ sized by the previous 8 bytes โ containing what was retrieved from debugfs/tracing/events/header_event.
This data is how the trace-cmd tool knows whether the ring buffer format of the kernel made any changes. lowkey a whole vibe check for the kernel ๐ฅ
๐ง FTRACE EVENT FORMATS ๐ง
Directly after the header information comes the info about the Ftrace specific events. These are the events used by the Ftrace plugins, and they are not enabled by the event tracing. (yes, they're the special ones.)
The next 4 bytes contain a 32-bit word: the number of Ftrace event format files stored in the file.
For that many times (as defined by the previous 4 bytes), you get:
- 8 bytes for the size of the Ftrace event format file.
And the Ftrace event format file, copied from the target machine at:
debugfs/tracing/events/ftrace/<event>/format
๐ EVENT FORMATS ๐
Directly after the Ftrace formats comes the info about the event layout.
The next 4 bytes are a 32-bit word containing the number of event systems stored in the file. These are the directories in debugfs/tracing/events โ excluding the ftrace directory. (not invited to this party.)
For that many times (as defined by the previous 4 bytes), here's the lineup:
- A null-terminated string containing the system name.
- 4 bytes containing a 32-bit word with the number of events within the system.
Then, for that many times (as defined in the previous 4 bytes):
- 8 bytes for the size of the event format file.
And the event format file, copied from the target machine at:
debugfs/tracing/events/<system>/<event>/format
โญ KALLSYMS INFORMATION โญ
Directly after the event formats comes the info mapping function addresses to function names. the ultimate name-drop directory ๐
The next 4 bytes are a 32-bit word containing the size of the data holding the function mappings.
Then the data itself, sized by the previous 4 bytes, containing the info from the target machine's file:
/proc/kallsyms
๐ TRACE_PRINTK INFORMATION ๐
If a developer used trace_printk() inside the kernel, it may store the format string outside the ring buffer. messy but valid. This information lives in:
debugfs/tracing/printk_formats
The next 4 bytes are a 32-bit word containing the size of the data holding the printk formats.
Then the data, sized by the previous 4 bytes, containing the info from debugfs/tracing/printk_formats.
๐ฅ PROCESS INFORMATION ๐ฅ
Directly after the trace_printk formats comes the info mapping a PID to a process name. main character identification energy, honestly.
The next 8 bytes contain a 64-bit word holding the size of the data mapping the PID to a process name.
Then the data, sized by the previous 8 bytes, containing the info from:
debugfs/tracing/saved_cmdlines
๐ REST OF TRACE-CMD HEADER ๐
Directly after the process info comes the last lil bit of the trace.dat file header.
The next 4 bytes are a 32-bit word defining the number of CPUs that were discovered on the target machine (and that have matching trace data for it).
The next 10 bytes are one of the following:
"options \0"
"latency \0"
"flyrecord\0"
๐ซ If it's "options \0" ๐ซ
Then:
- The next 2 bytes are a 16-bit word defining the current option.
- If that value is zero, there are no more options. periodt.
- Otherwise, the next 4 bytes contain a 32-bit word with the option size. If the reader doesn't know how to handle the option, it can simply skip it. Currently there are no options defined, but this is here to extend the data. future-proofing queen.
The next option will be directly after the previous option, and the options end with a zero in the option type field.
The next 10 bytes after the options are one of the following:
"latency \0"
"flyrecord\0"
โฆwhich follows exactly the same as if the options were never present. no drama.
๐ธ If the value is "latency \0" ๐ธ
Then the rest of the file is simply ASCII text taken from the target's:
debugfs/tracing/trace
easy, readable, a little retro. we respect it.
๐ฆ If the value is "flyrecord\0" ๐ฆ
Then the following is present:
For the number of CPUs that were read earlier, you get:
- 8 bytes that are a 64-bit word containing the offset into the file that holds the data for the CPU.
- 8 bytes that are a 64-bit word containing the size of the CPU data at that offset.
๐ CPU DATA ๐
The CPU data lives in the part of the file specified at the end of the header. Padding is placed between the header and the CPU data, which places the CPU data at a page aligned (target page) position in the file. aesthetic AND functional.
This data is copied directly from the Ftrace ring buffer and has the same format as the ring buffer specified by the event header files loaded in the header format file.
The trace-cmd tool will try to mmap(2) the data page by page with the target's page size if possible. If it fails to mmap, it will just read the data instead. plan B never looked so good ๐ญ
๐ซถ SEE ALSO ๐ซถ
trace-cmd(1)trace-cmd-record(1)trace-cmd-report(1)trace-cmd-start(1)trace-cmd-stop(1)trace-cmd-extract(1)trace-cmd-reset(1)trace-cmd-split(1)trace-cmd-list(1)trace-cmd-listen(1)trace-cmd.dat(5)
โจ AUTHOR โจ
Written by Steven Rostedt, <rostedt@goodmis.org[1]> โ the legend himself ๐
๐ RESOURCES ๐
https://git.kernel.org/pub/scm/utils/trace-cmd/trace-cmd.git/
๐ COPYING ๐
Copyright (C) 2010 Red Hat, Inc. Free use of this software is granted under the terms of the GNU Public License (GPL).
๐ NOTES ๐
rostedt@goodmis.orgmailto:rostedt@goodmis.org
okay that's the whole byte-by-byte tour bestie, you ate that ๐โจ this page came from libtracefs, dated 03/09/2026 โ go forth and parse some traces, iykyk ๐
๐ฆ where this page comes from
- arch rolling: trace-cmd 3.4-1 ยท GPL-2.0-only AND LGPL-2.1-only
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms