Move to kernel style SPDX license identifiers
[lttng-ust.git] / include / lttng / tracepoint.h
index 03bc913fd877292857215165d2926bc003cc11dd..bcab5e2d7b0fa3c2ac0efb71b2c4f2ed3a68f2fe 100644 (file)
@@ -1,28 +1,12 @@
-#ifndef _LTTNG_TRACEPOINT_H
-#define _LTTNG_TRACEPOINT_H
-
 /*
- * Copyright 2011-2012 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * SPDX-License-Identifier: MIT
+ *
+ * Copyright (C) 2011-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
  */
 
+#ifndef _LTTNG_TRACEPOINT_H
+#define _LTTNG_TRACEPOINT_H
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <lttng/tracepoint-types.h>
 #include <lttng/ust-compiler.h>
 
 #ifdef LTTNG_UST_HAVE_SDT_INTEGRATION
-#define SDT_USE_VARIADIC
+/*
+ * Instead of using SDT_USE_VARIADIC from 'sys/sdt.h', use our own namespaced
+ * macros since the instrumented application might already have included
+ * 'sys/sdt.h' without variadic support.
+ */
 #include <sys/sdt.h>
-#define LTTNG_STAP_PROBEV STAP_PROBEV
+
+#define _LTTNG_SDT_NARG(...) \
+       __LTTNG_SDT_NARG(__VA_ARGS__, 12,11,10,9,8,7,6,5,4,3,2,1,0)
+
+#define __LTTNG_SDT_NARG(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12, N, ...) N
+
+#define _LTTNG_SDT_PROBE_N(provider, name, N, ...) \
+       _SDT_PROBE(provider, name, N, (__VA_ARGS__))
+
+#define LTTNG_STAP_PROBEV(provider, name, ...) \
+       _LTTNG_SDT_PROBE_N(provider, name, _LTTNG_SDT_NARG(0, ##__VA_ARGS__), ##__VA_ARGS__)
+
 #else
 #define LTTNG_STAP_PROBEV(...)
 #endif
@@ -165,12 +164,12 @@ void __tracepoint_cb_##_provider##___##_name(_TP_ARGS_PROTO(__VA_ARGS__));                \
 static                                                                                 \
 void __tracepoint_cb_##_provider##___##_name(_TP_ARGS_PROTO(__VA_ARGS__))              \
 {                                                                                      \
-       struct lttng_ust_tracepoint_probe *__tp_probe;                                          \
+       struct lttng_ust_tracepoint_probe *__tp_probe;                                  \
                                                                                        \
        if (caa_unlikely(!TP_RCU_LINK_TEST()))                                          \
                return;                                                                 \
-       tp_rcu_read_lock_bp();                                                          \
-       __tp_probe = tp_rcu_dereference_bp(__tracepoint_##_provider##___##_name.probes); \
+       tp_rcu_read_lock();                                                             \
+       __tp_probe = tp_rcu_dereference(__tracepoint_##_provider##___##_name.probes);   \
        if (caa_unlikely(!__tp_probe))                                                  \
                goto end;                                                               \
        do {                                                                            \
@@ -181,7 +180,7 @@ void __tracepoint_cb_##_provider##___##_name(_TP_ARGS_PROTO(__VA_ARGS__))           \
                                (_TP_ARGS_DATA_VAR(__VA_ARGS__));                       \
        } while ((++__tp_probe)->func);                                                 \
 end:                                                                                   \
-       tp_rcu_read_unlock_bp();                                                        \
+       tp_rcu_read_unlock();                                                           \
 }                                                                                      \
 static inline lttng_ust_notrace                                                                \
 void __tracepoint_register_##_provider##___##_name(char *name,                         \
@@ -218,31 +217,14 @@ struct lttng_ust_tracepoint_dlopen {
        int (*tracepoint_register_lib)(struct lttng_ust_tracepoint * const *tracepoints_start,
                int tracepoints_count);
        int (*tracepoint_unregister_lib)(struct lttng_ust_tracepoint * const *tracepoints_start);
-       void (*rcu_read_lock_sym_bp)(void);
-       void (*rcu_read_unlock_sym_bp)(void);
-       void *(*rcu_dereference_sym_bp)(void *p);
+       void (*rcu_read_lock_sym)(void);
+       void (*rcu_read_unlock_sym)(void);
+       void *(*rcu_dereference_sym)(void *p);
 };
 
 extern struct lttng_ust_tracepoint_dlopen tracepoint_dlopen;
 extern struct lttng_ust_tracepoint_dlopen *tracepoint_dlopen_ptr;
 
-/* Disable tracepoint destructors. */
-int __tracepoints__disable_destructors __attribute__((weak));
-
-/*
- * Programs that have threads that survive after they exit, and
- * therefore call library destructors, should disable the tracepoint
- * destructors by calling tracepoint_disable_destructors(). This will
- * leak the tracepoint instrumentation library shared object, leaving
- * its teardown to the operating system process teardown.
- */
-static inline void tracepoint_disable_destructors(void)
-{
-       __tracepoints__disable_destructors = 1;
-}
-
-#if defined(TRACEPOINT_DEFINE) || defined(TRACEPOINT_CREATE_PROBES)
-
 /*
  * These weak symbols, the constructor, and destructor take care of
  * registering only _one_ instance of the tracepoints per shared-ojbect
@@ -267,6 +249,35 @@ struct lttng_ust_tracepoint_dlopen tracepoint_dlopen
 struct lttng_ust_tracepoint_dlopen *tracepoint_dlopen_ptr
        __attribute__((weak, visibility("hidden")));
 
+/*
+ * Tracepoint dynamic linkage handling (callbacks). Hidden visibility: shared
+ * across objects in a module/main executable. The callbacks are used to
+ * control and check if the destructors should be executed.
+ */
+struct lttng_ust_tracepoint_destructors_syms {
+       void (*tracepoint_disable_destructors)(void);
+       int (*tracepoint_get_destructors_state)(void);
+};
+
+extern struct lttng_ust_tracepoint_destructors_syms tracepoint_destructors_syms;
+extern struct lttng_ust_tracepoint_destructors_syms *tracepoint_destructors_syms_ptr;
+
+struct lttng_ust_tracepoint_destructors_syms tracepoint_destructors_syms
+       __attribute__((weak, visibility("hidden")));
+struct lttng_ust_tracepoint_destructors_syms *tracepoint_destructors_syms_ptr
+       __attribute__((weak, visibility("hidden")));
+
+static inline void tracepoint_disable_destructors(void)
+{
+       if (!tracepoint_dlopen_ptr)
+               tracepoint_dlopen_ptr = &tracepoint_dlopen;
+       if (!tracepoint_destructors_syms_ptr)
+               tracepoint_destructors_syms_ptr = &tracepoint_destructors_syms;
+       if (tracepoint_dlopen_ptr->liblttngust_handle
+                       && tracepoint_destructors_syms_ptr->tracepoint_disable_destructors)
+               tracepoint_destructors_syms_ptr->tracepoint_disable_destructors();
+}
+
 #ifndef _LGPL_SOURCE
 static inline void lttng_ust_notrace
 __tracepoint__init_urcu_sym(void);
@@ -279,21 +290,21 @@ __tracepoint__init_urcu_sym(void)
         * Symbols below are needed by tracepoint call sites and probe
         * providers.
         */
-       if (!tracepoint_dlopen_ptr->rcu_read_lock_sym_bp)
-               tracepoint_dlopen_ptr->rcu_read_lock_sym_bp =
+       if (!tracepoint_dlopen_ptr->rcu_read_lock_sym)
+               tracepoint_dlopen_ptr->rcu_read_lock_sym =
                        URCU_FORCE_CAST(void (*)(void),
                                dlsym(tracepoint_dlopen_ptr->liblttngust_handle,
-                                       "tp_rcu_read_lock_bp"));
-       if (!tracepoint_dlopen_ptr->rcu_read_unlock_sym_bp)
-               tracepoint_dlopen_ptr->rcu_read_unlock_sym_bp =
+                                       "tp_rcu_read_lock"));
+       if (!tracepoint_dlopen_ptr->rcu_read_unlock_sym)
+               tracepoint_dlopen_ptr->rcu_read_unlock_sym =
                        URCU_FORCE_CAST(void (*)(void),
                                dlsym(tracepoint_dlopen_ptr->liblttngust_handle,
-                                       "tp_rcu_read_unlock_bp"));
-       if (!tracepoint_dlopen_ptr->rcu_dereference_sym_bp)
-               tracepoint_dlopen_ptr->rcu_dereference_sym_bp =
+                                       "tp_rcu_read_unlock"));
+       if (!tracepoint_dlopen_ptr->rcu_dereference_sym)
+               tracepoint_dlopen_ptr->rcu_dereference_sym =
                        URCU_FORCE_CAST(void *(*)(void *p),
                                dlsym(tracepoint_dlopen_ptr->liblttngust_handle,
-                                       "tp_rcu_dereference_sym_bp"));
+                                       "tp_rcu_dereference_sym"));
 }
 #else
 static inline void lttng_ust_notrace
