Fix: tests: add `void` parameter to functions that take no parameters
[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>
9#include <stdio.h>
10#include <stdlib.h>
11#include <unistd.h>
12#include <popt.h>
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
f12eb9c1 26static
3f7f208a
FD
27void print_list(void)
28{
29 fprintf(stderr, "Test list (-t X):\n");
30 fprintf(stderr, "\t0: dlopen() all libraries pass in arguments and execute "
31 "the callsite.\n");
32 fprintf(stderr, "\t1: simulate the upgrade of a probe provider using dlopen() and dlclose(). \n");
33 fprintf(stderr, "\t2: simulate the upgrade of a library containing the callsites using dlopen() and dlclose(). \n");
34}
35
f12eb9c1
SM
36#if HAS_CALLSITES
37static
3f7f208a
FD
38int dl_open_all(int nb_libraries, char **libraries)
39{
40 int i, ret = 0;
41 void **handles;
42
43 handles = malloc(nb_libraries * sizeof(void *));
44 if (!handles) {
45 ret = -1;
46 goto error;
47 }
48
49 /* Iterate over the libs to dlopen and save the handles. */
50 for (i = 0; i < nb_libraries; i++) {
51 handles[i] = dlopen(libraries[i], RTLD_NOW);
52 if (!handles[i]) {
53 ret = -1;
54 goto error;
55 }
56 }
57
58 exec_callsite();
59error:
60 free(handles);
61 return ret;
62}
63
64/*
65 * Takes 2 paths to libraries, dlopen() the first, trace, dlopen() the second,
66 * and dlclose the first to simulate the upgrade of a library.
67 */
f12eb9c1 68static
3f7f208a
FD
69int upgrade_lib(int nb_libraries, char **libraries)
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 */
f12eb9c1 107static
3f7f208a
FD
108int upgrade_callsite(int nb_libraries, char **libraries)
109{
110 int ret = 0;
111 void *handles[2];
112 void (*fct_ptr[2])(void);
113
114 if (nb_libraries != 2) {
115 ret = -1;
116 goto error;
117 }
118
119 /* Load the probes in the first library. */
120 handles[0] = dlopen(libraries[0], RTLD_NOW);
121 if (!handles[0]) {
122 ret = -1;
123 goto error;
124 }
125
126 /*
127 * Get the pointer to the old function containing the callsite and call it.
128 */
129 fct_ptr[0] = dlsym(handles[0], "call_tracepoint");
130 if (!fct_ptr[0]) {
131 ret = -1;
132 goto error;
133 }
134 fct_ptr[0]();
135
136 /* Load the new callsite library. */
137 handles[1] = dlopen(libraries[1], RTLD_NOW);
138 if (!handles[1]) {
139 ret = -1;
140 goto error;
141 }
142
143 /*
144 * Get the pointer to the new function containing the callsite and call it.
145 */
146 fct_ptr[1] = dlsym(handles[1], "call_tracepoint");
147 if (!fct_ptr[1]) {
148 ret = -1;
149 goto error;
150 }
151 fct_ptr[1]();
152
153 /* Unload the old callsite library. */
154 ret = dlclose(handles[0]);
155 if (ret) {
156 goto error;
157 }
158
159 /* Call the function containing the callsite in the new library. */
160 fct_ptr[1]();
161
162 ret = dlclose(handles[1]);
163 if (ret) {
164 goto error;
165 }
166
167error:
168 return ret;
169}
f12eb9c1 170#endif /* !HAS_CALLSITES */
3f7f208a
FD
171
172int main(int argc, const char **argv)
173{
174 int c, ret = 0, test = -1, nb_libraries = 0;
175 char **libraries = NULL;
176 poptContext optCon;
177 struct poptOption optionsTable[] = {
178 { "test", 't', POPT_ARG_INT, &test, 0, "Test to run", NULL },
179 { "list", 'l', 0, 0, 'l', "List of tests (-t X)", NULL },
180 POPT_AUTOHELP
181 { NULL, 0, 0, NULL, 0 }
182 };
183
184 optCon = poptGetContext(NULL, argc, argv, optionsTable, 0);
185 if (argc < 2) {
186 poptPrintUsage(optCon, stderr, 0);
187 ret = -1;
188 goto error;
189 }
190
191 while ((c = poptGetNextOpt(optCon)) >= 0) {
192 switch(c) {
193 case 'l':
194 print_list();
195 goto error;
196 }
197 }
198
199 /*
200 * Populate the libraries array with the arguments passed to the process.
201 */
202 while (poptPeekArg(optCon) != NULL) {
8ac478d0
JG
203 char **realloced_libraries = NULL;
204
3f7f208a 205 nb_libraries++;
8ac478d0
JG
206 realloced_libraries = realloc(libraries, nb_libraries * sizeof(char *));
207 if (!realloced_libraries) {
3f7f208a
FD
208 ret = -1;
209 goto error;
210 }
8ac478d0 211 libraries = realloced_libraries;
3f7f208a
FD
212 libraries[nb_libraries - 1] = (char *) poptGetArg(optCon);
213 }
214
215 switch(test) {
216 case 0:
217#if HAS_CALLSITES
218 ret = dl_open_all(nb_libraries, libraries);
219#else
220 fprintf(stderr, "Test not implemented for configuration "
221 "(HAS_CALLSITES=%d)\n", HAS_CALLSITES == 1);
222#endif
223 break;
224 case 1:
225#if HAS_CALLSITES
226 ret = upgrade_lib(nb_libraries, libraries);
227#else
228 fprintf(stderr, "Test not implemented for configuration "
229 "(HAS_CALLSITES=%d)\n", HAS_CALLSITES == 1);
230#endif
231 break;
232 case 2:
233#if !HAS_CALLSITES
234 ret = upgrade_callsite(nb_libraries, libraries);
235#else
236 fprintf(stderr, "Test not implemented for configuration "
237 "(HAS_CALLSITES=%d)\n", HAS_CALLSITES == 1);
238#endif
239 break;
240 default:
241 fprintf(stderr, "Test %d not implemented\n", test);
242 ret = -1;
243 break;
244 }
245error:
246 free(libraries);
247 poptFreeContext(optCon);
248 return ret;
249}
This page took 0.0547 seconds and 4 git commands to generate.