Commit | Line | Data |
---|---|---|
5e0cbfb0 PP |
1 | --- |
2 | id: dynamic-linking | |
3 | --- | |
4 | ||
5 | The second approach to package the tracepoint providers is to use | |
6 | dynamic linking: the library and its member functions are explicitly | |
7 | sought, loaded and unloaded at runtime using `libdl`. | |
8 | ||
9 | It has to be noted that, for a variety of reasons, the created shared | |
47bfcb75 | 10 | library is be dynamically _loaded_, as opposed to dynamically |
5e0cbfb0 PP |
11 | _linked_. The tracepoint provider shared object is, however, linked |
12 | with `liblttng-ust`, so that `liblttng-ust` is guaranteed to be loaded | |
13 | as soon as the tracepoint provider is. If the tracepoint provider is | |
14 | not loaded, since the application itself is not linked with | |
15 | `liblttng-ust`, the latter is not loaded at all and the tracepoint calls | |
16 | become inert. | |
17 | ||
18 | The process to create the tracepoint provider shared object is pretty | |
19 | much the same as the static library method, except that: | |
20 | ||
21 | * since the tracepoint provider is not part of the application | |
cd41f97c PP |
22 | anymore, `TRACEPOINT_DEFINE` _must_ be defined, for each tracepoint |
23 | provider, in exactly one translation unit (C source file) of the | |
24 | _application_; | |
5e0cbfb0 PP |
25 | * `TRACEPOINT_PROBE_DYNAMIC_LINKAGE` must be defined next to |
26 | `TRACEPOINT_DEFINE`. | |
27 | ||
cd41f97c PP |
28 | Regarding `TRACEPOINT_DEFINE` and `TRACEPOINT_PROBE_DYNAMIC_LINKAGE`, |
29 | the recommended practice is to use a separate C source file in your | |
30 | application to define them, and then include the tracepoint provider | |
31 | header files afterwards, e.g.: | |
32 | ||
33 | ~~~ c | |
34 | #define TRACEPOINT_DEFINE | |
35 | #define TRACEPOINT_PROBE_DYNAMIC_LINKAGE | |
36 | ||
37 | /* include the header files of one or more tracepoint providers below */ | |
38 | #include "tp1.h" | |
39 | #include "tp2.h" | |
40 | #include "tp3.h" | |
41 | ~~~ | |
42 | ||
5e0cbfb0 PP |
43 | `TRACEPOINT_PROBE_DYNAMIC_LINKAGE` makes the macros included afterwards |
44 | (by including the tracepoint provider header, which itself includes | |
45 | LTTng-UST headers) aware that the tracepoint provider is to be loaded | |
46 | dynamically and not part of the application's executable. | |
47 | ||
48 | The tracepoint provider object file used to create the shared library | |
49 | is built like it is using the static library method, only with the | |
50 | `-fpic` option added: | |
51 | ||
52 | <pre class="term"> | |
53 | gcc -c <strong>-fpic</strong> -I. tp.c | |
54 | </pre> | |
55 | ||
56 | It is then linked as a shared library like this: | |
57 | ||
58 | <pre class="term"> | |
59 | gcc <strong>-shared -Wl,--no-as-needed -o tp.so -llttng-ust</strong> tp.o | |
60 | </pre> | |
61 | ||
62 | As previously stated, this tracepoint provider shared object isn't | |
47bfcb75 | 63 | linked with the user application: it's loaded manually. This is |
5e0cbfb0 PP |
64 | why the application is built with no mention of this tracepoint |
65 | provider, but still needs `libdl`: | |
66 | ||
67 | <pre class="term"> | |
68 | gcc -o app other.o files.o of.o your.o app.o <strong>-ldl</strong> | |
69 | </pre> | |
70 | ||
382d32dd PP |
71 | Now, to make LTTng-UST tracing available to the application, the |
72 | `LD_PRELOAD` environment variable is used to preload the tracepoint | |
73 | provider shared library _before_ the application actually starts: | |
5e0cbfb0 PP |
74 | |
75 | <pre class="term"> | |
76 | <strong>LD_PRELOAD=/path/to/tp.so</strong> ./app | |
77 | </pre> | |
78 | ||
382d32dd PP |
79 | <div class="tip"> |
80 | <p> | |
81 | <span class="t">Note:</span>It is not safe to use | |
82 | <code>dlclose()</code> on a tracepoint provider shared object that | |
83 | is being actively used for tracing, due to a lack of reference | |
84 | counting from LTTng-UST to the shared object. | |
85 | </p> | |
86 | ||
87 | <p> | |
88 | For example, statically linking a tracepoint provider to a | |
89 | shared object which is to be dynamically loaded by an application | |
90 | (e.g., a plugin) is not safe: the shared object, which contains the | |
91 | tracepoint provider, could be dynamically closed | |
92 | (<code>dlclose()</code>) at any time by the application. | |
93 | </p> | |
94 | ||
95 | <p> | |
96 | To instrument a shared object, either: | |
97 | </p> | |
98 | ||
99 | <ol> | |
100 | <li> | |
101 | Statically link the tracepoint provider to the | |
102 | <em>application</em>, or | |
103 | </li> | |
104 | <li> | |
105 | Build the tracepoint provider as a shared object (following | |
106 | the procedure shown in this section), and preload it when | |
107 | tracing is needed using the <code>LD_PRELOAD</code> | |
108 | environment variable. | |
109 | </li> | |
110 | </ol> | |
111 | </div> | |
112 | ||
0cc03080 | 113 | Your application will still work without this preloading, albeit without |
5e0cbfb0 PP |
114 | LTTng-UST tracing support: |
115 | ||
116 | <pre class="term"> | |
117 | ./app | |
118 | </pre> | |
cd41f97c | 119 |