New API: lttng_ust_init_thread() for async-signal tracing
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 30 Mar 2021 13:54:23 +0000 (09:54 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 30 Mar 2021 18:37:05 +0000 (14:37 -0400)
LTTng-UST uses Global Dynamic model TLS variables rather than IE
model because many versions of glibc don't preallocate a pool large
enough for TLS variables IE model defined in other shared libraries,
and causes issues when using LTTng-UST for Java tracing.

Because of this use of Global Dynamic TLS variables, users wishing to
trace from signal handlers need to explicitly trigger the lazy
allocation of those variables for each thread before using them.
This can be triggered by calling lttng_ust_init_thread().

Hide the public symbols for ring buffer and counter clients init/exit.
Expose new symbols for init/exit of all ring buffer and counter clients
instead. Those new symbols are only used by liblttng-ust-ctl, and are
thus in an internal header.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: I389be1db96e5ff1e9a116311b8adf8676c9752cb

include/Makefile.am
include/lttng/ust-thread.h [new file with mode: 0644]
liblttng-ust-ctl/ustctl.c
liblttng-ust/lttng-rb-clients.h
liblttng-ust/lttng-ring-buffer-client-discard-rt.c
liblttng-ust/lttng-ring-buffer-client-discard.c
liblttng-ust/lttng-ring-buffer-client-overwrite-rt.c
liblttng-ust/lttng-ring-buffer-client-overwrite.c
liblttng-ust/lttng-ring-buffer-client.h
liblttng-ust/lttng-ust-comm.c
liblttng-ust/ust-events-internal.h

index 4d4761d911aff407429b1a917aded656d6bca0d7..854b4785ee9c852ff5e639fb7ec9b69680df6bd2 100644 (file)
@@ -32,6 +32,7 @@ nobase_include_HEADERS = \
        lttng/ust-clock.h \
        lttng/ust-getcpu.h \
        lttng/ust-libc-wrapper.h \
+       lttng/ust-thread.h \
        lttng/urcu/pointer.h \
        lttng/urcu/urcu-ust.h \
        lttng/urcu/static/pointer.h \
diff --git a/include/lttng/ust-thread.h b/include/lttng/ust-thread.h
new file mode 100644 (file)
index 0000000..2c84ae7
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * SPDX-License-Identifier: MIT
+ *
+ * Copyright (C) 2021 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ */
+
+#ifndef _LTTNG_UST_THREAD_H
+#define _LTTNG_UST_THREAD_H
+
+#include <signal.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Initialize this thread's LTTng-UST data structures. There is
+ * typically no need to call this, because LTTng-UST initializes its
+ * per-thread data structures lazily, but it should be called explicitly
+ * upon creation of each thread before signal handlers nesting over
+ * those threads use LTTng-UST tracepoints.
+ */
+void lttng_ust_init_thread(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LTTNG_UST_THREAD_H */
index 40b3667b2994c11c0dc97c1e124fcfc1b0251216..9acce7a99b9d55fac380fb782c7f70e4e78f8e62 100644 (file)
@@ -84,17 +84,6 @@ struct ustctl_daemon_counter {
        struct ustctl_counter_attr *attr;       /* initial attributes */
 };
 
-extern void lttng_ring_buffer_client_overwrite_init(void);
-extern void lttng_ring_buffer_client_overwrite_rt_init(void);
-extern void lttng_ring_buffer_client_discard_init(void);
-extern void lttng_ring_buffer_client_discard_rt_init(void);
-extern void lttng_ring_buffer_metadata_client_init(void);
-extern void lttng_ring_buffer_client_overwrite_exit(void);
-extern void lttng_ring_buffer_client_overwrite_rt_exit(void);
-extern void lttng_ring_buffer_client_discard_exit(void);
-extern void lttng_ring_buffer_client_discard_rt_exit(void);
-extern void lttng_ring_buffer_metadata_client_exit(void);
-
 int ustctl_release_handle(int sock, int handle)
 {
        struct ustcomm_ust_msg lum;
@@ -2917,24 +2906,14 @@ void ustctl_init(void)
        ust_err_init();
        lttng_ust_getenv_init();        /* Needs ust_err_init() to be completed. */
        lttng_ust_clock_init();
-       lttng_ring_buffer_metadata_client_init();
-       lttng_ring_buffer_client_overwrite_init();
-       lttng_ring_buffer_client_overwrite_rt_init();
-       lttng_ring_buffer_client_discard_init();
-       lttng_ring_buffer_client_discard_rt_init();
-       lttng_counter_client_percpu_32_modular_init();
-       lttng_counter_client_percpu_64_modular_init();
+       lttng_ust_ring_buffer_clients_init();
+       lttng_ust_counter_clients_init();
        lib_ringbuffer_signal_init();
 }
 
 static __attribute__((destructor))
 void ustctl_exit(void)
 {
-       lttng_ring_buffer_client_discard_rt_exit();
-       lttng_ring_buffer_client_discard_exit();
-       lttng_ring_buffer_client_overwrite_rt_exit();
-       lttng_ring_buffer_client_overwrite_exit();
-       lttng_ring_buffer_metadata_client_exit();
-       lttng_counter_client_percpu_32_modular_exit();
-       lttng_counter_client_percpu_64_modular_exit();
+       lttng_ust_counter_clients_exit();
+       lttng_ust_ring_buffer_clients_exit();
 }
index 57d7cdfe46146a1cec034489088f5ad698261df9..4b6999e4e3974a98c0ab1d2e08b24683a98336ee 100644 (file)
@@ -39,4 +39,14 @@ struct lttng_ust_client_lib_ring_buffer_client_cb {
                        struct lttng_ust_lib_ring_buffer_channel *chan, uint64_t *id);
 };
 
+/*
+ * The ring buffer and counter clients init/exit symbols are private ABI
+ * for liblttng-ust-ctl, which is why they are not hidden.
+ */
+void lttng_ust_ring_buffer_clients_init(void);
+void lttng_ust_ring_buffer_clients_exit(void);
+
+void lttng_ust_counter_clients_init(void);
+void lttng_ust_counter_clients_exit(void);
+
 #endif /* _LTTNG_RB_CLIENT_H */
index 425515b6575a5361c14cc75e1bb765c4b69e5b9b..0c5884b742cb956d5a6ca5a53ea05a8a1c68d557 100644 (file)
@@ -11,6 +11,8 @@
 
 #define RING_BUFFER_MODE_TEMPLATE              RING_BUFFER_DISCARD
 #define RING_BUFFER_MODE_TEMPLATE_STRING       "discard-rt"
+#define RING_BUFFER_MODE_TEMPLATE_TLS_FIXUP    \
+       lttng_ust_fixup_ring_buffer_client_discard_rt_tls
 #define RING_BUFFER_MODE_TEMPLATE_INIT \
        lttng_ring_buffer_client_discard_rt_init
 #define RING_BUFFER_MODE_TEMPLATE_EXIT \
index 954303a84b4602d22f0205682e7080ef29d806a5..82d25fd4a498e708ddcbdc12d4758ff228ea5331 100644 (file)
@@ -11,6 +11,8 @@
 
 #define RING_BUFFER_MODE_TEMPLATE              RING_BUFFER_DISCARD
 #define RING_BUFFER_MODE_TEMPLATE_STRING       "discard"
+#define RING_BUFFER_MODE_TEMPLATE_TLS_FIXUP    \
+       lttng_ust_fixup_ring_buffer_client_discard_tls
 #define RING_BUFFER_MODE_TEMPLATE_INIT \
        lttng_ring_buffer_client_discard_init
 #define RING_BUFFER_MODE_TEMPLATE_EXIT \
index da568ee5ec3cd501c84eae3cbeffea7882d2ed83..d0b9151b3de39009c7fa7b203f422fe012e630f8 100644 (file)
@@ -11,6 +11,8 @@
 
 #define RING_BUFFER_MODE_TEMPLATE              RING_BUFFER_OVERWRITE
 #define RING_BUFFER_MODE_TEMPLATE_STRING       "overwrite-rt"
+#define RING_BUFFER_MODE_TEMPLATE_TLS_FIXUP    \
+       lttng_ust_fixup_ring_buffer_client_overwrite_rt_tls
 #define RING_BUFFER_MODE_TEMPLATE_INIT \
        lttng_ring_buffer_client_overwrite_rt_init
 #define RING_BUFFER_MODE_TEMPLATE_EXIT \
index 712e882cb6dde0abeb74e6fc432ef7416d013f9f..2a92fabac5678e4b6afa591884941ee7f9685ee9 100644 (file)
@@ -11,6 +11,8 @@
 
 #define RING_BUFFER_MODE_TEMPLATE              RING_BUFFER_OVERWRITE
 #define RING_BUFFER_MODE_TEMPLATE_STRING       "overwrite"
+#define RING_BUFFER_MODE_TEMPLATE_TLS_FIXUP    \
+       lttng_ust_fixup_ring_buffer_client_overwrite_tls
 #define RING_BUFFER_MODE_TEMPLATE_INIT \
        lttng_ring_buffer_client_overwrite_init
 #define RING_BUFFER_MODE_TEMPLATE_EXIT \
index dc3dd88f4260b7b2545e254de8c180efcb328e5c..dfc98ceeff8c4bc5044b35c771ef31043c985b92 100644 (file)
@@ -78,8 +78,7 @@ static DEFINE_URCU_TLS(private_ctx_stack_t, private_ctx_stack);
 /*
  * Force a read (imply TLS fixup for dlopen) of TLS variables.
  */
-static
-void lttng_fixup_rb_client_tls(void)
+void RING_BUFFER_MODE_TEMPLATE_TLS_FIXUP(void)
 {
        asm volatile ("" : : "m" (URCU_TLS(private_ctx_stack)));
 }
@@ -858,7 +857,6 @@ void RING_BUFFER_MODE_TEMPLATE_INIT(void)
 {
        DBG("LTT : ltt ring buffer client \"%s\" init\n",
                "relay-" RING_BUFFER_MODE_TEMPLATE_STRING "-mmap");
-       lttng_fixup_rb_client_tls();
        lttng_transport_register(&lttng_relay_transport);
 }
 
index cb9f8c88361cddf9fa308a31100351c1147e3b54..07ae9a348f99ef26c6ec99be958ed7de2fd85d1c 100644 (file)
@@ -351,17 +351,6 @@ static const char *cmd_name_mapping[] = {
 static const char *str_timeout;
 static int got_timeout_env;
 
-extern void lttng_ring_buffer_client_overwrite_init(void);
-extern void lttng_ring_buffer_client_overwrite_rt_init(void);
-extern void lttng_ring_buffer_client_discard_init(void);
-extern void lttng_ring_buffer_client_discard_rt_init(void);
-extern void lttng_ring_buffer_metadata_client_init(void);
-extern void lttng_ring_buffer_client_overwrite_exit(void);
-extern void lttng_ring_buffer_client_overwrite_rt_exit(void);
-extern void lttng_ring_buffer_client_discard_exit(void);
-extern void lttng_ring_buffer_client_discard_rt_exit(void);
-extern void lttng_ring_buffer_metadata_client_exit(void);
-
 static char *get_map_shm(struct sock_info *sock_info);
 
 ssize_t lttng_ust_read(int fd, void *buf, size_t len)
@@ -437,6 +426,31 @@ void lttng_ust_fixup_tls(void)
        lttng_fixup_net_ns_tls();
        lttng_fixup_time_ns_tls();
        lttng_fixup_uts_ns_tls();
+       lttng_ust_fixup_ring_buffer_client_discard_tls();
+       lttng_ust_fixup_ring_buffer_client_discard_rt_tls();
+       lttng_ust_fixup_ring_buffer_client_overwrite_tls();
+       lttng_ust_fixup_ring_buffer_client_overwrite_rt_tls();
+}
+
+/*
+ * LTTng-UST uses Global Dynamic model TLS variables rather than IE
+ * model because many versions of glibc don't preallocate a pool large
+ * enough for TLS variables IE model defined in other shared libraries,
+ * and causes issues when using LTTng-UST for Java tracing.
+ *
+ * Because of this use of Global Dynamic TLS variables, users wishing to
+ * trace from signal handlers need to explicitly trigger the lazy
+ * allocation of those variables for each thread before using them.
+ * This can be triggered by calling lttng_ust_init_thread().
+ */
+void lttng_ust_init_thread(void)
+{
+       /*
+        * Because those TLS variables are global dynamic, we need to
+        * ensure those are initialized before a signal handler nesting over
+        * this thread attempts to use them.
+        */
+       lttng_ust_fixup_tls();
 }
 
 int lttng_get_notify_socket(void *owner)
@@ -2048,6 +2062,36 @@ void lttng_ust_libc_wrapper_malloc_init(void)
 {
 }
 
+void lttng_ust_ring_buffer_clients_init(void)
+{
+       lttng_ring_buffer_metadata_client_init();
+       lttng_ring_buffer_client_overwrite_init();
+       lttng_ring_buffer_client_overwrite_rt_init();
+       lttng_ring_buffer_client_discard_init();
+       lttng_ring_buffer_client_discard_rt_init();
+}
+
+void lttng_ust_ring_buffer_clients_exit(void)
+{
+       lttng_ring_buffer_client_discard_rt_exit();
+       lttng_ring_buffer_client_discard_exit();
+       lttng_ring_buffer_client_overwrite_rt_exit();
+       lttng_ring_buffer_client_overwrite_exit();
+       lttng_ring_buffer_metadata_client_exit();
+}
+
+void lttng_ust_counter_clients_init(void)
+{
+       lttng_counter_client_percpu_64_modular_init();
+       lttng_counter_client_percpu_32_modular_init();
+}
+
+void lttng_ust_counter_clients_exit(void)
+{
+       lttng_counter_client_percpu_32_modular_exit();
+       lttng_counter_client_percpu_64_modular_exit();
+}
+
 /*
  * sessiond monitoring thread: monitor presence of global and per-user
  * sessiond by polling the application common named pipe.
@@ -2106,13 +2150,8 @@ void __attribute__((constructor)) lttng_ust_init(void)
        lttng_ust_clock_init();
        lttng_ust_getcpu_init();
        lttng_ust_statedump_init();
-       lttng_ring_buffer_metadata_client_init();
-       lttng_ring_buffer_client_overwrite_init();
-       lttng_ring_buffer_client_overwrite_rt_init();
-       lttng_ring_buffer_client_discard_init();
-       lttng_ring_buffer_client_discard_rt_init();
-       lttng_counter_client_percpu_32_modular_init();
-       lttng_counter_client_percpu_64_modular_init();
+       lttng_ust_ring_buffer_clients_init();
+       lttng_ust_counter_clients_init();
        lttng_perf_counter_init();
        /*
         * Invoke ust malloc wrapper init before starting other threads.
@@ -2253,13 +2292,8 @@ void lttng_ust_cleanup(int exiting)
        lttng_ust_abi_exit();
        lttng_ust_abi_events_exit();
        lttng_perf_counter_exit();
-       lttng_ring_buffer_client_discard_rt_exit();
-       lttng_ring_buffer_client_discard_exit();
-       lttng_ring_buffer_client_overwrite_rt_exit();
-       lttng_ring_buffer_client_overwrite_exit();
-       lttng_ring_buffer_metadata_client_exit();
-       lttng_counter_client_percpu_32_modular_exit();
-       lttng_counter_client_percpu_64_modular_exit();
+       lttng_ust_ring_buffer_clients_exit();
+       lttng_ust_counter_clients_exit();
        lttng_ust_statedump_destroy();
        lttng_ust_tp_exit();
        if (!exiting) {
index 055e4f6eab259b633b615015a449a888f3538d52..e8c44be40499132ef4c71f214935e24ec0117d16 100644 (file)
@@ -908,4 +908,35 @@ __attribute__((visibility("hidden")))
 void lttng_ust_format_event_name(const struct lttng_ust_event_desc *desc,
                char *name);
 
+__attribute__((visibility("hidden")))
+void lttng_ring_buffer_client_overwrite_init(void);
+__attribute__((visibility("hidden")))
+void lttng_ring_buffer_client_overwrite_rt_init(void);
+__attribute__((visibility("hidden")))
+void lttng_ring_buffer_client_discard_init(void);
+__attribute__((visibility("hidden")))
+void lttng_ring_buffer_client_discard_rt_init(void);
+__attribute__((visibility("hidden")))
+void lttng_ring_buffer_metadata_client_init(void);
+
+__attribute__((visibility("hidden")))
+void lttng_ring_buffer_client_overwrite_exit(void);
+__attribute__((visibility("hidden")))
+void lttng_ring_buffer_client_overwrite_rt_exit(void);
+__attribute__((visibility("hidden")))
+void lttng_ring_buffer_client_discard_exit(void);
+__attribute__((visibility("hidden")))
+void lttng_ring_buffer_client_discard_rt_exit(void);
+__attribute__((visibility("hidden")))
+void lttng_ring_buffer_metadata_client_exit(void);
+
+__attribute__((visibility("hidden")))
+void lttng_ust_fixup_ring_buffer_client_overwrite_tls(void);
+__attribute__((visibility("hidden")))
+void lttng_ust_fixup_ring_buffer_client_overwrite_rt_tls(void);
+__attribute__((visibility("hidden")))
+void lttng_ust_fixup_ring_buffer_client_discard_tls(void);
+__attribute__((visibility("hidden")))
+void lttng_ust_fixup_ring_buffer_client_discard_rt_tls(void);
+
 #endif /* _LTTNG_UST_EVENTS_INTERNAL_H */
This page took 0.030955 seconds and 4 git commands to generate.