dlopen() liblttng-ust.so from constructor to prevent unloading
[lttng-ust.git] / tests / test-app-ctx / hello.c
1 /*
2 * Copyright (C) 2009 Pierre-Marc Fournier
3 * Copyright (C) 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; version 2.1 of
8 * the License.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #include <stdio.h>
21 #include <unistd.h>
22 #include <sys/mman.h>
23 #include <stdarg.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <fcntl.h>
27 #include <signal.h>
28 #include <string.h>
29 /*
30 * Work-around inet.h missing struct mmsghdr forward declaration, with
31 * triggers a warning when system files warnings are enabled.
32 */
33 struct mmsghdr;
34 #include <arpa/inet.h>
35 #include <stdlib.h>
36 #include <stdbool.h>
37
38 #define TRACEPOINT_DEFINE
39 #include "ust_tests_hello.h"
40
41 /* Internal header. */
42 #include <lttng/ust-events.h>
43 #include <lttng/ringbuffer-config.h>
44 #include <lttng/ust-context-provider.h>
45
46 static __thread unsigned int test_count;
47
48 void test_inc_count(void)
49 {
50 test_count++;
51 }
52
53 static
54 size_t test_get_size(struct lttng_ctx_field *field, size_t offset)
55 {
56 int sel = test_count % _NR_LTTNG_UST_DYNAMIC_TYPES;
57 size_t size = 0;
58
59 size += lib_ring_buffer_align(offset, lttng_alignof(char));
60 size += sizeof(char); /* tag */
61 switch (sel) {
62 case LTTNG_UST_DYNAMIC_TYPE_NONE:
63 break;
64 case LTTNG_UST_DYNAMIC_TYPE_S8:
65 size += lib_ring_buffer_align(offset, lttng_alignof(int8_t));
66 size += sizeof(int8_t); /* variant */
67 break;
68 case LTTNG_UST_DYNAMIC_TYPE_S16:
69 size += lib_ring_buffer_align(offset, lttng_alignof(int16_t));
70 size += sizeof(int16_t); /* variant */
71 break;
72 case LTTNG_UST_DYNAMIC_TYPE_S32:
73 size += lib_ring_buffer_align(offset, lttng_alignof(int32_t));
74 size += sizeof(int32_t); /* variant */
75 break;
76 case LTTNG_UST_DYNAMIC_TYPE_S64:
77 size += lib_ring_buffer_align(offset, lttng_alignof(int64_t));
78 size += sizeof(int64_t); /* variant */
79 break;
80 case LTTNG_UST_DYNAMIC_TYPE_U8:
81 size += lib_ring_buffer_align(offset, lttng_alignof(uint8_t));
82 size += sizeof(uint8_t); /* variant */
83 break;
84 case LTTNG_UST_DYNAMIC_TYPE_U16:
85 size += lib_ring_buffer_align(offset, lttng_alignof(uint16_t));
86 size += sizeof(uint16_t); /* variant */
87 break;
88 case LTTNG_UST_DYNAMIC_TYPE_U32:
89 size += lib_ring_buffer_align(offset, lttng_alignof(uint32_t));
90 size += sizeof(uint32_t); /* variant */
91 break;
92 case LTTNG_UST_DYNAMIC_TYPE_U64:
93 size += lib_ring_buffer_align(offset, lttng_alignof(uint64_t));
94 size += sizeof(uint64_t); /* variant */
95 break;
96 case LTTNG_UST_DYNAMIC_TYPE_FLOAT:
97 size += lib_ring_buffer_align(offset, lttng_alignof(float));
98 size += sizeof(float); /* variant */
99 break;
100 case LTTNG_UST_DYNAMIC_TYPE_DOUBLE:
101 size += lib_ring_buffer_align(offset, lttng_alignof(double));
102 size += sizeof(double); /* variant */
103 break;
104 case LTTNG_UST_DYNAMIC_TYPE_STRING:
105 size += strlen("teststr") + 1;
106 break;
107 default:
108 abort();
109 }
110
111 return size;
112 }
113
114 static
115 void test_record(struct lttng_ctx_field *field,
116 struct lttng_ust_lib_ring_buffer_ctx *ctx,
117 struct lttng_channel *chan)
118 {
119 int sel = test_count % _NR_LTTNG_UST_DYNAMIC_TYPES;
120 char sel_char = (char) sel;
121
122 lib_ring_buffer_align_ctx(ctx, lttng_alignof(char));
123 chan->ops->event_write(ctx, &sel_char, sizeof(sel_char));
124 switch (sel) {
125 case LTTNG_UST_DYNAMIC_TYPE_NONE:
126 break;
127 case LTTNG_UST_DYNAMIC_TYPE_S8:
128 {
129 int8_t v = -8;
130
131 lib_ring_buffer_align_ctx(ctx, lttng_alignof(v));
132 chan->ops->event_write(ctx, &v, sizeof(v));
133 break;
134 }
135 case LTTNG_UST_DYNAMIC_TYPE_S16:
136 {
137 int16_t v = -16;
138
139 lib_ring_buffer_align_ctx(ctx, lttng_alignof(v));
140 chan->ops->event_write(ctx, &v, sizeof(v));
141 break;
142 }
143 case LTTNG_UST_DYNAMIC_TYPE_S32:
144 {
145 int32_t v = -32;
146
147 lib_ring_buffer_align_ctx(ctx, lttng_alignof(v));
148 chan->ops->event_write(ctx, &v, sizeof(v));
149 break;
150 }
151 case LTTNG_UST_DYNAMIC_TYPE_S64:
152 {
153 int64_t v = -64;
154
155 lib_ring_buffer_align_ctx(ctx, lttng_alignof(v));
156 chan->ops->event_write(ctx, &v, sizeof(v));
157 break;
158 }
159 case LTTNG_UST_DYNAMIC_TYPE_U8:
160 {
161 uint8_t v = 8;
162
163 lib_ring_buffer_align_ctx(ctx, lttng_alignof(v));
164 chan->ops->event_write(ctx, &v, sizeof(v));
165 break;
166 }
167 case LTTNG_UST_DYNAMIC_TYPE_U16:
168 {
169 uint16_t v = 16;
170
171 lib_ring_buffer_align_ctx(ctx, lttng_alignof(v));
172 chan->ops->event_write(ctx, &v, sizeof(v));
173 break;
174 }
175 case LTTNG_UST_DYNAMIC_TYPE_U32:
176 {
177 uint32_t v = 32;
178
179 lib_ring_buffer_align_ctx(ctx, lttng_alignof(v));
180 chan->ops->event_write(ctx, &v, sizeof(v));
181 break;
182 }
183 case LTTNG_UST_DYNAMIC_TYPE_U64:
184 {
185 uint64_t v = 64;
186
187 lib_ring_buffer_align_ctx(ctx, lttng_alignof(v));
188 chan->ops->event_write(ctx, &v, sizeof(v));
189 break;
190 }
191 case LTTNG_UST_DYNAMIC_TYPE_FLOAT:
192 {
193 float f = 22322.0;
194
195 lib_ring_buffer_align_ctx(ctx, lttng_alignof(f));
196 chan->ops->event_write(ctx, &f, sizeof(f));
197 break;
198 }
199 case LTTNG_UST_DYNAMIC_TYPE_DOUBLE:
200 {
201 double d = 2.0;
202
203 lib_ring_buffer_align_ctx(ctx, lttng_alignof(d));
204 chan->ops->event_write(ctx, &d, sizeof(d));
205 break;
206 }
207 case LTTNG_UST_DYNAMIC_TYPE_STRING:
208 {
209 const char *str = "teststr";
210 chan->ops->event_write(ctx, str, strlen(str) + 1);
211 break;
212 }
213 default:
214 abort();
215 }
216 }
217
218 static
219 void test_get_value(struct lttng_ctx_field *field,
220 struct lttng_ctx_value *value)
221 {
222 int sel = test_count % _NR_LTTNG_UST_DYNAMIC_TYPES;
223
224 value->sel = sel;
225 switch (sel) {
226 case LTTNG_UST_DYNAMIC_TYPE_NONE:
227 break;
228 case LTTNG_UST_DYNAMIC_TYPE_S8:
229 value->u.s64 = -8;
230 break;
231 case LTTNG_UST_DYNAMIC_TYPE_S16:
232 value->u.s64 = -16;
233 break;
234 case LTTNG_UST_DYNAMIC_TYPE_S32:
235 value->u.s64 = -32;
236 break;
237 case LTTNG_UST_DYNAMIC_TYPE_S64:
238 value->u.s64 = -64;
239 break;
240 case LTTNG_UST_DYNAMIC_TYPE_U8:
241 value->u.s64 = 8;
242 break;
243 case LTTNG_UST_DYNAMIC_TYPE_U16:
244 value->u.s64 = 16;
245 break;
246 case LTTNG_UST_DYNAMIC_TYPE_U32:
247 value->u.s64 = 32;
248 break;
249 case LTTNG_UST_DYNAMIC_TYPE_U64:
250 value->u.s64 = 64;
251 break;
252 case LTTNG_UST_DYNAMIC_TYPE_FLOAT:
253 value->u.d = 22322.0;
254 break;
255 case LTTNG_UST_DYNAMIC_TYPE_DOUBLE:
256 value->u.d = 2.0;
257 break;
258 case LTTNG_UST_DYNAMIC_TYPE_STRING:
259 value->u.str = "teststr";
260 break;
261 default:
262 abort();
263 }
264 }
265
266 struct lttng_ust_context_provider myprovider = {
267 .name = "$app.myprovider",
268 .get_size = test_get_size,
269 .record = test_record,
270 .get_value = test_get_value,
271 };
272
273 void inthandler(int sig)
274 {
275 printf("in SIGUSR1 handler\n");
276 tracepoint(ust_tests_hello, tptest_sighandler);
277 }
278
279 int init_int_handler(void)
280 {
281 int result;
282 struct sigaction act;
283
284 memset(&act, 0, sizeof(act));
285 result = sigemptyset(&act.sa_mask);
286 if (result == -1) {
287 perror("sigemptyset");
288 return -1;
289 }
290
291 act.sa_handler = inthandler;
292 act.sa_flags = SA_RESTART;
293
294 /* Only defer ourselves. Also, try to restart interrupted
295 * syscalls to disturb the traced program as little as possible.
296 */
297 result = sigaction(SIGUSR1, &act, NULL);
298 if (result == -1) {
299 perror("sigaction");
300 return -1;
301 }
302
303 return 0;
304 }
305
306 void test_inc_count(void);
307
308 int main(int argc, char **argv)
309 {
310 int i, netint;
311 long values[] = { 1, 2, 3 };
312 char text[10] = "test";
313 double dbl = 2.0;
314 float flt = 2222.0;
315 int delay = 0;
316 bool mybool = 123; /* should print "1" */
317
318 init_int_handler();
319
320 if (argc == 2)
321 delay = atoi(argv[1]);
322
323 if (lttng_ust_context_provider_register(&myprovider))
324 abort();
325
326 fprintf(stderr, "Hello, World!\n");
327
328 sleep(delay);
329
330 fprintf(stderr, "Tracing... ");
331 for (i = 0; i < 1000000; i++) {
332 netint = htonl(i);
333 tracepoint(ust_tests_hello, tptest, i, netint, values,
334 text, strlen(text), dbl, flt, mybool);
335 test_inc_count();
336 //usleep(100000);
337 }
338 lttng_ust_context_provider_unregister(&myprovider);
339 fprintf(stderr, " done.\n");
340 return 0;
341 }
This page took 0.038959 seconds and 4 git commands to generate.