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 | |
10 | library will be dynamically _loaded_, as opposed to dynamically | |
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 | |
63 | linked with the user application: it will be loaded manually. This is | |
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 | ||
71 | Now, to make LTTng-UST tracing available to the application, | |
72 | the `LD_PRELOAD` environment variable is used to preload the | |
73 | tracepoint provider shared library _before_ the application actually | |
74 | starts: | |
75 | ||
76 | <pre class="term"> | |
77 | <strong>LD_PRELOAD=/path/to/tp.so</strong> ./app | |
78 | </pre> | |
79 | ||
0cc03080 | 80 | Your application will still work without this preloading, albeit without |
5e0cbfb0 PP |
81 | LTTng-UST tracing support: |
82 | ||
83 | <pre class="term"> | |
84 | ./app | |
85 | </pre> | |
cd41f97c | 86 |