00fcc740101b5f443d77fba5b8596f3053643302
[lttng-ust.git] / liblttng-ust / tracepoint.c
1 /*
2 * SPDX-License-Identifier: LGPL-2.1-only
3 *
4 * Copyright (C) 2008-2011 Mathieu Desnoyers
5 * Copyright (C) 2009 Pierre-Marc Fournier
6 *
7 * Ported to userspace by Pierre-Marc Fournier.
8 */
9
10 #define _LGPL_SOURCE
11 #include <errno.h>
12 #include <stdint.h>
13 #include <stddef.h>
14 #include <stdio.h>
15
16 #include <urcu/arch.h>
17 #include <lttng/urcu/urcu-ust.h>
18 #include <urcu/hlist.h>
19 #include <urcu/uatomic.h>
20 #include <urcu/compiler.h>
21 #include <urcu/system.h>
22
23 #include <lttng/tracepoint.h>
24 #include <lttng/ust-abi.h> /* for LTTNG_UST_ABI_SYM_NAME_LEN */
25
26 #include <usterr-signal-safe.h>
27 #include <ust-helper.h>
28
29 #include "tracepoint-internal.h"
30 #include "lttng-tracer-core.h"
31 #include "jhash.h"
32 #include "error.h"
33
34 /* Test compiler support for weak symbols with hidden visibility. */
35 int __tracepoint_test_symbol1 __attribute__((weak, visibility("hidden")));
36 void *__tracepoint_test_symbol2 __attribute__((weak, visibility("hidden")));
37 struct {
38 char a[24];
39 } __tracepoint_test_symbol3 __attribute__((weak, visibility("hidden")));
40
41 /* Set to 1 to enable tracepoint debug output */
42 static const int tracepoint_debug;
43 static int initialized;
44
45 /*
46 * If tracepoint_destructors_state = 1, tracepoint destructors are
47 * enabled. They are disabled otherwise.
48 */
49 static int tracepoint_destructors_state = 1;
50
51 static void (*new_tracepoint_cb)(struct lttng_ust_tracepoint *);
52
53 /*
54 * tracepoint_mutex nests inside UST mutex.
55 *
56 * Note about interaction with fork/clone: UST does not hold the
57 * tracepoint mutex across fork/clone because it is either:
58 * - nested within UST mutex, in which case holding the UST mutex across
59 * fork/clone suffice,
60 * - taken by a library constructor, which should never race with a
61 * fork/clone if the application is expected to continue running with
62 * the same memory layout (no following exec()).
63 */
64 static pthread_mutex_t tracepoint_mutex = PTHREAD_MUTEX_INITIALIZER;
65
66 /*
67 * libraries that contain tracepoints (struct tracepoint_lib).
68 * Protected by tracepoint mutex.
69 */
70 static CDS_LIST_HEAD(libs);
71
72 /*
73 * The tracepoint mutex protects the library tracepoints, the hash table, and
74 * the library list.
75 * All calls to the tracepoint API must be protected by the tracepoint mutex,
76 * excepts calls to tracepoint_register_lib and
77 * tracepoint_unregister_lib, which take the tracepoint mutex themselves.
78 */
79
80 /*
81 * Tracepoint hash table, containing the active tracepoints.
82 * Protected by tracepoint mutex.
83 */
84 #define TRACEPOINT_HASH_BITS 12
85 #define TRACEPOINT_TABLE_SIZE (1 << TRACEPOINT_HASH_BITS)
86 static struct cds_hlist_head tracepoint_table[TRACEPOINT_TABLE_SIZE];
87
88 static CDS_LIST_HEAD(old_probes);
89 static int need_update;
90
91 static CDS_LIST_HEAD(release_queue);
92 static int release_queue_need_update;
93
94 /*
95 * Note about RCU :
96 * It is used to to delay the free of multiple probes array until a quiescent
97 * state is reached.
98 * Tracepoint entries modifications are protected by the tracepoint mutex.
99 */
100 struct tracepoint_entry {
101 struct cds_hlist_node hlist;
102 struct lttng_ust_tracepoint_probe *probes;
103 int refcount; /* Number of times armed. 0 if disarmed. */
104 int callsite_refcount; /* how many libs use this tracepoint */
105 char *signature;
106 char *name;
107 };
108
109 struct tp_probes {
110 union {
111 struct cds_list_head list;
112 /* Field below only used for call_rcu scheme */
113 /* struct rcu_head head; */
114 } u;
115 struct lttng_ust_tracepoint_probe probes[0];
116 };
117
118 /*
119 * Callsite hash table, containing the tracepoint call sites.
120 * Protected by tracepoint mutex.
121 */
122 #define CALLSITE_HASH_BITS 12
123 #define CALLSITE_TABLE_SIZE (1 << CALLSITE_HASH_BITS)
124 static struct cds_hlist_head callsite_table[CALLSITE_TABLE_SIZE];
125
126 struct callsite_entry {
127 struct cds_hlist_node hlist; /* hash table node */
128 struct cds_list_head node; /* lib list of callsites node */
129 struct lttng_ust_tracepoint *tp;
130 bool tp_entry_callsite_ref; /* Has a tp_entry took a ref on this callsite */
131 };
132
133 /* coverity[+alloc] */
134 static void *allocate_probes(int count)
135 {
136 struct tp_probes *p =
137 zmalloc(count * sizeof(struct lttng_ust_tracepoint_probe)
138 + sizeof(struct tp_probes));
139 return p == NULL ? NULL : p->probes;
140 }
141
142 /* coverity[+free : arg-0] */
143 static void release_probes(void *old)
144 {
145 if (old) {
146 struct tp_probes *tp_probes = caa_container_of(old,
147 struct tp_probes, probes[0]);
148 lttng_ust_urcu_synchronize_rcu();
149 free(tp_probes);
150 }
151 }
152
153 static void debug_print_probes(struct tracepoint_entry *entry)
154 {
155 int i;
156
157 if (!tracepoint_debug || !entry->probes)
158 return;
159
160 for (i = 0; entry->probes[i].func; i++)
161 DBG("Probe %d : %p", i, entry->probes[i].func);
162 }
163
164 static void *
165 tracepoint_entry_add_probe(struct tracepoint_entry *entry,
166 void (*probe)(void), void *data)
167 {
168 int nr_probes = 0;
169 struct lttng_ust_tracepoint_probe *old, *new;
170
171 if (!probe) {
172 WARN_ON(1);
173 return ERR_PTR(-EINVAL);
174 }
175 debug_print_probes(entry);
176 old = entry->probes;
177 if (old) {
178 /* (N -> N+1), (N != 0, 1) probes */
179 for (nr_probes = 0; old[nr_probes].func; nr_probes++)
180 if (old[nr_probes].func == probe &&
181 old[nr_probes].data == data)
182 return ERR_PTR(-EEXIST);
183 }
184 /* + 2 : one for new probe, one for NULL func */
185 new = allocate_probes(nr_probes + 2);
186 if (new == NULL)
187 return ERR_PTR(-ENOMEM);
188 if (old)
189 memcpy(new, old,
190 nr_probes * sizeof(struct lttng_ust_tracepoint_probe));
191 new[nr_probes].func = probe;
192 new[nr_probes].data = data;
193 new[nr_probes + 1].func = NULL;
194 entry->refcount = nr_probes + 1;
195 entry->probes = new;
196 debug_print_probes(entry);
197 return old;
198 }
199
200 static void *
201 tracepoint_entry_remove_probe(struct tracepoint_entry *entry,
202 void (*probe)(void), void *data)
203 {
204 int nr_probes = 0, nr_del = 0, i;
205 struct lttng_ust_tracepoint_probe *old, *new;
206
207 old = entry->probes;
208
209 if (!old)
210 return ERR_PTR(-ENOENT);
211
212 debug_print_probes(entry);
213 /* (N -> M), (N > 1, M >= 0) probes */
214 if (probe) {
215 for (nr_probes = 0; old[nr_probes].func; nr_probes++) {
216 if (old[nr_probes].func == probe &&
217 old[nr_probes].data == data)
218 nr_del++;
219 }
220 }
221
222 if (nr_probes - nr_del == 0) {
223 /* N -> 0, (N > 1) */
224 entry->probes = NULL;
225 entry->refcount = 0;
226 debug_print_probes(entry);
227 return old;
228 } else {
229 int j = 0;
230 /* N -> M, (N > 1, M > 0) */
231 /* + 1 for NULL */
232 new = allocate_probes(nr_probes - nr_del + 1);
233 if (new == NULL)
234 return ERR_PTR(-ENOMEM);
235 for (i = 0; old[i].func; i++)
236 if (old[i].func != probe || old[i].data != data)
237 new[j++] = old[i];
238 new[nr_probes - nr_del].func = NULL;
239 entry->refcount = nr_probes - nr_del;
240 entry->probes = new;
241 }
242 debug_print_probes(entry);
243 return old;
244 }
245
246 /*
247 * Get tracepoint if the tracepoint is present in the tracepoint hash table.
248 * Must be called with tracepoint mutex held.
249 * Returns NULL if not present.
250 */
251 static struct tracepoint_entry *get_tracepoint(const char *name)
252 {
253 struct cds_hlist_head *head;
254 struct cds_hlist_node *node;
255 struct tracepoint_entry *e;
256 size_t name_len = strlen(name);
257 uint32_t hash;
258
259 if (name_len > LTTNG_UST_ABI_SYM_NAME_LEN - 1) {
260 WARN("Truncating tracepoint name %s which exceeds size limits of %u chars", name, LTTNG_UST_ABI_SYM_NAME_LEN - 1);
261 name_len = LTTNG_UST_ABI_SYM_NAME_LEN - 1;
262 }
263 hash = jhash(name, name_len, 0);
264 head = &tracepoint_table[hash & (TRACEPOINT_TABLE_SIZE - 1)];
265 cds_hlist_for_each_entry(e, node, head, hlist) {
266 if (!strncmp(name, e->name, LTTNG_UST_ABI_SYM_NAME_LEN - 1))
267 return e;
268 }
269 return NULL;
270 }
271
272 /*
273 * Add the tracepoint to the tracepoint hash table. Must be called with
274 * tracepoint mutex held.
275 */
276 static struct tracepoint_entry *add_tracepoint(const char *name,
277 const char *signature)
278 {
279 struct cds_hlist_head *head;
280 struct cds_hlist_node *node;
281 struct tracepoint_entry *e;
282 size_t name_len = strlen(name);
283 size_t sig_len = strlen(signature);
284 size_t sig_off, name_off;
285 uint32_t hash;
286
287 if (name_len > LTTNG_UST_ABI_SYM_NAME_LEN - 1) {
288 WARN("Truncating tracepoint name %s which exceeds size limits of %u chars", name, LTTNG_UST_ABI_SYM_NAME_LEN - 1);
289 name_len = LTTNG_UST_ABI_SYM_NAME_LEN - 1;
290 }
291 hash = jhash(name, name_len, 0);
292 head = &tracepoint_table[hash & (TRACEPOINT_TABLE_SIZE - 1)];
293 cds_hlist_for_each_entry(e, node, head, hlist) {
294 if (!strncmp(name, e->name, LTTNG_UST_ABI_SYM_NAME_LEN - 1)) {
295 DBG("tracepoint %s busy", name);
296 return ERR_PTR(-EEXIST); /* Already there */
297 }
298 }
299
300 /*
301 * Using zmalloc here to allocate a variable length elements: name and
302 * signature. Could cause some memory fragmentation if overused.
303 */
304 name_off = sizeof(struct tracepoint_entry);
305 sig_off = name_off + name_len + 1;
306
307 e = zmalloc(sizeof(struct tracepoint_entry) + name_len + 1 + sig_len + 1);
308 if (!e)
309 return ERR_PTR(-ENOMEM);
310 e->name = (char *) e + name_off;
311 memcpy(e->name, name, name_len + 1);
312 e->name[name_len] = '\0';
313
314 e->signature = (char *) e + sig_off;
315 memcpy(e->signature, signature, sig_len + 1);
316 e->signature[sig_len] = '\0';
317
318 e->probes = NULL;
319 e->refcount = 0;
320 e->callsite_refcount = 0;
321
322 cds_hlist_add_head(&e->hlist, head);
323 return e;
324 }
325
326 /*
327 * Remove the tracepoint from the tracepoint hash table. Must be called with
328 * tracepoint mutex held.
329 */
330 static void remove_tracepoint(struct tracepoint_entry *e)
331 {
332 cds_hlist_del(&e->hlist);
333 free(e);
334 }
335
336 /*
337 * Sets the probe callback corresponding to one tracepoint.
338 */
339 static void set_tracepoint(struct tracepoint_entry **entry,
340 struct lttng_ust_tracepoint *elem, int active)
341 {
342 WARN_ON(strncmp((*entry)->name, elem->name, LTTNG_UST_ABI_SYM_NAME_LEN - 1) != 0);
343 /*
344 * Check that signatures match before connecting a probe to a
345 * tracepoint. Warn the user if they don't.
346 */
347 if (strcmp(elem->signature, (*entry)->signature) != 0) {
348 static int warned = 0;
349
350 /* Only print once, don't flood console. */
351 if (!warned) {
352 WARN("Tracepoint signature mismatch, not enabling one or more tracepoints. Ensure that the tracepoint probes prototypes match the application.");
353 WARN("Tracepoint \"%s\" signatures: call: \"%s\" vs probe: \"%s\".",
354 elem->name, elem->signature, (*entry)->signature);
355 warned = 1;
356 }
357 /* Don't accept connecting non-matching signatures. */
358 return;
359 }
360
361 /*
362 * rcu_assign_pointer has a cmm_smp_wmb() which makes sure that the new
363 * probe callbacks array is consistent before setting a pointer to it.
364 * This array is referenced by __DO_TRACE from
365 * include/linux/tracepoints.h. A matching cmm_smp_read_barrier_depends()
366 * is used.
367 */
368 lttng_ust_rcu_assign_pointer(elem->probes, (*entry)->probes);
369 CMM_STORE_SHARED(elem->state, active);
370 }
371
372 /*
373 * Disable a tracepoint and its probe callback.
374 * Note: only waiting an RCU period after setting elem->call to the empty
375 * function insures that the original callback is not used anymore. This insured
376 * by preempt_disable around the call site.
377 */
378 static void disable_tracepoint(struct lttng_ust_tracepoint *elem)
379 {
380 CMM_STORE_SHARED(elem->state, 0);
381 lttng_ust_rcu_assign_pointer(elem->probes, NULL);
382 }
383
384 /*
385 * Add the callsite to the callsite hash table. Must be called with
386 * tracepoint mutex held.
387 */
388 static void add_callsite(struct tracepoint_lib * lib, struct lttng_ust_tracepoint *tp)
389 {
390 struct cds_hlist_head *head;
391 struct callsite_entry *e;
392 const char *name = tp->name;
393 size_t name_len = strlen(name);
394 uint32_t hash;
395 struct tracepoint_entry *tp_entry;
396
397 if (name_len > LTTNG_UST_ABI_SYM_NAME_LEN - 1) {
398 WARN("Truncating tracepoint name %s which exceeds size limits of %u chars", name, LTTNG_UST_ABI_SYM_NAME_LEN - 1);
399 name_len = LTTNG_UST_ABI_SYM_NAME_LEN - 1;
400 }
401 hash = jhash(name, name_len, 0);
402 head = &callsite_table[hash & (CALLSITE_TABLE_SIZE - 1)];
403 e = zmalloc(sizeof(struct callsite_entry));
404 if (!e) {
405 PERROR("Unable to add callsite for tracepoint \"%s\"", name);
406 return;
407 }
408 cds_hlist_add_head(&e->hlist, head);
409 e->tp = tp;
410 cds_list_add(&e->node, &lib->callsites);
411
412 tp_entry = get_tracepoint(name);
413 if (!tp_entry)
414 return;
415 tp_entry->callsite_refcount++;
416 e->tp_entry_callsite_ref = true;
417 }
418
419 /*
420 * Remove the callsite from the callsite hash table and from lib
421 * callsite list. Must be called with tracepoint mutex held.
422 */
423 static void remove_callsite(struct callsite_entry *e)
424 {
425 struct tracepoint_entry *tp_entry;
426
427 tp_entry = get_tracepoint(e->tp->name);
428 if (tp_entry) {
429 if (e->tp_entry_callsite_ref)
430 tp_entry->callsite_refcount--;
431 if (tp_entry->callsite_refcount == 0)
432 disable_tracepoint(e->tp);
433 }
434 cds_hlist_del(&e->hlist);
435 cds_list_del(&e->node);
436 free(e);
437 }
438
439 /*
440 * Enable/disable all callsites based on the state of a specific
441 * tracepoint entry.
442 * Must be called with tracepoint mutex held.
443 */
444 static void tracepoint_sync_callsites(const char *name)
445 {
446 struct cds_hlist_head *head;
447 struct cds_hlist_node *node;
448 struct callsite_entry *e;
449 size_t name_len = strlen(name);
450 uint32_t hash;
451 struct tracepoint_entry *tp_entry;
452
453 tp_entry = get_tracepoint(name);
454 if (name_len > LTTNG_UST_ABI_SYM_NAME_LEN - 1) {
455 WARN("Truncating tracepoint name %s which exceeds size limits of %u chars", name, LTTNG_UST_ABI_SYM_NAME_LEN - 1);
456 name_len = LTTNG_UST_ABI_SYM_NAME_LEN - 1;
457 }
458 hash = jhash(name, name_len, 0);
459 head = &callsite_table[hash & (CALLSITE_TABLE_SIZE - 1)];
460 cds_hlist_for_each_entry(e, node, head, hlist) {
461 struct lttng_ust_tracepoint *tp = e->tp;
462
463 if (strncmp(name, tp->name, LTTNG_UST_ABI_SYM_NAME_LEN - 1))
464 continue;
465 if (tp_entry) {
466 if (!e->tp_entry_callsite_ref) {
467 tp_entry->callsite_refcount++;
468 e->tp_entry_callsite_ref = true;
469 }
470 set_tracepoint(&tp_entry, tp,
471 !!tp_entry->refcount);
472 } else {
473 disable_tracepoint(tp);
474 e->tp_entry_callsite_ref = false;
475 }
476 }
477 }
478
479 /**
480 * tracepoint_update_probe_range - Update a probe range
481 * @begin: beginning of the range
482 * @end: end of the range
483 *
484 * Updates the probe callback corresponding to a range of tracepoints.
485 */
486 static
487 void tracepoint_update_probe_range(struct lttng_ust_tracepoint * const *begin,
488 struct lttng_ust_tracepoint * const *end)
489 {
490 struct lttng_ust_tracepoint * const *iter;
491 struct tracepoint_entry *mark_entry;
492
493 for (iter = begin; iter < end; iter++) {
494 if (!*iter)
495 continue; /* skip dummy */
496 if (!(*iter)->name) {
497 disable_tracepoint(*iter);
498 continue;
499 }
500 mark_entry = get_tracepoint((*iter)->name);
501 if (mark_entry) {
502 set_tracepoint(&mark_entry, *iter,
503 !!mark_entry->refcount);
504 } else {
505 disable_tracepoint(*iter);
506 }
507 }
508 }
509
510 static void lib_update_tracepoints(struct tracepoint_lib *lib)
511 {
512 tracepoint_update_probe_range(lib->tracepoints_start,
513 lib->tracepoints_start + lib->tracepoints_count);
514 }
515
516 static void lib_register_callsites(struct tracepoint_lib *lib)
517 {
518 struct lttng_ust_tracepoint * const *begin;
519 struct lttng_ust_tracepoint * const *end;
520 struct lttng_ust_tracepoint * const *iter;
521
522 begin = lib->tracepoints_start;
523 end = lib->tracepoints_start + lib->tracepoints_count;
524
525 for (iter = begin; iter < end; iter++) {
526 if (!*iter)
527 continue; /* skip dummy */
528 if (!(*iter)->name) {
529 continue;
530 }
531 add_callsite(lib, *iter);
532 }
533 }
534
535 static void lib_unregister_callsites(struct tracepoint_lib *lib)
536 {
537 struct callsite_entry *callsite, *tmp;
538
539 cds_list_for_each_entry_safe(callsite, tmp, &lib->callsites, node)
540 remove_callsite(callsite);
541 }
542
543 /*
544 * Update probes, removing the faulty probes.
545 */
546 static void tracepoint_update_probes(void)
547 {
548 struct tracepoint_lib *lib;
549
550 /* tracepoints registered from libraries and executable. */
551 cds_list_for_each_entry(lib, &libs, list)
552 lib_update_tracepoints(lib);
553 }
554
555 static struct lttng_ust_tracepoint_probe *
556 tracepoint_add_probe(const char *name, void (*probe)(void), void *data,
557 const char *signature)
558 {
559 struct tracepoint_entry *entry;
560 struct lttng_ust_tracepoint_probe *old;
561
562 entry = get_tracepoint(name);
563 if (entry) {
564 if (strcmp(entry->signature, signature) != 0) {
565 ERR("Tracepoint and probe signature do not match.");
566 return ERR_PTR(-EINVAL);
567 }
568 } else {
569 entry = add_tracepoint(name, signature);
570 if (IS_ERR(entry))
571 return (struct lttng_ust_tracepoint_probe *)entry;
572 }
573 old = tracepoint_entry_add_probe(entry, probe, data);
574 if (IS_ERR(old) && !entry->refcount)
575 remove_tracepoint(entry);
576 return old;
577 }
578
579 static void tracepoint_release_queue_add_old_probes(void *old)
580 {
581 release_queue_need_update = 1;
582 if (old) {
583 struct tp_probes *tp_probes = caa_container_of(old,
584 struct tp_probes, probes[0]);
585 cds_list_add(&tp_probes->u.list, &release_queue);
586 }
587 }
588
589 /**
590 * __tracepoint_probe_register - Connect a probe to a tracepoint
591 * @name: tracepoint name
592 * @probe: probe handler
593 *
594 * Returns 0 if ok, error value on error.
595 * The probe address must at least be aligned on the architecture pointer size.
596 * Called with the tracepoint mutex held.
597 */
598 int __tracepoint_probe_register(const char *name, void (*probe)(void),
599 void *data, const char *signature)
600 {
601 void *old;
602 int ret = 0;
603
604 DBG("Registering probe to tracepoint %s", name);
605
606 pthread_mutex_lock(&tracepoint_mutex);
607 old = tracepoint_add_probe(name, probe, data, signature);
608 if (IS_ERR(old)) {
609 ret = PTR_ERR(old);
610 goto end;
611 }
612
613 tracepoint_sync_callsites(name);
614 release_probes(old);
615 end:
616 pthread_mutex_unlock(&tracepoint_mutex);
617 return ret;
618 }
619
620 /*
621 * Caller needs to invoke __tracepoint_probe_release_queue() after
622 * calling lttng_ust_tp_probe_register_queue_release() one or multiple
623 * times to ensure it does not leak memory.
624 */
625 int lttng_ust_tp_probe_register_queue_release(const char *name,
626 void (*probe)(void), void *data, const char *signature)
627 {
628 void *old;
629 int ret = 0;
630
631 DBG("Registering probe to tracepoint %s. Queuing release.", name);
632
633 pthread_mutex_lock(&tracepoint_mutex);
634 old = tracepoint_add_probe(name, probe, data, signature);
635 if (IS_ERR(old)) {
636 ret = PTR_ERR(old);
637 goto end;
638 }
639
640 tracepoint_sync_callsites(name);
641 tracepoint_release_queue_add_old_probes(old);
642 end:
643 pthread_mutex_unlock(&tracepoint_mutex);
644 return ret;
645 }
646
647 static void *tracepoint_remove_probe(const char *name, void (*probe)(void),
648 void *data)
649 {
650 struct tracepoint_entry *entry;
651 void *old;
652
653 entry = get_tracepoint(name);
654 if (!entry)
655 return ERR_PTR(-ENOENT);
656 old = tracepoint_entry_remove_probe(entry, probe, data);
657 if (IS_ERR(old))
658 return old;
659 if (!entry->refcount)
660 remove_tracepoint(entry);
661 return old;
662 }
663
664 /**
665 * tracepoint_probe_unregister - Disconnect a probe from a tracepoint
666 * @name: tracepoint name
667 * @probe: probe function pointer
668 * @probe: probe data pointer
669 */
670 int __tracepoint_probe_unregister(const char *name, void (*probe)(void),
671 void *data)
672 {
673 void *old;
674 int ret = 0;
675
676 DBG("Un-registering probe from tracepoint %s", name);
677
678 pthread_mutex_lock(&tracepoint_mutex);
679 old = tracepoint_remove_probe(name, probe, data);
680 if (IS_ERR(old)) {
681 ret = PTR_ERR(old);
682 goto end;
683 }
684 tracepoint_sync_callsites(name);
685 release_probes(old);
686 end:
687 pthread_mutex_unlock(&tracepoint_mutex);
688 return ret;
689 }
690
691 /*
692 * Caller needs to invoke __tracepoint_probe_release_queue() after
693 * calling lttng_ust_tp_probe_unregister_queue_release() one or multiple
694 * times to ensure it does not leak memory.
695 */
696 int lttng_ust_tp_probe_unregister_queue_release(const char *name,
697 void (*probe)(void), void *data)
698 {
699 void *old;
700 int ret = 0;
701
702 DBG("Un-registering probe from tracepoint %s. Queuing release.", name);
703
704 pthread_mutex_lock(&tracepoint_mutex);
705 old = tracepoint_remove_probe(name, probe, data);
706 if (IS_ERR(old)) {
707 ret = PTR_ERR(old);
708 goto end;
709 }
710 tracepoint_sync_callsites(name);
711 tracepoint_release_queue_add_old_probes(old);
712 end:
713 pthread_mutex_unlock(&tracepoint_mutex);
714 return ret;
715 }
716
717 void lttng_ust_tp_probe_prune_release_queue(void)
718 {
719 CDS_LIST_HEAD(release_probes);
720 struct tp_probes *pos, *next;
721
722 DBG("Release queue of unregistered tracepoint probes.");
723
724 pthread_mutex_lock(&tracepoint_mutex);
725 if (!release_queue_need_update)
726 goto end;
727 if (!cds_list_empty(&release_queue))
728 cds_list_replace_init(&release_queue, &release_probes);
729 release_queue_need_update = 0;
730
731 /* Wait for grace period between all sync_callsites and free. */
732 lttng_ust_urcu_synchronize_rcu();
733
734 cds_list_for_each_entry_safe(pos, next, &release_probes, u.list) {
735 cds_list_del(&pos->u.list);
736 free(pos);
737 }
738 end:
739 pthread_mutex_unlock(&tracepoint_mutex);
740 }
741
742 static void tracepoint_add_old_probes(void *old)
743 {
744 need_update = 1;
745 if (old) {
746 struct tp_probes *tp_probes = caa_container_of(old,
747 struct tp_probes, probes[0]);
748 cds_list_add(&tp_probes->u.list, &old_probes);
749 }
750 }
751
752 /**
753 * tracepoint_probe_register_noupdate - register a probe but not connect
754 * @name: tracepoint name
755 * @probe: probe handler
756 *
757 * caller must call tracepoint_probe_update_all()
758 */
759 int tracepoint_probe_register_noupdate(const char *name, void (*probe)(void),
760 void *data, const char *signature)
761 {
762 void *old;
763 int ret = 0;
764
765 pthread_mutex_lock(&tracepoint_mutex);
766 old = tracepoint_add_probe(name, probe, data, signature);
767 if (IS_ERR(old)) {
768 ret = PTR_ERR(old);
769 goto end;
770 }
771 tracepoint_add_old_probes(old);
772 end:
773 pthread_mutex_unlock(&tracepoint_mutex);
774 return ret;
775 }
776
777 /**
778 * tracepoint_probe_unregister_noupdate - remove a probe but not disconnect
779 * @name: tracepoint name
780 * @probe: probe function pointer
781 *
782 * caller must call tracepoint_probe_update_all()
783 * Called with the tracepoint mutex held.
784 */
785 int tracepoint_probe_unregister_noupdate(const char *name, void (*probe)(void),
786 void *data)
787 {
788 void *old;
789 int ret = 0;
790
791 DBG("Un-registering probe from tracepoint %s", name);
792
793 pthread_mutex_lock(&tracepoint_mutex);
794 old = tracepoint_remove_probe(name, probe, data);
795 if (IS_ERR(old)) {
796 ret = PTR_ERR(old);
797 goto end;
798 }
799 tracepoint_add_old_probes(old);
800 end:
801 pthread_mutex_unlock(&tracepoint_mutex);
802 return ret;
803 }
804
805 /**
806 * tracepoint_probe_update_all - update tracepoints
807 */
808 void tracepoint_probe_update_all(void)
809 {
810 CDS_LIST_HEAD(release_probes);
811 struct tp_probes *pos, *next;
812
813 pthread_mutex_lock(&tracepoint_mutex);
814 if (!need_update) {
815 goto end;
816 }
817 if (!cds_list_empty(&old_probes))
818 cds_list_replace_init(&old_probes, &release_probes);
819 need_update = 0;
820
821 tracepoint_update_probes();
822 /* Wait for grace period between update_probes and free. */
823 lttng_ust_urcu_synchronize_rcu();
824 cds_list_for_each_entry_safe(pos, next, &release_probes, u.list) {
825 cds_list_del(&pos->u.list);
826 free(pos);
827 }
828 end:
829 pthread_mutex_unlock(&tracepoint_mutex);
830 }
831
832 static void new_tracepoints(struct lttng_ust_tracepoint * const *start,
833 struct lttng_ust_tracepoint * const *end)
834 {
835 if (new_tracepoint_cb) {
836 struct lttng_ust_tracepoint * const *t;
837
838 for (t = start; t < end; t++) {
839 if (*t)
840 new_tracepoint_cb(*t);
841 }
842 }
843 }
844
845 /*
846 * tracepoint_{un,}register_lib is meant to be looked up by instrumented
847 * applications through dlsym(). If found, those can register their
848 * tracepoints, else those tracepoints will not be available for
849 * tracing. The number at the end of those symbols acts as a major
850 * version for tracepoints.
851 *
852 * Older instrumented applications should still work with newer
853 * liblttng-ust, but it is fine that instrumented applications compiled
854 * against recent liblttng-ust headers require a recent liblttng-ust
855 * runtime for those tracepoints to be taken into account.
856 */
857 int tracepoint_register_lib(struct lttng_ust_tracepoint * const *tracepoints_start,
858 int tracepoints_count);
859 int tracepoint_register_lib(struct lttng_ust_tracepoint * const *tracepoints_start,
860 int tracepoints_count)
861 {
862 struct tracepoint_lib *pl, *iter;
863
864 lttng_ust_tp_init();
865
866 pl = (struct tracepoint_lib *) zmalloc(sizeof(struct tracepoint_lib));
867 if (!pl) {
868 PERROR("Unable to register tracepoint lib");
869 return -1;
870 }
871 pl->tracepoints_start = tracepoints_start;
872 pl->tracepoints_count = tracepoints_count;
873 CDS_INIT_LIST_HEAD(&pl->callsites);
874
875 pthread_mutex_lock(&tracepoint_mutex);
876 /*
877 * We sort the libs by struct lib pointer address.
878 */
879 cds_list_for_each_entry_reverse(iter, &libs, list) {
880 BUG_ON(iter == pl); /* Should never be in the list twice */
881 if (iter < pl) {
882 /* We belong to the location right after iter. */
883 cds_list_add(&pl->list, &iter->list);
884 goto lib_added;
885 }
886 }
887 /* We should be added at the head of the list */
888 cds_list_add(&pl->list, &libs);
889 lib_added:
890 new_tracepoints(tracepoints_start, tracepoints_start + tracepoints_count);
891 lib_register_callsites(pl);
892 lib_update_tracepoints(pl);
893 pthread_mutex_unlock(&tracepoint_mutex);
894
895 DBG("just registered a tracepoints section from %p and having %d tracepoints",
896 tracepoints_start, tracepoints_count);
897 if (ust_err_debug_enabled()) {
898 int i;
899
900 for (i = 0; i < tracepoints_count; i++) {
901 DBG("registered tracepoint: %s", tracepoints_start[i]->name);
902 }
903 }
904
905 return 0;
906 }
907
908 int tracepoint_unregister_lib(struct lttng_ust_tracepoint * const *tracepoints_start);
909 int tracepoint_unregister_lib(struct lttng_ust_tracepoint * const *tracepoints_start)
910 {
911 struct tracepoint_lib *lib;
912
913 pthread_mutex_lock(&tracepoint_mutex);
914 cds_list_for_each_entry(lib, &libs, list) {
915 if (lib->tracepoints_start != tracepoints_start)
916 continue;
917
918 cds_list_del(&lib->list);
919 /*
920 * Unregistering a callsite also decreases the
921 * callsite reference count of the corresponding
922 * tracepoint, and disables the tracepoint if
923 * the reference count drops to zero.
924 */
925 lib_unregister_callsites(lib);
926 DBG("just unregistered a tracepoints section from %p",
927 lib->tracepoints_start);
928 free(lib);
929 break;
930 }
931 pthread_mutex_unlock(&tracepoint_mutex);
932 return 0;
933 }
934
935 /*
936 * Report in debug message whether the compiler correctly supports weak
937 * hidden symbols. This test checks that the address associated with two
938 * weak symbols with hidden visibility is the same when declared within
939 * two compile units part of the same module.
940 */
941 static void check_weak_hidden(void)
942 {
943 DBG("Your compiler treats weak symbols with hidden visibility for integer objects as %s between compile units part of the same module.",
944 &__tracepoint_test_symbol1 == lttng_ust_tp_check_weak_hidden1() ?
945 "SAME address" :
946 "DIFFERENT addresses");
947 DBG("Your compiler treats weak symbols with hidden visibility for pointer objects as %s between compile units part of the same module.",
948 &__tracepoint_test_symbol2 == lttng_ust_tp_check_weak_hidden2() ?
949 "SAME address" :
950 "DIFFERENT addresses");
951 DBG("Your compiler treats weak symbols with hidden visibility for 24-byte structure objects as %s between compile units part of the same module.",
952 &__tracepoint_test_symbol3 == lttng_ust_tp_check_weak_hidden3() ?
953 "SAME address" :
954 "DIFFERENT addresses");
955 }
956
957 void lttng_ust_tp_init(void)
958 {
959 if (uatomic_xchg(&initialized, 1) == 1)
960 return;
961 ust_err_init();
962 check_weak_hidden();
963 }
964
965 void lttng_ust_tp_exit(void)
966 {
967 initialized = 0;
968 }
969
970 /*
971 * Create the wrapper symbols.
972 */
973 #undef tp_rcu_read_lock
974 #undef tp_rcu_read_unlock
975 #undef tp_rcu_dereference
976
977 void tp_rcu_read_lock(void);
978 void tp_rcu_read_lock(void)
979 {
980 lttng_ust_urcu_read_lock();
981 }
982
983 void tp_rcu_read_unlock(void);
984 void tp_rcu_read_unlock(void)
985 {
986 lttng_ust_urcu_read_unlock();
987 }
988
989 void *tp_rcu_dereference_sym(void *p);
990 void *tp_rcu_dereference_sym(void *p)
991 {
992 return lttng_ust_rcu_dereference(p);
993 }
994
995 /*
996 * Programs that have threads that survive after they exit, and therefore call
997 * library destructors, should disable the tracepoint destructors by calling
998 * tp_disable_destructors(). This will leak the tracepoint
999 * instrumentation library shared object, leaving its teardown to the operating
1000 * system process teardown.
1001 *
1002 * To access and/or modify this value, users need to use a combination of
1003 * dlopen(3) and dlsym(3) to get an handle on the
1004 * tp_disable_destructors and tp_get_destructors_state symbols below.
1005 */
1006 void tp_disable_destructors(void);
1007 void tp_disable_destructors(void)
1008 {
1009 uatomic_set(&tracepoint_destructors_state, 0);
1010 }
1011
1012 /*
1013 * Returns 1 if the destructors are enabled and should be executed.
1014 * Returns 0 if the destructors are disabled.
1015 */
1016 int tp_get_destructors_state(void);
1017 int tp_get_destructors_state(void)
1018 {
1019 return uatomic_read(&tracepoint_destructors_state);
1020 }
This page took 0.068043 seconds and 4 git commands to generate.