José Fonseca | 38ab518 | 2014-05-23 21:16:11 +0100 | [diff] [blame] | 1 | # Trace binary format specification # |
| 2 | |
| 3 | This document specifies the binary format of trace streams. |
| 4 | |
Jose Fonseca | 6c3d267 | 2016-10-05 23:06:40 +0100 | [diff] [blame] | 5 | ## Compression ## |
| 6 | |
| 7 | Trace streams are not written verbatim to file, but compressed. |
| 8 | |
| 9 | By default traces are compressed with [Snappy](https://github.com/google/snappy) |
| 10 | (see below for details). Previously they used to be compressed with gzip. And |
| 11 | recently it also possible to have them compressed with |
| 12 | [Brotli](https://github.com/google/brotli), though this is mostly intended for |
| 13 | space savings on large databases of trace files. |
| 14 | |
| 15 | `apitrace repack` utility can be used to recompress the stream without any loss. |
| 16 | |
| 17 | ### Snappy ### |
| 18 | |
| 19 | The used Snappy format is different from the standard _Snappy framing format_, |
| 20 | because it predates it. |
| 21 | |
| 22 | file = header chunk* |
Jose Fonseca | c110dbc | 2017-06-23 13:04:17 +0100 | [diff] [blame] | 23 | |
Jose Fonseca | 6c3d267 | 2016-10-05 23:06:40 +0100 | [diff] [blame] | 24 | header = 'a' 't' |
Jose Fonseca | c110dbc | 2017-06-23 13:04:17 +0100 | [diff] [blame] | 25 | |
Jose Fonseca | 6c3d267 | 2016-10-05 23:06:40 +0100 | [diff] [blame] | 26 | chunk = compressed_length compressed_data |
Jose Fonseca | c110dbc | 2017-06-23 13:04:17 +0100 | [diff] [blame] | 27 | |
Jose Fonseca | 6c3d267 | 2016-10-05 23:06:40 +0100 | [diff] [blame] | 28 | compressed_length = uint32 // length of compressed data in little endian |
| 29 | compressed_data = byte* |
José Fonseca | 38ab518 | 2014-05-23 21:16:11 +0100 | [diff] [blame] | 30 | |
| 31 | |
| 32 | ## Versions ## |
| 33 | |
Jose Fonseca | b5ce015 | 2016-10-05 22:32:47 +0100 | [diff] [blame] | 34 | We keep backwards compatibility reading old traces, i.e., it should always be |
José Fonseca | 38ab518 | 2014-05-23 21:16:11 +0100 | [diff] [blame] | 35 | possible to parse and retrace old trace files. |
| 36 | |
| 37 | The trace version number refers not only to changes in the binary format |
| 38 | representation, but also semantic changes in the way certain functions should |
| 39 | be retraced. |
| 40 | |
| 41 | | `version_no` | Changes | |
| 42 | | ------------ | ------- | |
| 43 | | 0 | initial implementation | |
| 44 | | 1 | support for OpenGL user arrays as blobs (whereas before calls that operated with user memory instead of VBOs should be ignored) | |
| 45 | | 2 | malloc/free memory calls | |
| 46 | | 3 | enums signatures with the whole set of name/value pairs | |
| 47 | | 4 | call enter events include thread no | |
| 48 | | 5 | support for call backtraces | |
Jose Fonseca | af0d45b | 2017-06-28 22:35:37 +0100 | [diff] [blame] | 49 | | 6 | unicode strings; semantic version; properties; fake flag | |
José Fonseca | 38ab518 | 2014-05-23 21:16:11 +0100 | [diff] [blame] | 50 | |
| 51 | Writing/editing old traces is not supported however. An older version of |
Jose Fonseca | b5ce015 | 2016-10-05 22:32:47 +0100 | [diff] [blame] | 52 | apitrace should be used in such circumstances. |
José Fonseca | 38ab518 | 2014-05-23 21:16:11 +0100 | [diff] [blame] | 53 | |
| 54 | |
| 55 | ## Basic types ## |
| 56 | |
| 57 | | Type | Description | |
| 58 | | ---- | ----------- | |
| 59 | | `byte` | Raw byte. | |
Jose Fonseca | b5ce015 | 2016-10-05 22:32:47 +0100 | [diff] [blame] | 60 | | `uint` | Variable-length unsigned integer, where the most significant bit is zero for last byte or non-zero if more bytes follow; the 7 least significant bits of each byte are used for the integer's bits, in little-endian order. | |
José Fonseca | 38ab518 | 2014-05-23 21:16:11 +0100 | [diff] [blame] | 61 | | `float` | 32 bits single precision floating point number | |
| 62 | | `double` | 64 bits single precision floating point number | |
| 63 | |
| 64 | Strings are length-prefixed. The trailing zero is implied, not appearing neither in the length prefix nor in the raw bytes. |
| 65 | |
| 66 | string = count byte* |
| 67 | |
| 68 | count = uint |
| 69 | |
| 70 | |
| 71 | ## Grammar ## |
| 72 | |
| 73 | The trace consists of a small header with version information, followed by an |
| 74 | arbitrary number of events. |
| 75 | |
Jose Fonseca | c110dbc | 2017-06-23 13:04:17 +0100 | [diff] [blame] | 76 | trace = header event* |
| 77 | |
| 78 | header = version_no semantic_version_no properties // version_no >= 6 |
| 79 | | version_no // version_no < 6 |
José Fonseca | 38ab518 | 2014-05-23 21:16:11 +0100 | [diff] [blame] | 80 | |
| 81 | version_no = uint |
Jose Fonseca | e8a5de7 | 2017-06-22 15:18:52 +0100 | [diff] [blame] | 82 | semantic_version_no = uint |
| 83 | |
José Fonseca | 38ab518 | 2014-05-23 21:16:11 +0100 | [diff] [blame] | 84 | |
Jose Fonseca | c110dbc | 2017-06-23 13:04:17 +0100 | [diff] [blame] | 85 | ### Properties ### |
| 86 | |
| 87 | Properties are used to describe characteristics of the process, OS, hardware, etc. |
| 88 | |
| 89 | properties = property+ |
| 90 | |
| 91 | property = property_name property_value |
| 92 | | empty_string // terminator |
| 93 | property_name = string |
| 94 | property_value = string |
| 95 | |
| 96 | |
José Fonseca | 38ab518 | 2014-05-23 21:16:11 +0100 | [diff] [blame] | 97 | ### Calls ### |
| 98 | |
| 99 | Calls consist of an enter and leave event pair. Calls are numbered from zero, |
| 100 | and the call number is implied for the enter event. |
| 101 | |
| 102 | event = 0x00 thread_no call_sig call_detail+ // enter call (version_no >= 4) |
| 103 | | 0x00 call_sig call_detail+ // enter call (version_no < 4) |
| 104 | | 0x01 call_no call_detail+ // leave call |
| 105 | |
| 106 | call_sig = id function_name count arg_name* // first occurrence |
| 107 | | id // follow-on occurrences |
| 108 | |
| 109 | call_detail = 0x00 // terminator |
| 110 | | 0x01 arg_no value // argument value |
| 111 | | 0x02 value // return value |
| 112 | | 0x03 thread_no // thread number (version_no < 4) |
| 113 | | 0x04 count frame* // stack backtrace |
Jose Fonseca | af0d45b | 2017-06-28 22:35:37 +0100 | [diff] [blame] | 114 | | 0x05 uint // flag |
José Fonseca | 38ab518 | 2014-05-23 21:16:11 +0100 | [diff] [blame] | 115 | |
| 116 | arg_name = string |
| 117 | function_name = string |
| 118 | |
| 119 | arg_no = uint |
| 120 | call_no = uint |
| 121 | thread_no = uint |
| 122 | |
| 123 | id = uint |
| 124 | |
| 125 | ### Values ### |
| 126 | |
| 127 | value = 0x00 // null pointer |
| 128 | | 0x01 // false value |
| 129 | | 0x02 // true |
| 130 | | 0x03 uint // negative integer |
| 131 | | 0x04 uint // positive integer value |
| 132 | | 0x05 float // single-precision floating point value |
| 133 | | 0x06 double // double-precision floating point value |
| 134 | | 0x07 string // character string value (zero terminator implied) |
| 135 | | 0x08 string // binary blob |
José Fonseca | 1ba7d25 | 2014-06-03 13:24:32 +0100 | [diff] [blame] | 136 | | 0x09 enum_sig value // enumeration (version_no >= 3) |
| 137 | | 0x09 string value // enumeration (version_no < 3) |
| 138 | | 0x0a bitmask_sig value // integer bitmask |
| 139 | | 0x0b count value* // array |
| 140 | | 0x0c struct_sig value* // structure |
| 141 | | 0x0d uint // opaque pointer |
| 142 | | 0x0e value value // human-machine representation |
José Fonseca | d5cda7c | 2014-09-25 15:19:09 +0100 | [diff] [blame] | 143 | | 0x0f wstring // wide character string value (zero terminator implied) |
José Fonseca | 38ab518 | 2014-05-23 21:16:11 +0100 | [diff] [blame] | 144 | |
| 145 | enum_sig = id count (name value)+ // first occurrence |
| 146 | | id // follow-on occurrences |
| 147 | |
Jose Fonseca | b5ce015 | 2016-10-05 22:32:47 +0100 | [diff] [blame] | 148 | bitmask_sig = id count (name uint)+ // first occurrence |
| 149 | | id // follow-on occurrences |
José Fonseca | 38ab518 | 2014-05-23 21:16:11 +0100 | [diff] [blame] | 150 | |
Jose Fonseca | b5ce015 | 2016-10-05 22:32:47 +0100 | [diff] [blame] | 151 | struct_sig = id struct_name count member_name* // first occurrence |
| 152 | | id // follow-on occurrences |
José Fonseca | 38ab518 | 2014-05-23 21:16:11 +0100 | [diff] [blame] | 153 | |
| 154 | name = string |
Jose Fonseca | b5ce015 | 2016-10-05 22:32:47 +0100 | [diff] [blame] | 155 | struct_name = string |
José Fonseca | 38ab518 | 2014-05-23 21:16:11 +0100 | [diff] [blame] | 156 | member_name = string |
| 157 | |
José Fonseca | d5cda7c | 2014-09-25 15:19:09 +0100 | [diff] [blame] | 158 | wstring = count uint* |
| 159 | |
José Fonseca | 38ab518 | 2014-05-23 21:16:11 +0100 | [diff] [blame] | 160 | ### Backtraces ### |
| 161 | |
| 162 | frame = id frame_detail+ // first occurrence |
| 163 | | id // follow-on occurrences |
| 164 | |
| 165 | frame_detail = 0x00 // terminator |
| 166 | | 0x01 string // module name |
| 167 | | 0x02 string // function name |
| 168 | | 0x03 string // source file name |
| 169 | | 0x04 uint // source line number |
| 170 | | 0x05 uint // byte offset from module start |