instrumenting-linux-kernel-itself: document LTTNG_TRACEPOINT_EVENT_CODE()
[lttng-docs.git] / contents / using-lttng / instrumenting / instrumenting-linux-kernel / instrumenting-linux-kernel-itself / lttng-adaptation-layer.md
1 ---
2 id: lttng-adaptation-layer
3 ---
4
5 The steps to write the LTTng adaptation layer are, in your
6 LTTng-modules copy's source code tree:
7
8 1. In `instrumentation/events/lttng-module`,
9 add a header <code><em>subsys</em>.h</code> for your custom
10 subsystem <code><em>subsys</em></code> and write your
11 tracepoint definitions using LTTng-modules macros in it.
12 Those macros look like the mainline kernel equivalents,
13 but they present subtle, yet important differences.
14 2. In `probes`, create the C source file of the LTTng probe kernel
15 module for your subsystem. It should be named
16 <code>lttng-probe-<em>subsys</em>.c</code>.
17 3. Edit `probes/Makefile` so that the LTTng-modules project
18 builds your custom LTTng probe kernel module.
19 4. Build and install LTTng kernel modules.
20
21 Following our `hello_world` event example, here's the content of
22 `instrumentation/events/lttng-module/hello.h`:
23
24 ~~~ c
25 #undef TRACE_SYSTEM
26 #define TRACE_SYSTEM hello
27
28 #if !defined(_TRACE_HELLO_H) || defined(TRACE_HEADER_MULTI_READ)
29 #define _TRACE_HELLO_H
30
31 #include "../../../probes/lttng-tracepoint-event.h"
32 #include <linux/tracepoint.h>
33
34 LTTNG_TRACEPOINT_EVENT(
35 /* format identical to mainline version for those */
36 hello_world,
37 TP_PROTO(int foo, const char* bar),
38 TP_ARGS(foo, bar),
39
40 /* possible differences */
41 TP_STRUCT__entry(
42 __field(int, my_int)
43 __field(char, char0)
44 __field(char, char1)
45 __string(product, bar)
46 ),
47
48 /* notice the use of tp_assign()/tp_strcpy() and no semicolons */
49 TP_fast_assign(
50 tp_assign(my_int, foo)
51 tp_assign(char0, bar[0])
52 tp_assign(char1, bar[1])
53 tp_strcpy(product, bar)
54 ),
55
56 /* This one is actually not used by LTTng either, but must be
57 * present for the moment.
58 */
59 TP_printk("", 0)
60
61 /* no semicolon after this either */
62 )
63
64 #endif
65
66 /* other difference: do NOT include <trace/define_trace.h> */
67 #include "../../../probes/define_trace.h"
68 ~~~
69
70 Some possible entries for `TP_STRUCT__entry()` and `TP_fast_assign()`,
71 in the case of LTTng-modules, are shown in the
72 [LTTng-modules reference](#doc-lttng-modules-ref) section.
73
74 You may also be interested in using the
75 [`LTTNG_TRACEPOINT_EVENT_CODE()` macro](#doc-lttng-tracepoint-event-code),
76 instead of using `LTTNG_TRACEPOINT_EVENT()`, which allows custom local
77 variables and C code to be executed before the event fields are recorded.
78
79 The best way to learn how to use the above macros is to inspect
80 existing LTTng tracepoint definitions in `instrumentation/events/lttng-module`
81 header files. Compare them with the Linux kernel mainline versions
82 in `include/trace/events`.
83
84 The next step is writing the LTTng probe kernel module C source file.
85 This one is named <code>lttng-probe-<em>subsys</em>.c</code>
86 in `probes`. You may always use the following template:
87
88 ~~~ c
89 #include <linux/module.h>
90 #include "../lttng-tracer.h"
91
92 /* Build time verification of mismatch between mainline TRACE_EVENT()
93 * arguments and LTTng adaptation layer LTTNG_TRACEPOINT_EVENT() arguments.
94 */
95 #include <trace/events/hello.h>
96
97 /* create LTTng tracepoint probes */
98 #define LTTNG_PACKAGE_BUILD
99 #define CREATE_TRACE_POINTS
100 #define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module
101
102 #include "../instrumentation/events/lttng-module/hello.h"
103
104 MODULE_LICENSE("GPL and additional rights");
105 MODULE_AUTHOR("Your name <your-email>");
106 MODULE_DESCRIPTION("LTTng hello probes");
107 MODULE_VERSION(__stringify(LTTNG_MODULES_MAJOR_VERSION) "."
108 __stringify(LTTNG_MODULES_MINOR_VERSION) "."
109 __stringify(LTTNG_MODULES_PATCHLEVEL_VERSION)
110 LTTNG_MODULES_EXTRAVERSION);
111 ~~~
112
113 Just replace `hello` with your subsystem name. In this example,
114 `<trace/events/hello.h>`, which is the original mainline tracepoint
115 definition header, is included for verification purposes: the
116 LTTng-modules build system is able to emit an error at build time when
117 the arguments of the mainline `TRACE_EVENT()` definitions do not match
118 the ones of the LTTng-modules adaptation layer
119 (`LTTNG_TRACEPOINT_EVENT()`).
120
121 Edit `probes/Makefile` and add your new kernel module object
122 next to existing ones:
123
124 ~~~ makefile
125 # ...
126
127 obj-m += lttng-probe-module.o
128 obj-m += lttng-probe-power.o
129
130 obj-m += lttng-probe-hello.o
131
132 # ...
133 ~~~
134
135 Time to build! Point to your custom Linux kernel source tree using
136 the `KERNELDIR` variable:
137
138 <pre class="term">
139 make <strong>KERNELDIR=/path/to/custom/linux</strong>
140 </pre>
141
142 Finally, install modules:
143
144 <pre class="term">
145 sudo make modules_install
146 </pre>
This page took 0.032944 seconds and 4 git commands to generate.