Commit | Line | Data |
---|---|---|
5e0cbfb0 PP |
1 | --- |
2 | id: defining-tracepoints | |
3 | --- | |
4 | ||
5 | As written in [Tracepoint provider](#doc-tracepoint-provider), | |
6 | tracepoints are defined using the | |
7 | `TRACEPOINT_EVENT()` macro. Each tracepoint, when called using the | |
8 | `tracepoint()` macro in the actual application's source code, generates | |
9 | a specific event type with its own fields. | |
10 | ||
11 | Let's have another look at the example above, with a few added comments: | |
12 | ||
13 | ~~~ c | |
14 | TRACEPOINT_EVENT( | |
15 | /* tracepoint provider name */ | |
16 | my_provider, | |
17 | ||
18 | /* tracepoint/event name */ | |
19 | my_first_tracepoint, | |
20 | ||
21 | /* list of tracepoint arguments */ | |
22 | TP_ARGS( | |
23 | int, my_integer_arg, | |
24 | char*, my_string_arg | |
25 | ), | |
26 | ||
27 | /* list of fields of eventual event */ | |
28 | TP_FIELDS( | |
29 | ctf_string(my_string_field, my_string_arg) | |
30 | ctf_integer(int, my_integer_field, my_integer_arg) | |
31 | ) | |
32 | ) | |
33 | ~~~ | |
34 | ||
35 | The tracepoint provider name must match the name of the tracepoint | |
36 | provider in which this tracepoint is defined | |
37 | (see [Tracepoint provider](#doc-tracepoint-provider)). In other words, | |
38 | always use the same string as the value of `TRACEPOINT_PROVIDER` above. | |
39 | ||
47bfcb75 | 40 | The tracepoint name becomes the event name once events are recorded |
5e0cbfb0 PP |
41 | by the LTTng-UST tracer. It must follow the tracepoint provider name |
42 | syntax: start with a letter and contain either letters, numbers or | |
43 | underscores. Two tracepoints under the same provider cannot have the | |
44 | same name, i.e. you cannot overload a tracepoint like you would | |
45 | overload functions and methods in C++/Java. | |
46 | ||
47 | <div class="tip"> | |
48 | <p><span class="t">Note:</span>The concatenation of the tracepoint | |
49 | provider name and the tracepoint name cannot exceed 254 characters. If | |
47bfcb75 PP |
50 | it does, the instrumented application compiles and runs, but LTTng |
51 | issues multiple warnings and you could experience serious problems.</p> | |
5e0cbfb0 PP |
52 | </div> |
53 | ||
54 | The list of tracepoint arguments gives this tracepoint its signature: | |
55 | see it like the declaration of a C function. The format of `TP_ARGS()` | |
56 | arguments is: C type, then argument name; repeat as needed, up to ten | |
57 | times. For example, if we were to replicate the signature of C standard | |
58 | library's `fseek()`, the `TP_ARGS()` part would look like: | |
59 | ||
60 | ~~~ c | |
61 | TP_ARGS( | |
62 | FILE*, stream, | |
63 | long int, offset, | |
64 | int, origin | |
65 | ), | |
66 | ~~~ | |
67 | ||
47bfcb75 | 68 | Of course, you need to include appropriate header files before |
5e0cbfb0 PP |
69 | the `TRACEPOINT_EVENT()` macro calls if any argument has a complex type. |
70 | ||
71 | `TP_ARGS()` may not be omitted, but may be empty. `TP_ARGS(void)` is | |
72 | also accepted. | |
73 | ||
74 | The list of fields is where the fun really begins. The fields defined | |
47bfcb75 | 75 | in this list are the fields of the events generated by the execution |
5e0cbfb0 | 76 | of this tracepoint. Each tracepoint field definition has a C |
47bfcb75 | 77 | _argument expression_ which is evaluated when the execution reaches |
5e0cbfb0 PP |
78 | the tracepoint. Tracepoint arguments _may be_ used freely in those |
79 | argument expressions, but they _don't_ have to. | |
80 | ||
81 | There are several types of tracepoint fields available. The macros to | |
82 | define them are given and explained in the | |
83 | [LTTng-UST library reference](#doc-liblttng-ust-tp-fields) section. | |
84 | ||
85 | Field names must follow the standard C identifier syntax: letter, then | |
86 | optional sequence of letters, numbers or underscores. Each field must have | |
87 | a different name. | |
88 | ||
89 | Those `ctf_*()` macros are added to the `TP_FIELDS()` part of | |
90 | `TRACEPOINT_EVENT()`. Note that they are not delimited by commas. | |
91 | `TP_FIELDS()` may be empty, but the `TP_FIELDS(void)` form is _not_ | |
92 | accepted. | |
93 | ||
94 | The following snippet shows how argument expressions may be used in | |
95 | tracepoint fields and how they may refer freely to tracepoint arguments. | |
96 | ||
97 | ~~~ c | |
98 | /* for struct stat */ | |
99 | #include <sys/types.h> | |
100 | #include <sys/stat.h> | |
101 | #include <unistd.h> | |
102 | ||
103 | TRACEPOINT_EVENT( | |
104 | my_provider, | |
105 | my_tracepoint, | |
106 | TP_ARGS( | |
107 | int, my_int_arg, | |
108 | char*, my_str_arg, | |
109 | struct stat*, st | |
110 | ), | |
111 | TP_FIELDS( | |
112 | /* simple integer field with constant value */ | |
113 | ctf_integer( | |
114 | int, /* field C type */ | |
115 | my_constant_field, /* field name */ | |
116 | 23 + 17 /* argument expression */ | |
117 | ) | |
118 | ||
119 | /* my_int_arg tracepoint argument */ | |
120 | ctf_integer( | |
121 | int, | |
122 | my_int_arg_field, | |
123 | my_int_arg | |
124 | ) | |
125 | ||
126 | /* my_int_arg squared */ | |
127 | ctf_integer( | |
128 | int, | |
129 | my_int_arg_field2, | |
130 | my_int_arg * my_int_arg | |
131 | ) | |
132 | ||
133 | /* sum of first 4 characters of my_str_arg */ | |
134 | ctf_integer( | |
135 | int, | |
136 | sum4, | |
137 | my_str_arg[0] + my_str_arg[1] + | |
138 | my_str_arg[2] + my_str_arg[3] | |
139 | ) | |
140 | ||
141 | /* my_str_arg as string field */ | |
142 | ctf_string( | |
143 | my_str_arg_field, /* field name */ | |
144 | my_str_arg /* argument expression */ | |
145 | ) | |
146 | ||
147 | /* st_size member of st tracepoint argument, hexadecimal */ | |
148 | ctf_integer_hex( | |
149 | off_t, /* field C type */ | |
150 | size_field, /* field name */ | |
151 | st->st_size /* argument expression */ | |
152 | ) | |
153 | ||
154 | /* st_size member of st tracepoint argument, as double */ | |
155 | ctf_float( | |
156 | double, /* field C type */ | |
157 | size_dbl_field, /* field name */ | |
158 | (double) st->st_size /* argument expression */ | |
159 | ) | |
160 | ||
161 | /* half of my_str_arg string as text sequence */ | |
162 | ctf_sequence_text( | |
163 | char, /* element C type */ | |
164 | half_my_str_arg_field, /* field name */ | |
165 | my_str_arg, /* argument expression */ | |
166 | size_t, /* length expression C type */ | |
167 | strlen(my_str_arg) / 2 /* length expression */ | |
168 | ) | |
169 | ) | |
170 | ) | |
171 | ~~~ | |
172 | ||
173 | As you can see, having a custom argument expression for each field | |
174 | makes tracepoints very flexible for tracing a user space C application. | |
175 | This tracepoint definition is reused later in this guide, when | |
176 | actually using tracepoints in a user space application. |