Commit | Line | Data |
---|---|---|
fffd4c7d PP |
1 | barectf |
2 | ======= | |
3 | ||
4 | **barectf** is a command-line utility which generates pure C99 | |
5 | code that is able to write native | |
6 | [CTF](http://git.efficios.com/?p=ctf.git;a=blob_plain;f=common-trace-format-specification.txt;hb=master) | |
7 | (the Common Trace Format) out of a pre-written CTF metadata file. | |
8 | ||
9 | You will find barectf interesting if: | |
10 | ||
11 | 1. You need to trace a program. | |
12 | 2. You need tracing to be as fast as possible, but also very flexible: | |
13 | record integers of custom sizes, custom floating point numbers, | |
14 | enumerations mapped to a specific integer type, structure fields, | |
15 | NULL-terminated strings, static and dynamic arrays, etc. | |
16 | 3. You need to be able to convert the recorded binary events to | |
17 | human-readable text, as well as analyze them with Python scripts | |
18 | ([Babeltrace](http://www.efficios.com/babeltrace) does all that, | |
19 | given a CTF input). | |
20 | 4. You _cannot_ use [LTTng](http://lttng.org/), an efficient tracing | |
21 | framework for the Linux kernel and Linux/BSD user applications, which | |
22 | outputs CTF. | |
23 | ||
24 | The target audience of barectf is developers who need to trace bare metal | |
25 | systems (without an operating system). The code produced by barectf | |
26 | is pure C99 and is lightweight enough to fit on a tiny microcontroller. | |
27 | Each event described in the CTF metadata input becomes one C function with | |
28 | one parameter mapped to one event field. CTF data is recorded in a buffer of | |
29 | any size provided by the user. This buffer corresponds to one CTF packet. | |
30 | The generated tracing functions report when the buffer is full. The user | |
31 | is entirely responsible for the buffering scheme: leave the buffer in memory, | |
32 | save it to some permanent storage, swap it with another empty buffer and | |
33 | concatenate recorded packets, etc. | |
34 | ||
35 | barectf is written in Python 3 and currently uses | |
36 | [pytsdl](https://github.com/eepp/pytsdl) to parse the CTF metadata file | |
37 | provided by the user. | |
38 | ||
39 | ||
40 | installing | |
41 | ---------- | |
42 | ||
43 | Make sure you have `pip` for Python 3. On the latest Ubuntu releases, | |
44 | it is called `pip3`: | |
45 | ||
46 | sudo apt-get install python3-pip | |
47 | ||
48 | On Ubuntu 12.04, you need to install `setuptools` first, then use | |
49 | `easy_install3` to install `pip3`: | |
50 | ||
51 | sudo apt-get install python3-setuptools | |
52 | sudo easy_install3 pip | |
53 | ||
54 | Install barectf: | |
55 | ||
56 | sudo pip3 install barectf | |
57 | ||
58 | ||
59 | using | |
60 | ----- | |
61 | ||
62 | Using barectf involves: | |
63 | ||
64 | 1. Writing the CTF metadata file describing the various headers, | |
65 | contexts and event fields. | |
66 | 2. Running the `barectf` command to generate C99 files out of | |
67 | the CTF metadata file. | |
68 | 3. Using the generated C code in your specific application. | |
69 | ||
70 | The following subsections explain the three steps above. | |
71 | ||
72 | ||
73 | ### writing the CTF metadata | |
74 | ||
75 | The **Common Trace Format** is a specialized file format for recording | |
76 | trace data. CTF is designed to be very fast to write and very flexible. | |
77 | All headers, contexts and event fields written in binary files are | |
78 | described using a custom C-like, declarative language, TSDL (Trace | |
79 | Stream Description Language). The file containing this description is | |
80 | called the **CTF metadata**. The latter may be automatically generated | |
81 | by a tracer, like it is the case of LTTng, or written by hand. This | |
82 | metadata file is then used by CTF trace readers to know the layout of | |
83 | CTF binary files containing actual event contexts and fields. | |
84 | ||
85 | The CTF metadata file contains several blocks describing various CTF | |
86 | binary layouts. A CTF trace file is a concatenation of several CTF | |
87 | packets. Here's the anatomy of a CTF packet: | |
88 | ||
89 | ![CTF packet anatomy](doc/ctf-packet.png) | |
90 | ||
91 | A CTF packet belongs to a specific CTF stream. While the packet header | |
92 | is the same for all streams of a given CTF trace, everything else is | |
93 | specified per stream. Following this packet header is a packet context, | |
94 | and then actual recorded events. Each event starts with a mandatory | |
95 | header (same event header for all events of a given stream). The event | |
96 | header is followed by an optional event context with a layout shared | |
97 | by all events of a given stream. Then follows another optional event | |
98 | context, although this one has a layout specific to the event type. | |
99 | Finally, event fields are written. | |
100 | ||
101 | barectf asks you to write the CTF metadata by hand. Although its official | |
102 | [specification](http://git.efficios.com/?p=ctf.git;a=blob_plain;f=common-trace-format-specification.txt;hb=master) | |
103 | is thorough, you will almost always start from this template: | |
104 | ||
105 | ``` | |
106 | /* CTF 1.8 */ | |
107 | ||
108 | // a few useful standard integer aliases | |
109 | typealias integer {size = 8; align = 8;} := uint8_t; | |
110 | typealias integer {size = 16; align = 16;} := uint16_t; | |
111 | typealias integer {size = 32; align = 32;} := uint32_t; | |
112 | typealias integer {size = 64; align = 64;} := uint64_t; | |
113 | typealias integer {size = 8; align = 8; signed = true;} := int8_t; | |
114 | typealias integer {size = 16; align = 16; signed = true;} := int16_t; | |
115 | typealias integer {size = 32; align = 32; signed = true;} := int32_t; | |
116 | typealias integer {size = 64; align = 64; signed = true;} := int64_t; | |
117 | ||
118 | // IEEE 754 standard-precision floating point alias | |
119 | typealias floating_point { | |
120 | exp_dig = 8; | |
121 | mant_dig = 24; | |
122 | align = 32; | |
123 | } := float; | |
124 | ||
125 | // IEEE 754 double-precision floating point alias | |
126 | typealias floating_point { | |
127 | exp_dig = 11; | |
128 | mant_dig = 53; | |
129 | align = 64; | |
130 | } := double; | |
131 | ||
132 | // trace block | |
133 | trace { | |
134 | // CTF version 1.8; leave this as is | |
135 | major = 1; | |
136 | minor = 8; | |
137 | ||
138 | /* Native byte order (`le` or `be`). This is used by barectf to generate | |
139 | * the appropriate code when writing data to the packet. | |
140 | */ | |
141 | byte_order = le; | |
142 | ||
143 | /* Packet header. All packets (buffers) will have the same header. | |
144 | * | |
145 | * Special fields recognized by barectf (must appear in this order): | |
146 | * | |
147 | * magic: will be set to CTF's magic number (must be the first field) | |
148 | * (32-bit unsigned integer) | |
149 | * stream_id: will be set to the ID of the stream associated with | |
150 | * this packet (unsigned integer of your choice) (mandatory) | |
151 | */ | |
152 | packet.header := struct { | |
153 | uint32_t magic; | |
154 | uint32_t stream_id; | |
155 | }; | |
156 | }; | |
157 | ||
158 | // environment variables; you may add custom entries | |
159 | env { | |
160 | domain = "bare"; | |
161 | tracer_name = "barectf"; | |
162 | tracer_major = 0; | |
163 | tracer_minor = 1; | |
164 | tracer_patchlevel = 0; | |
165 | }; | |
166 | ||
167 | // clock descriptor | |
168 | clock { | |
169 | // clock name | |
170 | name = my_clock; | |
171 | ||
172 | // clock frequency (Hz) | |
173 | freq = 1000000000; | |
174 | ||
175 | // optional clock value offset (offfset from Epoch is: offset * (1 / freq)) | |
176 | offset = 0; | |
177 | }; | |
178 | ||
179 | // alias for integer used to hold clock cycles | |
180 | typealias integer { | |
181 | size = 32; | |
182 | ||
183 | // map to the appropriate clock using its name | |
184 | map = clock.my_clock.value; | |
185 | } := my_clock_int_t; | |
186 | ||
187 | /* A stream. You may have as many streams as you want. Events are unique | |
188 | * within their own stream. The main advantage of having multiple streams | |
189 | * is having different event headers, stream event contexts and stream | |
190 | * packet contexts for each one. | |
191 | */ | |
192 | stream { | |
193 | /* Mandatory stream ID (must fit the integer type of | |
194 | * `trace.packet.header.stream_id`. | |
195 | */ | |
196 | id = 0; | |
197 | ||
198 | /* Mandatory packet context. This structure follows the packet header | |
199 | * (see `trace.packet.header`) immediately in CTF binary streams. | |
200 | * | |
201 | * Special fields recognized by barectf: | |
202 | * | |
203 | * timestamp_begin: will be set to the current clock value when opening | |
204 | * the packet (same integer type as the clock's value) | |
205 | * timestamp_end: will be set to the current clock value when closing | |
206 | * the packet (same integer type as the clock's value) | |
207 | * content_size: will be set to the content size, in bits, of this | |
208 | * stream (unsigned 32-bit or 64-bit integer) (mandatory) | |
209 | * packet_size: will be set to the packet size, in bits, of this | |
210 | * stream (unsigned 32-bit or 64-bit integer) (mandatory) | |
211 | * cpu_id: if present, the barectf_open_packet() function of this | |
212 | * stream will accept an additional parameter to specify the | |
213 | * ID of the CPU associated with this stream (a given | |
214 | * stream should only be written to by a specific CPU) | |
215 | * (unsigned integer of your choice) | |
216 | * | |
217 | * `timestamp_end` must be present if `timestamp_begin` exists. | |
218 | */ | |
219 | packet.context := struct { | |
220 | my_clock_int_t timestamp_begin; | |
221 | my_clock_int_t timestamp_end; | |
222 | uint64_t content_size; | |
223 | uint64_t packet_size; | |
224 | uint32_t cpu_id; | |
225 | }; | |
226 | ||
227 | /* Mandatory event header. All events recorded in this stream will start | |
228 | * with this structure. | |
229 | * | |
230 | * Special fields recognized by barectf: | |
231 | * | |
232 | * id: will be filled by the event ID corresponding to a tracing | |
233 | * function (unsigned integer of your choice) | |
234 | * timestamp: will be filled by the current clock's value (same integer | |
235 | * type as the clock's value) | |
236 | */ | |
237 | event.header := struct { | |
238 | uint32_t id; | |
239 | my_clock_int_t timestamp; | |
240 | }; | |
241 | ||
242 | /* Optional stream event context (you may remove the whole block or leave | |
243 | * the structure empty if you don't want any). This structure follows the | |
244 | * event header (see `stream.event.header`) immediately in CTF binary streams. | |
245 | */ | |
246 | event.context := struct { | |
247 | int32_t _some_stream_event_context_field; | |
248 | }; | |
249 | }; | |
250 | ||
251 | /* An event. Events have an ID, a name, an optional context and fields. An | |
252 | * event is associated to a specific stream using its stream ID. | |
253 | */ | |
254 | event { | |
255 | /* Mandatory event name. This is used by barectf to generate the suffix | |
256 | * of this event's corresponding tracing function, so make sure it follows | |
257 | * the C identifier syntax even though it's a quoted string here. | |
258 | */ | |
259 | name = "my_event"; | |
260 | ||
261 | /* Mandatory event ID (must fit the integer type of | |
262 | * in `stream.event.header.id` of the associated stream). | |
263 | */ | |
264 | id = 0; | |
265 | ||
266 | // ID of the stream in which this event will be recorded | |
267 | stream_id = 0; | |
268 | ||
269 | /* Optional event context (you may remove the whole block or leave the | |
270 | * structure empty if you don't want one). This structure follows the | |
271 | * stream event context (if it exists) immediately in CTF binary streams. | |
272 | */ | |
273 | context := struct { | |
274 | int32_t _some_event_context_field; | |
275 | }; | |
276 | ||
277 | /* Mandatory event fields (although the structure may be left empty if this | |
278 | * event has no fields). This structure follows the event context (if it | |
279 | * exists) immediately in CTF binary streams. | |
280 | */ | |
281 | fields := struct { | |
282 | uint32_t _a; | |
283 | uint32_t _b; | |
284 | uint16_t _c; | |
285 | string _d; | |
286 | }; | |
287 | }; | |
288 | ``` | |
289 | ||
290 | The top `/* CTF 1.8 */` is actually needed right there, and as is, since it | |
291 | acts as a CTF metadata magic number for CTF readers. | |
292 | ||
293 | Only one stream and one event (belonging to this single stream) are described | |
294 | in this template, but you may add as many as you need. | |
295 | ||
296 | The following subsections describe the features of CTF metadata supported | |
297 | by barectf. | |
298 | ||
299 | ||
300 | #### types | |
301 | ||
302 | The supported structure field types are: | |
303 | ||
304 | * **integers** of any size (64-bit and less), any alignment (power of two) | |
305 | * **floating point numbers** of any total size (64-bit and less), any | |
306 | alignment (power of two) | |
307 | * NULL-terminated **strings** of bytes | |
308 | * **enumerations** associated with a specific integer type | |
309 | * **static** and **dynamic arrays** of any type | |
310 | * **structures** containing only integers, floating point numbers, | |
311 | enumerations and _static_ arrays | |
312 | ||
313 | CTF also supports _variants_ (dynamic selection between different types), | |
314 | but barectf **does not**. Any detected variant will throw an error when | |
315 | running `barectf`. | |
316 | ||
317 | ||
318 | ##### integers | |
319 | ||
320 | CTF integers are defined like this: | |
321 | ||
322 | ``` | |
323 | integer { | |
324 | // mandatory size in bits (64-bit and less) | |
325 | size = 16; | |
326 | ||
327 | /* Optional alignment in bits (power of two). Default is 8 when the | |
328 | * size is a multiple of 8, and 1 otherwise. | |
329 | */ | |
330 | align = 16; | |
331 | ||
332 | // optional signedness (`true` or `false`); default is unsigned | |
333 | signed = true; | |
334 | ||
335 | /* Optional byte order (`le`, `be`, `native` or `network`). `native` | |
336 | * will use the byte order specified by the `trace.byte_order`. | |
337 | * Default is `native`. | |
338 | */ | |
339 | byte_order = le; | |
340 | ||
341 | /* Optional display base, used to display the integer value when | |
342 | * reading the trace. Valid values are 2 (or `binary`, `bin` and `b`), | |
343 | * 8 (or `o`, `oct` or `octal`), 10 (or `u`, `i`, `d`, `dec` or | |
344 | * `decimal`), and 16 (or `x`, `X`, `p`, `hex` or `hexadecimal`). | |
345 | * Default is 10. | |
346 | */ | |
347 | base = hex; | |
348 | ||
349 | /* Encoding (if this integer represents a character). Valid values | |
350 | * are `none`, `UTF8` and `ASCII`. Default is `none`. | |
351 | */ | |
352 | encoding = UTF8; | |
353 | } | |
354 | ``` | |
355 | ||
356 | The size (the only mandatory property) does _not_ have to be a power of two: | |
357 | ||
358 | ``` | |
359 | integer {size = 23;} | |
360 | ``` | |
361 | ||
362 | is perfectly valid. | |
363 | ||
364 | A CTF integer field will make barectf produce a corresponding C integer | |
365 | function parameter with an appropriate size. For example, the 23-bit integer | |
366 | above would produce an `uint32_t` parameter (of which only the first 23 | |
367 | least significant bits will be written to the trace), while the first | |
368 | 16-bit one will produce an `int16_t` parameter. | |
369 | ||
370 | The `integer` block also accepts a `map` property which is only used | |
371 | when defining the integer used to carry the value of a specified | |
372 | clock. You may always follow the example above. | |
373 | ||
374 | ||
375 | ##### floating point numbers | |
376 | ||
377 | CTF floating point numbers are defined like this: | |
378 | ||
379 | ``` | |
380 | floating_point { | |
381 | // exponent size in bits | |
382 | exp_dig = 8; | |
383 | ||
384 | // mantissa size in bits | |
385 | mant_dig = 24; | |
386 | ||
387 | /* Optional alignment (power of two). Default is 8 when the total | |
388 | * size (exponent + mantissa) is a multiple of 8, and 1 otherwise. | |
389 | */ | |
390 | align = 32; | |
391 | ||
392 | /* Optional byte order (`le`, `be`, `native` or `network`). `native` | |
393 | * will use the byte order specified by the `trace.byte_order`. | |
394 | * Default is `native`. | |
395 | */ | |
396 | byte_order = le; | |
397 | } | |
398 | ``` | |
399 | ||
400 | If a CTF floating point number is defined with an 8-bit exponent, a 24-bit | |
401 | mantissa and a 32-bit alignment, its barectf C function parameter type will | |
402 | be `float`. It will be `double` for an 11-bit exponent, 53-bit mantissa | |
403 | and 64-bit aligned CTF floating point number. Any other configuration | |
404 | will produce a `uint64_t` function parameter (you will need to cast your | |
405 | custom floating point number to this when calling the tracing function). | |
406 | ||
407 | ||
408 | ##### strings | |
409 | ||
410 | CTF strings are pretty simple to define: | |
411 | ||
412 | ``` | |
413 | string | |
414 | ``` | |
415 | ||
416 | They may also have an encoding property: | |
417 | ||
418 | ``` | |
419 | string { | |
420 | // encoding: `none`, `UTF8` or `ASCII`; default is `none` | |
421 | encoding = UTF8; | |
422 | } | |
423 | ``` | |
424 | ||
425 | CTF strings are always byte-aligned. | |
426 | ||
427 | A CTF string field will make barectf produce a corresponding C function | |
428 | parameter of type `const char*`. Bytes will be copied from this pointer | |
429 | until a byte of value 0 is found (which will also be written to the | |
430 | buffer to mark the end of the recorded string). | |
431 | ||
432 | ||
433 | ##### enumerations | |
434 | ||
435 | CTF enumerations associate labels to ranges of integer values. They | |
436 | are a great way to trace named states using an integer. Here's an | |
437 | example: | |
438 | ||
439 | ``` | |
440 | enum : uint32_t { | |
441 | ZERO, | |
442 | ONE, | |
443 | TWO, | |
444 | TEN = 10, | |
445 | ELEVEN, | |
446 | "label with spaces", | |
447 | RANGE = 23 ... 193 | |
448 | } | |
449 | ``` | |
450 | ||
451 | Unless the first entry specifies a value, CTF enumerations are | |
452 | always started at 0. They work pretty much like their C counterpart, | |
453 | although they support ranges and literal strings as labels. | |
454 | ||
455 | CTF enumerations are associated with a CTF integer type (`uint32_t` | |
456 | above). This identifier must be an existing integer type alias. | |
457 | ||
458 | A CTF enumeration field will make barectf produce a corresponding C | |
459 | integer function parameter compatible with the associated CTF integer type. | |
460 | ||
461 | ||
462 | ##### static arrays | |
463 | ||
464 | Structure field names may be followed by a subscripted constant to | |
465 | define a static array of the field type: | |
466 | ||
467 | ``` | |
468 | struct { | |
469 | integer {size = 16;} _field[10]; | |
470 | } | |
471 | ``` | |
472 | ||
473 | In the above structure, `_field` is a static array of ten 16-bit integers. | |
474 | ||
475 | A CTF static array field will make barectf produce a `const void*` C function | |
476 | parameter. Bytes will be copied from this pointer to match the total static | |
477 | array size. In the example above, the integer size is 16-bit, thus its | |
478 | default alignment is 8-bit, so 20 bytes would be copied. | |
479 | ||
480 | The inner element of a CTF static array _must be at least byte-aligned_ | |
481 | (8-bit), either by forcing its alignment, or by ensuring it manually | |
482 | when placing fields one after the other. This means the following static | |
483 | array is valid for barectf: | |
484 | ||
485 | ``` | |
486 | struct { | |
487 | // ... | |
488 | integer {size = 5;} _field[10]; | |
489 | } | |
490 | ``` | |
491 | ||
492 | as long as the very first 5-bit, 1-bit aligned integer element starts | |
493 | on an 8-bit boundary. | |
494 | ||
495 | ||
496 | ##### dynamic arrays | |
497 | ||
498 | Just like static arrays, dynamic arrays are defined using a subscripted | |
499 | length, albeit in this case, this length refers to another field using | |
500 | the dot notation. Dynamic arrays are called _sequences_ in the CTF | |
501 | specification. | |
502 | ||
503 | Here's an example: | |
504 | ||
505 | ``` | |
506 | struct { | |
507 | uint32_t _length; | |
508 | integer {size = 16;} _field[_length]; | |
509 | } | |
510 | ``` | |
511 | ||
512 | In the above structure, `_field` is a dynamic array of `_length` | |
513 | 16-bit integers. | |
514 | ||
515 | There are various scopes to which a dynamic array may refer: | |
516 | ||
517 | * no prefix: previous field in the same structure, or in parent | |
518 | structures until found | |
519 | * `event.fields.` prefix: field of the event fields | |
520 | * `event.context.` prefix: field of the event context if it exists | |
521 | * `stream.event.context.` prefix: field of the stream event context | |
522 | if it exists | |
523 | * `stream.event.header.` prefix: field of the event header | |
524 | * `stream.packet.context.` prefix: field of the packet context | |
525 | * `trace.packet.header.` prefix: field of the packet header | |
526 | * `env.` prefix: static property of the environment block | |
527 | ||
528 | Here's another, more complex example: | |
529 | ||
530 | ``` | |
531 | struct { | |
532 | uint32_t _length; | |
533 | string _other_field[stream.event.context.length]; | |
534 | float _static_array_of_dynamic_arrays[10][_length]; | |
535 | } | |
536 | ``` | |
537 | ||
538 | The above examples also demonstrates that dynamic arrays and static | |
539 | arrays may contain eachother. `_other_field` is a dynamic array of | |
540 | `stream.event.context.length` strings. `_static_array_of_dynamic_arrays` | |
541 | is a static array of 10 dynamic arrays of `_length` floating point | |
542 | numbers. This syntax follows the C language. | |
543 | ||
544 | A CTF dynamic array field will make barectf produce a `const void*` C function | |
545 | parameter. Bytes will be copied from this pointer to match the | |
546 | total dynamic array size. The previously recorded length will be | |
547 | found automatically (always an offset from the beginning of the | |
548 | stream packet, or from the beginning of the current event). | |
549 | ||
550 | barectf has a few limitations concerning dynamic arrays: | |
551 | ||
552 | * The inner element of a CTF dynamic array _must be at least byte-aligned_ | |
553 | (8-bit), either by forcing its alignment, or by ensuring it manually | |
554 | when placing fields one after the other. | |
555 | * The length type must be a 32-bit, byte-aligned unsigned integer | |
556 | with a native byte order. | |
557 | ||
558 | ||
559 | ##### structures | |
560 | ||
561 | Structures contain fields associating a name to a type. The fields | |
562 | are recorded in the specified order within the CTF binary stream. | |
563 | ||
564 | Here's an example: | |
565 | ||
566 | ``` | |
567 | struct { | |
568 | uint32_t _a; | |
569 | int16_t _b; | |
570 | string {encoding = ASCII;} _c; | |
571 | } | |
572 | ``` | |
573 | ||
574 | The default alignment of a structure is the largest alignment amongst | |
575 | its fields. For example, the following structure has a 32-bit alignment: | |
576 | ||
577 | ``` | |
578 | struct { | |
579 | uint16_t _a; // alignment: 16 | |
580 | struct { // alignment: 32 | |
581 | uint32_t _a; // alignment: 32 | |
582 | string; _b; // alignment: 8 | |
583 | } _b; | |
584 | integer {size = 64;} _c; // alignment: 8 | |
585 | } | |
586 | ``` | |
587 | ||
588 | This default alignment may be overridden using a special `align()` | |
589 | option after the structure is closed: | |
590 | ||
591 | ``` | |
592 | struct { | |
593 | uint16_t _a; // alignment: 16 | |
594 | struct { // alignment: 32 | |
595 | uint32_t _a; // alignment: 32 | |
596 | string; _b; // alignment: 8 | |
597 | } _b; | |
598 | integer {size = 64;} _c; // alignment: 8 | |
599 | } align(16) | |
600 | ``` | |
601 | ||
602 | You may use structures as field types, although they must have a | |
603 | _known size_ when running barectf. This means they cannot contain | |
604 | sequences or strings. | |
605 | ||
606 | A CTF structure field will make barectf produce a `const void*` C function | |
607 | parameter. The structure (of known size) will be copied as is to the | |
608 | current buffer, respecting its alignment. | |
609 | ||
610 | Note that barectf requires inner structures to be at least byte-aligned. | |
611 | ||
612 | Be careful when using CTF structures for recording binary structures | |
613 | declared in C. You need to make sure your C compiler aligns structure | |
614 | fields and adds padding exactly in the way you define your equivalent | |
615 | CTF structure. For example, using GCC on the x86 architecture, 3 bytes | |
616 | are added after field `a` in the following C structure since `b` is | |
617 | 32-bit aligned: | |
618 | ||
619 | ```c | |
620 | struct my_struct { | |
621 | char a; | |
622 | unsigned int b; | |
623 | }; | |
624 | ``` | |
625 | ||
626 | It would be wrong to use the following CTF structure: | |
627 | ||
628 | ``` | |
629 | struct { | |
630 | integer {size = 8; signed = true;} a; | |
631 | integer {size = 32;} b; | |
632 | } | |
633 | ``` | |
634 | ||
635 | since field `b` is byte-aligned by default. This one would work fine: | |
636 | ||
637 | ``` | |
638 | struct { | |
639 | integer {size = 8; signed = true;} a; | |
640 | integer {size = 32; align = 32;} b; | |
641 | } | |
642 | ``` | |
643 | ||
644 | CTF structures can prove very useful for recording protocols with named | |
645 | fields when reading the trace. For example, here's the CTF structure | |
646 | describing the IPv4 header (excluding options): | |
647 | ||
648 | ``` | |
649 | struct ipv4_header { | |
650 | integer {size = 4;} version; | |
651 | integer {size = 4;} ihl; | |
652 | integer {size = 6;} dscp; | |
653 | integer {size = 2;} ecn; | |
654 | integer {size = 16; byte_order = network;} total_length; | |
655 | integer {size = 16; byte_order = network;} identification; | |
656 | integer {size = 1;} flag_more_fragment; | |
657 | integer {size = 1;} flag_dont_fragment; | |
658 | integer {size = 1;} flag_reserved; | |
659 | integer {size = 13; byte_order = network;} fragment_offset; | |
660 | integer {size = 8;} ttl; | |
661 | integer {size = 8;} protocol; | |
662 | integer {size = 16; byte_order = network;} header_checksum; | |
663 | integer {size = 8;} src_ip_addr[4]; | |
664 | integer {size = 8;} dst_ip_addr[4]; | |
665 | } | |
666 | ``` | |
667 | ||
668 | ||
669 | #### type aliases | |
670 | ||
671 | Type aliases associate a name with a type definition. Any type may have | |
672 | any name. They are similar to C `typedef`s. | |
673 | ||
674 | Examples: | |
675 | ||
676 | ``` | |
677 | typealias integer { | |
678 | size = 16; | |
679 | align = 4; | |
680 | signed = true; | |
681 | byte_order = network; | |
682 | base = hex; | |
683 | encoding = UTF8; | |
684 | } := my_int; | |
685 | ``` | |
686 | ||
687 | ``` | |
688 | typealias floating_point { | |
689 | exp_dig = 8; | |
690 | mant_dig = 8; | |
691 | align = 16; | |
692 | byte_order = be; | |
693 | } := my_float; | |
694 | ``` | |
695 | ||
696 | ``` | |
697 | typealias string { | |
698 | encoding = ASCII; | |
699 | } := my_string; | |
700 | ``` | |
701 | ||
702 | ``` | |
703 | typealias enum : uint32_t { | |
704 | ZERO, | |
705 | ONE, | |
706 | TWO, | |
707 | TEN = 10, | |
708 | ELEVEN, | |
709 | "label with spaces", | |
710 | RANGE = 23 ... 193 | |
711 | } := my_enum; | |
712 | ``` | |
713 | ||
714 | ``` | |
715 | typealias struct { | |
716 | uint32_t _length; | |
717 | string _other_field; | |
718 | float _hello[10][_length]; | |
719 | } align(8) := my_struct; | |
720 | ``` | |
721 | ||
722 | ||
723 | ### running the `barectf` command | |
724 | ||
725 | Using the `barectf` command-line utility is easy. In its simplest form, | |
726 | it outputs a few C99 files out of a CTF metadata file: | |
727 | ||
728 | barectf metadata | |
729 | ||
730 | will output in the current working directory: | |
731 | ||
732 | * `barectf_bitfield.h`: macros used by tracing functions to pack bits | |
733 | * `barectf.h`: other macros and prototypes of context/tracing functions | |
734 | * `barectf.c`: context/tracing functions | |
735 | ||
736 | You may also want to produce `static inline` functions if your target | |
737 | system has enough memory to hold the extra code: | |
738 | ||
739 | barectf --static-inline metadata | |
740 | ||
741 | `barectf` is the default name of the files and the default prefix of | |
742 | barectf C functions and structures. You may use a custom prefix: | |
743 | ||
744 | barectf --prefix trace metadata | |
745 | ||
746 | You may also output the files elsewhere: | |
747 | ||
748 | barectf --output /custom/path metadata | |
749 | ||
750 | ### using the generated C99 code | |
751 | ||
752 | This section assumes you ran `barectf` with no options: | |
753 | ||
754 | barectf metadata | |
755 | ||
756 | The command generates ANSI C structures and functions to initialize | |
757 | and finalize bare CTF contexts. It also generates as many tracing functions | |
758 | as there are events described in the CTF metadata file. | |
759 | ||
760 | Before starting the record events, you must initialize a barectf | |
761 | context. This is done using `barectf_init()`. | |
762 | ||
763 | The clock callback parameter (`clock_cb`) is used to get the clock whenever | |
764 | a tracing function is called. Each platform has its own way of obtaining | |
765 | the a clock value, so this is left to user implementation. The actual | |
766 | return type of the clock callback depends on the clock value CTF integer | |
767 | type defined in the CTF metadata. | |
768 | ||
769 | The `barectf_init()` function name will contain the decimal stream | |
770 | ID if you have more than one stream. You must allocate the context | |
771 | structure yourself. | |
772 | ||
773 | Example: | |
774 | ||
775 | ```c | |
776 | struct barectf_ctx* barectf_ctx = platform_alloc(sizeof(*barectf_ctx)); | |
777 | ||
778 | barectf_init(barectf_ctx, buf, 8192, platform_get_clock, NULL); | |
779 | ``` | |
780 | ||
781 | This initializes a barectf context with a buffer of 8192 bytes. | |
782 | ||
783 | After the barectf context is initialized, open a packet using | |
784 | `barectf_open_packet()`. If you have any non-special fields in | |
785 | your stream packet context, `barectf_open_packet()` accepts a | |
786 | parameter for each of them since the packet context is written | |
787 | at this moment: | |
788 | ||
789 | ``` | |
790 | barectf_open_packet(barectf_ctx); | |
791 | ``` | |
792 | ||
793 | Once the packet is opened, you may call any of the tracing functions to record | |
794 | CTF events into the context's buffer. | |
795 | ||
796 | As an example, let's take the following CTF event definition: | |
797 | ||
798 | ``` | |
799 | event { | |
800 | name = "my_event"; | |
801 | id = 0; | |
802 | stream_id = 0; | |
803 | fields := struct { | |
804 | integer {size = 32;} _a; | |
805 | integer {size = 14; signed = true;} _b; | |
806 | floating_point {exp_dig = 8; mant_dig = 24; align = 32;} _c; | |
807 | struct { | |
808 | uint32_t _a; | |
809 | uint32_t _b; | |
810 | } _d; | |
811 | string _e; | |
812 | }; | |
813 | }; | |
814 | ``` | |
815 | ||
816 | In this example, we assume the stream event context and the event context | |
817 | are not defined for this event. `barectf` generates the following tracing | |
818 | function prototype: | |
819 | ||
820 | ```c | |
821 | int barectf_trace_my_event( | |
822 | struct barectf_ctx* ctx, | |
823 | uint32_t param_ef__a, | |
824 | int16_t param_ef__b, | |
825 | float param_ef__c, | |
826 | const void* param_ef__d, | |
827 | const char* param_ef__e | |
828 | ); | |
829 | ``` | |
830 | ||
831 | When called, this function first calls the clock callback to get a clock | |
832 | value as soon as possible. It then proceeds to record each field with | |
833 | proper alignment and updates the barectf context. On success, 0 is returned. | |
834 | Otherwise, one of the following negative errors is returned: | |
835 | ||
836 | * `-EBARECTF_NOSPC`: no space left in the context's buffer; the event | |
837 | was **not** recorded. You should call `barectf_close_packet()` to finalize the | |
838 | CTF packet. | |
839 | ||
840 | `barectf_close_packet()` may be called at any time. | |
841 | When `barectf_close_packet()` returns, the packet is complete and ready | |
842 | to be read by a CTF reader. CTF packets may be concatenated in a single | |
843 | CTF stream file. You may reuse the same context and buffer to record another | |
844 | CTF packet, as long as you call `barectf_open_packet()` before calling any | |
845 | tracing function. | |
846 | ||
847 | ||
848 | ### reading CTF traces | |
849 | ||
850 | To form a complete CTF trace, put your CTF metadata file (it should be | |
851 | named `metadata`) and your binary stream files (concatenations of CTF | |
852 | packets written by C code generated by barectf) in the same directory. | |
853 | ||
854 | To read a CTF trace, use [Babeltrace](http://www.efficios.com/babeltrace). | |
855 | Babeltrace is packaged by most major distributions (`babeltrace`). | |
856 | Babeltrace ships with a command-line utility that can convert a CTF trace | |
857 | to human-readable text output. Also, it includes a Python binding so | |
858 | that you may analyze a CTF trace using a custom script. | |
859 | ||
860 | In its simplest form, the `babeltrace` command-line converter is quite | |
861 | easy to use: | |
862 | ||
863 | babeltrace /path/to/directory/containing/ctf/files | |
864 | ||
865 | See `babeltrace --help` for more options. | |
866 | ||
867 | You may also use the Python 3 binding of Babeltrace to create custom | |
868 | analysis scripts. |