@@ -320,7 +331,7 @@ __tracepoints__init(void)
                tracepoint_dlopen_ptr = &tracepoint_dlopen;
        if (!tracepoint_dlopen_ptr->liblttngust_handle)
                tracepoint_dlopen_ptr->liblttngust_handle =
-                       dlopen("liblttng-ust-tracepoint.so.0", RTLD_NOW | RTLD_GLOBAL);
+                       dlopen("liblttng-ust-tracepoint.so.1", RTLD_NOW | RTLD_GLOBAL);
        if (!tracepoint_dlopen_ptr->liblttngust_handle)
                return;
        __tracepoint__init_urcu_sym();
@@ -337,20 +348,32 @@ __tracepoints__destroy(void)
                return;
        if (!tracepoint_dlopen_ptr)
                tracepoint_dlopen_ptr = &tracepoint_dlopen;
-       if (!__tracepoints__disable_destructors
-                       && tracepoint_dlopen_ptr->liblttngust_handle
-                       && !__tracepoint_ptrs_registered) {
-               ret = dlclose(tracepoint_dlopen_ptr->liblttngust_handle);
-               if (ret) {
-                       fprintf(stderr, "Error (%d) in dlclose\n", ret);
-                       abort();
-               }
-               memset(tracepoint_dlopen_ptr, 0, sizeof(*tracepoint_dlopen_ptr));
+       if (!tracepoint_destructors_syms_ptr)
+               tracepoint_destructors_syms_ptr = &tracepoint_destructors_syms;
+       if (!tracepoint_dlopen_ptr->liblttngust_handle)
+               return;
+       if (__tracepoint_ptrs_registered)
+               return;
+       /*
+        * Lookup if destructors must be executed using the new method.
+        */
+       if (tracepoint_destructors_syms_ptr->tracepoint_get_destructors_state
+               && !tracepoint_destructors_syms_ptr->tracepoint_get_destructors_state()) {
+               /*
+                * The tracepoint_get_destructors_state symbol was found with
+                * dlsym but its returned value is 0 meaning that destructors
+                * must not be executed.
+                */
+               return;
        }
+       ret = dlclose(tracepoint_dlopen_ptr->liblttngust_handle);
+       if (ret) {
+               fprintf(stderr, "Error (%d) in dlclose\n", ret);
+               abort();
+       }
+       memset(tracepoint_dlopen_ptr, 0, sizeof(*tracepoint_dlopen_ptr));
 }
 
