Commit | Line | Data |
---|---|---|
5e0cbfb0 PP |
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 | ||
41aea258 | 31 | #include "../../../probes/lttng-tracepoint-event.h" |
5e0cbfb0 PP |
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 | ||
d154e24c PP |
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 | ||
5e0cbfb0 PP |
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> |