Clarify TRACEPOINT_DEFINE and multi TP
[lttng-docs.git] / contents / using-lttng / instrumenting / c-application / tracepoint-provider.md
1 ---
2 id: tracepoint-provider
3 ---
4
5 Before jumping into defining tracepoints and inserting
6 them into the application source code, you must understand what a
7 _tracepoint provider_ is.
8
9 For the sake of this guide, consider the following two files:
10
11 `tp.h`:
12
13 ~~~ c
14 #undef TRACEPOINT_PROVIDER
15 #define TRACEPOINT_PROVIDER my_provider
16
17 #undef TRACEPOINT_INCLUDE
18 #define TRACEPOINT_INCLUDE "./tp.h"
19
20 #if !defined(_TP_H) || defined(TRACEPOINT_HEADER_MULTI_READ)
21 #define _TP_H
22
23 #include <lttng/tracepoint.h>
24
25 TRACEPOINT_EVENT(
26 my_provider,
27 my_first_tracepoint,
28 TP_ARGS(
29 int, my_integer_arg,
30 char*, my_string_arg
31 ),
32 TP_FIELDS(
33 ctf_string(my_string_field, my_string_arg)
34 ctf_integer(int, my_integer_field, my_integer_arg)
35 )
36 )
37
38 TRACEPOINT_EVENT(
39 my_provider,
40 my_other_tracepoint,
41 TP_ARGS(
42 int, my_int
43 ),
44 TP_FIELDS(
45 ctf_integer(int, some_field, my_int)
46 )
47 )
48
49 #endif /* _TP_H */
50
51 #include <lttng/tracepoint-event.h>
52 ~~~
53
54 `tp.c`:
55
56 ~~~ c
57 #define TRACEPOINT_CREATE_PROBES
58
59 #include "tp.h"
60 ~~~
61
62 The two files above are defining a _tracepoint provider_. A tracepoint
63 provider is some sort of namespace for _tracepoint definitions_. Tracepoint
64 definitions are written above with the `TRACEPOINT_EVENT()` macro, and allow
65 eventual `tracepoint()` calls respecting their definitions to be inserted
66 into the user application's C source code (we explore this in a
67 later section).
68
69 Many tracepoint definitions may be part of the same tracepoint provider
70 and many tracepoint providers may coexist in a user space application. A
71 tracepoint provider is packaged either:
72
73 * directly into an existing user application's C source file
74 * as an object file
75 * as a static library
76 * as a shared library
77
78 The two files above, `tp.h` and `tp.c`, show a typical template for
79 writing a tracepoint provider. LTTng-UST was designed so that two
80 tracepoint providers should not be defined in the same header file.
81
82 We will now go through the various parts of the above files and
83 give them a meaning. As you may have noticed, the LTTng-UST API for
84 C/C++ applications is some preprocessor sorcery. The LTTng-UST macros
85 used in your application and those in the LTTng-UST headers are
86 combined to produce actual source code needed to make tracing possible
87 using LTTng.
88
89 Let's start with the header file, `tp.h`. It begins with
90
91 ~~~ c
92 #undef TRACEPOINT_PROVIDER
93 #define TRACEPOINT_PROVIDER my_provider
94 ~~~
95
96 `TRACEPOINT_PROVIDER` defines the name of the provider to which the
97 following tracepoint definitions will belong. It is used internally by
98 LTTng-UST headers and _must_ be defined. Since `TRACEPOINT_PROVIDER`
99 could have been defined by another header file also included by the same
100 C source file, the best practice is to undefine it first.
101
102 <div class="tip">
103 <p><span class="t">Note:</span>Names in LTTng-UST follow the C
104 <em>identifier</em> syntax (starting with a letter and containing either
105 letters, numbers or underscores); they are <em>not</em> C strings
106 (not surrounded by double quotes). This is because LTTng-UST macros
107 use those identifier-like strings to create symbols (named types and
108 variables).</p>
109 </div>
110
111 The tracepoint provider is a group of tracepoint definitions; its chosen
112 name should reflect this. A hierarchy like Java packages is recommended,
113 using underscores instead of dots, e.g., `org_company_project_component`.
114
115 Next is `TRACEPOINT_INCLUDE`:
116
117 ~~~ c
118 #undef TRACEPOINT_INCLUDE
119 #define TRACEPOINT_INCLUDE "./tp.h"
120 ~~~
121
122 This little bit of instrospection is needed by LTTng-UST to include
123 your header at various predefined places.
124
125 Include guard follows:
126
127 ~~~ c
128 #if !defined(_TP_H) || defined(TRACEPOINT_HEADER_MULTI_READ)
129 #define _TP_H
130 ~~~
131
132 Add these precompiler conditionals to ensure the tracepoint event
133 generation can include this file more than once.
134
135 The `TRACEPOINT_EVENT()` macro is defined in a LTTng-UST header file which
136 must be included:
137
138 ~~~ c
139 #include <lttng/tracepoint.h>
140 ~~~
141
142 This will also allow the application to use the `tracepoint()` macro.
143
144 Next is a list of `TRACEPOINT_EVENT()` macro calls which create the
145 actual tracepoint definitions. We will skip this for the moment and
146 come back to how to use `TRACEPOINT_EVENT()`
147 [in a later section](#doc-defining-tracepoints). Just pay attention to
148 the first argument: it's always the name of the tracepoint provider
149 being defined in this header file.
150
151 End of include guard:
152
153 ~~~ c
154 #endif /* _TP_H */
155 ~~~
156
157 Finally, include `<lttng/tracepoint-event.h>` to expand the macros:
158
159 ~~~ c
160 #include <lttng/tracepoint-event.h>
161 ~~~
162
163 That's it for `tp.h`. Of course, this is only a header file; it must be
164 included in some C source file to actually use it. This is the job of
165 `tp.c`:
166
167 ~~~ c
168 #define TRACEPOINT_CREATE_PROBES
169
170 #include "tp.h"
171 ~~~
172
173 When `TRACEPOINT_CREATE_PROBES` is defined, the macros used in `tp.h`,
174 which is included just after, will actually create the source code for
175 LTTng-UST probes (global data structures and functions) out of your
176 tracepoint definitions. How exactly this is done is out of this text's scope.
177 `TRACEPOINT_CREATE_PROBES` is discussed further
178 in [Building/linking tracepoint providers and the user application](#doc-building-tracepoint-providers-and-user-application).
179
180 You could include other header files like `tp.h` here to create the probes
181 of different tracepoint providers, e.g.:
182
183 ~~~ c
184 #define TRACEPOINT_CREATE_PROBES
185
186 #include "tp1.h"
187 #include "tp2.h"
188 ~~~
189
190 The rule is: probes of a given tracepoint provider
191 must be created in exactly one source file. This source file could be one
192 of your project's; it doesn't have to be on its own like `tp.c`, although
193 [a later section](#doc-building-tracepoint-providers-and-user-application)
194 shows that doing so allows packaging the tracepoint providers
195 independently and keep them out of your application, also making it
196 possible to reuse them between projects.
197
198 The following sections explain how to define tracepoints, how to use the
199 `tracepoint()` macro to instrument your user space C application and how
200 to build/link tracepoint providers and your application with LTTng-UST
201 support.
This page took 0.038721 seconds and 5 git commands to generate.