-#endif
-
 #ifdef TRACEPOINT_DEFINE
 
 /*
@@ -402,7 +425,8 @@ extern struct lttng_ust_tracepoint * const __stop___tracepoints_ptrs[]
                };                                                              \
        static struct lttng_ust_tracepoint *                                    \
                __tracepoint_ptr_##_provider##___##_name                        \
-               __attribute__((used, section("__tracepoints_ptrs"))) =          \
+               __attribute__((section("__tracepoints_ptrs"), used))            \
+               __lttng_ust_variable_attribute_no_sanitize_address =            \
                        &__tracepoint_##_provider##___##_name;
 
 static void lttng_ust_notrace __attribute__((constructor))
@@ -416,9 +440,11 @@ __tracepoints__ptrs_init(void)
                tracepoint_dlopen_ptr = &tracepoint_dlopen;
        if (!tracepoint_dlopen_ptr->liblttngust_handle)
                tracepoint_dlopen_ptr->liblttngust_handle =
-                       dlopen("liblttng-ust-tracepoint.so.0", RTLD_NOW | RTLD_GLOBAL);
+                       dlopen("liblttng-ust-tracepoint.so.1", RTLD_NOW | RTLD_GLOBAL);
        if (!tracepoint_dlopen_ptr->liblttngust_handle)
                return;
+       if (!tracepoint_destructors_syms_ptr)
+               tracepoint_destructors_syms_ptr = &tracepoint_destructors_syms;
        tracepoint_dlopen_ptr->tracepoint_register_lib =
                URCU_FORCE_CAST(int (*)(struct lttng_ust_tracepoint * const *, int),
                                dlsym(tracepoint_dlopen_ptr->liblttngust_handle,
@@ -427,6 +453,14 @@ __tracepoints__ptrs_init(void)
                URCU_FORCE_CAST(int (*)(struct lttng_ust_tracepoint * const *),
                                dlsym(tracepoint_dlopen_ptr->liblttngust_handle,
                                        "tracepoint_unregister_lib"));
+       tracepoint_destructors_syms_ptr->tracepoint_disable_destructors =
+               URCU_FORCE_CAST(void (*)(void),
+                               dlsym(tracepoint_dlopen_ptr->liblttngust_handle,
+                                       "tp_disable_destructors"));
+       tracepoint_destructors_syms_ptr->tracepoint_get_destructors_state =
+               URCU_FORCE_CAST(int (*)(void),
+                               dlsym(tracepoint_dlopen_ptr->liblttngust_handle,
+                                       "tp_get_destructors_state"));
        __tracepoint__init_urcu_sym();
        if (tracepoint_dlopen_ptr->tracepoint_register_lib) {
                tracepoint_dlopen_ptr->tracepoint_register_lib(__start___tracepoints_ptrs,
@@ -446,10 +480,13 @@ __tracepoints__ptrs_destroy(void)
                return;
        if (!tracepoint_dlopen_ptr)
                tracepoint_dlopen_ptr = &tracepoint_dlopen;
+       if (!tracepoint_destructors_syms_ptr)
+               tracepoint_destructors_syms_ptr = &tracepoint_destructors_syms;
        if (tracepoint_dlopen_ptr->tracepoint_unregister_lib)
                tracepoint_dlopen_ptr->tracepoint_unregister_lib(__start___tracepoints_ptrs);
-       if (!__tracepoints__disable_destructors
-                       && tracepoint_dlopen_ptr->liblttngust_handle
+       if (tracepoint_dlopen_ptr->liblttngust_handle
+                       && tracepoint_destructors_syms_ptr->tracepoint_get_destructors_state
+                       && tracepoint_destructors_syms_ptr->tracepoint_get_destructors_state()
                        && !__tracepoint_ptrs_registered) {
                ret = dlclose(tracepoint_dlopen_ptr->liblttngust_handle);
                if (ret) {
@@ -524,7 +561,7 @@ __tracepoints__ptrs_destroy(void)
  * How to use the TRACEPOINT_EVENT macro:
  *
  * An example:
- * 
+ *
  * TRACEPOINT_EVENT(someproject_component, event_name,
  *
  *     * TP_ARGS takes from 0 to 10 "type, field_name" pairs *
@@ -535,23 +572,23 @@ __tracepoints__ptrs_destroy(void)
  *     * TP_FIELDS describes the event payload layout in the trace *
  *
  *     TP_FIELDS(
- *         * Integer, printed in base 10 * 
+ *         * Integer, printed in base 10 *
  *         ctf_integer(int, field_a, arg0)
  *
- *         * Integer, printed with 0x base 16 * 
+ *         * Integer, printed with 0x base 16 *
  *         ctf_integer_hex(unsigned long, field_d, arg1)
  *
  *         * Enumeration *
  *         ctf_enum(someproject_component, enum_name, int, field_e, arg0)
  *
- *         * Array Sequence, printed as UTF8-encoded array of bytes * 
+ *         * Array Sequence, printed as UTF8-encoded array of bytes *
  *         ctf_array_text(char, field_b, string, FIXED_LEN)
  *         ctf_sequence_text(char, field_c, string, size_t, strlen)
  *
- *         * String, printed as UTF8-encoded string * 
+ *         * String, printed as UTF8-encoded string *
  *         ctf_string(field_e, string)
  *
- *         * Array sequence of signed integer values * 
+ *         * Array sequence of signed integer values *
  *         ctf_array(long, field_f, arg4, FIXED_LEN4)
  *         ctf_sequence(long, field_g, arg4, size_t, arg4_len)
  *     )
This page took 0.030464 seconds and 4 git commands to generate.