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