docs: Add supported versions and fix-backport policy
[lttng-tools.git] / tests / regression / ust / multi-lib / multi-lib-test.c
CommitLineData
3f7f208a 1/*
9d16b343 2 * Copyright (C) 2018 Francis Deslauriers <francis.deslauriers@efficios.com>
3f7f208a 3 *
9d16b343 4 * SPDX-License-Identifier: LGPL-2.1-only
3f7f208a 5 *
3f7f208a
FD
6 */
7
8#include <dlfcn.h>
28f23191 9#include <popt.h>
3f7f208a
FD
10#include <stdio.h>
11#include <stdlib.h>
12#include <unistd.h>
3f7f208a
FD
13
14#if HAS_CALLSITES
15#include "callsites.h"
16#endif
17
b670b304
SM
18void exec_callsite(void);
19void exec_callsite(void)
3f7f208a
FD
20{
21#if HAS_CALLSITES
22 call_tracepoint();
23#endif
24}
25
28f23191 26static void print_list(void)
3f7f208a
FD
27{
28 fprintf(stderr, "Test list (-t X):\n");
28f23191
JG
29 fprintf(stderr,
30 "\t0: dlopen() all libraries pass in arguments and execute "
31 "the callsite.\n");
32 fprintf(stderr,
33 "\t1: simulate the upgrade of a probe provider using dlopen() and dlclose(). \n");
34 fprintf(stderr,
35 "\t2: simulate the upgrade of a library containing the callsites using dlopen() and dlclose(). \n");
3f7f208a
FD
36}
37
f12eb9c1 38#if HAS_CALLSITES
28f23191 39static int dl_open_all(int nb_libraries, char **libraries)
3f7f208a
FD
40{
41 int i, ret = 0;
42 void **handles;
43
44 handles = malloc(nb_libraries * sizeof(void *));
45 if (!handles) {
46 ret = -1;
47 goto error;
48 }
49
50 /* Iterate over the libs to dlopen and save the handles. */
51 for (i = 0; i < nb_libraries; i++) {
52 handles[i] = dlopen(libraries[i], RTLD_NOW);
53 if (!handles[i]) {
54 ret = -1;
55 goto error;
56 }
57 }
58
59 exec_callsite();
60error:
61 free(handles);
62 return ret;
63}
64
65/*
66 * Takes 2 paths to libraries, dlopen() the first, trace, dlopen() the second,
67 * and dlclose the first to simulate the upgrade of a library.
68 */
28f23191 69static int upgrade_lib(int nb_libraries, char **libraries)
3f7f208a
FD
70{
71 int i, ret = 0;
72 void *handles[2];
73
74 if (nb_libraries != 2) {
75 ret = -1;
76 goto error;
77 }
78
79 /* Iterate over the libs to dlopen and save the handles. */
80 for (i = 0; i < nb_libraries; i++) {
81 handles[i] = dlopen(libraries[i], RTLD_NOW);
82 if (!handles[i]) {
83 ret = -1;
84 goto error;
85 }
86
87 exec_callsite();
88 }
89
90 ret = dlclose(handles[0]);
91 if (ret) {
92 goto error;
93 }
94
95 exec_callsite();
96
97error:
98 return ret;
99}
f12eb9c1 100#endif /* HAS_CALLSITES */
3f7f208a 101
f12eb9c1 102#if !HAS_CALLSITES
3f7f208a
FD
103/*
104 * Simulate the upgrade of a library containing a callsite.
105 * Receives two libraries containing callsites for the same tracepoint.
106 */
28f23191 107static int upgrade_callsite(int nb_libraries, char **libraries)
3f7f208a
FD
108{
109 int ret = 0;
110 void *handles[2];
111 void (*fct_ptr[2])(void);
112
113 if (nb_libraries != 2) {
114 ret = -1;
115 goto error;
116 }
117
118 /* Load the probes in the first library. */
119 handles[0] = dlopen(libraries[0], RTLD_NOW);
120 if (!handles[0]) {
121 ret = -1;
122 goto error;
123 }
124
125 /*
126 * Get the pointer to the old function containing the callsite and call it.
127 */
128 fct_ptr[0] = dlsym(handles[0], "call_tracepoint");
129 if (!fct_ptr[0]) {
130 ret = -1;
131 goto error;
132 }
133 fct_ptr[0]();
134
135 /* Load the new callsite library. */
136 handles[1] = dlopen(libraries[1], RTLD_NOW);
137 if (!handles[1]) {
138 ret = -1;
139 goto error;
140 }
141
142 /*
143 * Get the pointer to the new function containing the callsite and call it.
144 */
145 fct_ptr[1] = dlsym(handles[1], "call_tracepoint");
146 if (!fct_ptr[1]) {
147 ret = -1;
148 goto error;
149 }
150 fct_ptr[1]();
151
152 /* Unload the old callsite library. */
153 ret = dlclose(handles[0]);
154 if (ret) {
155 goto error;
156 }
157
158 /* Call the function containing the callsite in the new library. */
159 fct_ptr[1]();
160
161 ret = dlclose(handles[1]);
162 if (ret) {
163 goto error;
164 }
165
166error:
167 return ret;
168}
f12eb9c1 169#endif /* !HAS_CALLSITES */
3f7f208a
FD
170
171int main(int argc, const char **argv)
172{
173 int c, ret = 0, test = -1, nb_libraries = 0;
174 char **libraries = NULL;
175 poptContext optCon;
176 struct poptOption optionsTable[] = {
28f23191
JG
177 { "test", 't', POPT_ARG_INT, &test, 0, "Test to run", NULL },
178 { "list", 'l', 0, 0, 'l', "List of tests (-t X)", NULL },
179 POPT_AUTOHELP{ NULL, 0, 0, NULL, 0, NULL, NULL }
3f7f208a
FD
180 };
181
182 optCon = poptGetContext(NULL, argc, argv, optionsTable, 0);
183 if (argc < 2) {
184 poptPrintUsage(optCon, stderr, 0);
185 ret = -1;
186 goto error;
187 }
188
189 while ((c = poptGetNextOpt(optCon)) >= 0) {
28f23191 190 switch (c) {
3f7f208a
FD
191 case 'l':
192 print_list();
193 goto error;
194 }
195 }
196
197 /*
198 * Populate the libraries array with the arguments passed to the process.
199 */
200 while (poptPeekArg(optCon) != NULL) {
8ac478d0
JG
201 char **realloced_libraries = NULL;
202
3f7f208a 203 nb_libraries++;
8ac478d0
JG
204 realloced_libraries = realloc(libraries, nb_libraries * sizeof(char *));
205 if (!realloced_libraries) {
3f7f208a
FD
206 ret = -1;
207 goto error;
208 }
8ac478d0 209 libraries = realloced_libraries;
3f7f208a
FD
210 libraries[nb_libraries - 1] = (char *) poptGetArg(optCon);
211 }
212
28f23191 213 switch (test) {
3f7f208a
FD
214 case 0:
215#if HAS_CALLSITES
216 ret = dl_open_all(nb_libraries, libraries);
217#else
28f23191
JG
218 fprintf(stderr,
219 "Test not implemented for configuration "
220 "(HAS_CALLSITES=%d)\n",
221 HAS_CALLSITES == 1);
3f7f208a
FD
222#endif
223 break;
224 case 1:
225#if HAS_CALLSITES
226 ret = upgrade_lib(nb_libraries, libraries);
227#else
28f23191
JG
228 fprintf(stderr,
229 "Test not implemented for configuration "
230 "(HAS_CALLSITES=%d)\n",
231 HAS_CALLSITES == 1);
3f7f208a
FD
232#endif
233 break;
234 case 2:
235#if !HAS_CALLSITES
236 ret = upgrade_callsite(nb_libraries, libraries);
237#else
28f23191
JG
238 fprintf(stderr,
239 "Test not implemented for configuration "
240 "(HAS_CALLSITES=%d)\n",
241 HAS_CALLSITES == 1);
3f7f208a
FD
242#endif
243 break;
244 default:
245 fprintf(stderr, "Test %d not implemented\n", test);
246 ret = -1;
247 break;
248 }
249error:
250 free(libraries);
251 poptFreeContext(optCon);
252 return ret;
253}
This page took 0.06002 seconds and 5 git commands to generate.