From fca97dfd73a96bbf964c39e7f3a21fe70cccee96 Mon Sep 17 00:00:00 2001 From: Michael Jeanson Date: Tue, 13 Apr 2021 16:39:18 -0400 Subject: [PATCH] Initialize liblttng-ust-common in dependent libraries liblttng-ust-common is a new public library introduced in this developement cycle to contain the shared state between liblttng-ust and our other libs that can't link directly on liblttng-ust. The constructor of each of these libraries should now call the liblttng-ust-common constructor early in their own constructors to ensure proper execution order. * Rename library constructors with the _ctor suffix to help distinguish them from other _init functions. * Hide the fd-tracker init fonction, the liblttng-ust-common ctor should be called instead. * All libraries linked on 'liblttng-ust-common' call its constructor early in theirs. Change-Id: I8e083f392b4ef2427addd00120cffc61a6314697 Signed-off-by: Michael Jeanson Signed-off-by: Mathieu Desnoyers --- include/Makefile.am | 1 + include/lttng/ust-common.h | 20 +++++++++++++++++ include/lttng/ust-libc-wrapper.h | 2 +- src/common/ust-fd.h | 1 - src/lib/lttng-ust-common/Makefile.am | 1 + src/lib/lttng-ust-common/fd-tracker.c | 14 +++++++----- src/lib/lttng-ust-common/fd-tracker.h | 13 +++++++++++ src/lib/lttng-ust-common/ust-common.c | 22 ++++++++++++------- src/lib/lttng-ust-ctl/ustctl.c | 10 +++++++-- src/lib/lttng-ust-fd/Makefile.am | 2 ++ src/lib/lttng-ust-fd/lttng-ust-fd.c | 13 ++++++++++- .../lttng-ust-libc-wrapper/lttng-ust-malloc.c | 2 +- src/lib/lttng-ust-tracepoint/tracepoint.c | 2 ++ src/lib/lttng-ust/lttng-ust-comm.c | 17 ++++++++------ 14 files changed, 93 insertions(+), 27 deletions(-) create mode 100644 include/lttng/ust-common.h create mode 100644 src/lib/lttng-ust-common/fd-tracker.h diff --git a/include/Makefile.am b/include/Makefile.am index 287fe13d..72239e5a 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -15,6 +15,7 @@ nobase_include_HEADERS = \ lttng/ust-tracepoint-event-nowrite.h \ lttng/ust-arch.h \ lttng/ust-events.h \ + lttng/ust-common.h \ lttng/ust-ctl.h \ lttng/ust-abi.h \ lttng/ust-tracer.h \ diff --git a/include/lttng/ust-common.h b/include/lttng/ust-common.h new file mode 100644 index 00000000..8396e6b4 --- /dev/null +++ b/include/lttng/ust-common.h @@ -0,0 +1,20 @@ +/* + * SPDX-License-Identifier: MIT + * + * Copyright (C) 2021 Michael Jeanson + * + * Public symbols of liblttng-ust-common.so + */ + +#ifndef _LTTNG_UST_COMMON_H +#define _LTTNG_UST_COMMON_H + +/* + * The liblttng-ust-common constructor is public so it can be called in the + * constructors of client libraries since there is no reliable way to guarantee + * the execution order of constructors across shared library. + */ +void lttng_ust_common_ctor(void) + __attribute__((constructor)); + +#endif diff --git a/include/lttng/ust-libc-wrapper.h b/include/lttng/ust-libc-wrapper.h index 2eaf5dc6..0853997b 100644 --- a/include/lttng/ust-libc-wrapper.h +++ b/include/lttng/ust-libc-wrapper.h @@ -20,7 +20,7 @@ * function in liblttng-ust that is overridden by the one in * liblttng-ust-wrapper-libc when it's preloaded. */ -void lttng_ust_libc_wrapper_malloc_init(void) +void lttng_ust_libc_wrapper_malloc_ctor(void) __attribute__((constructor)); #endif diff --git a/src/common/ust-fd.h b/src/common/ust-fd.h index 9d14583c..eb9c525c 100644 --- a/src/common/ust-fd.h +++ b/src/common/ust-fd.h @@ -17,7 +17,6 @@ #include -void lttng_ust_init_fd_tracker(void); int lttng_ust_add_fd_to_tracker(int fd); void lttng_ust_delete_fd_from_tracker(int fd); void lttng_ust_lock_fd_tracker(void); diff --git a/src/lib/lttng-ust-common/Makefile.am b/src/lib/lttng-ust-common/Makefile.am index bb32360f..5d0b2242 100644 --- a/src/lib/lttng-ust-common/Makefile.am +++ b/src/lib/lttng-ust-common/Makefile.am @@ -4,6 +4,7 @@ lib_LTLIBRARIES = liblttng-ust-common.la liblttng_ust_common_la_SOURCES = \ fd-tracker.c \ + fd-tracker.h \ ust-common.c \ lttng-ust-urcu.c \ lttng-ust-urcu-pointer.c diff --git a/src/lib/lttng-ust-common/fd-tracker.c b/src/lib/lttng-ust-common/fd-tracker.c index 026a9327..54f7deb4 100644 --- a/src/lib/lttng-ust-common/fd-tracker.c +++ b/src/lib/lttng-ust-common/fd-tracker.c @@ -30,6 +30,8 @@ #include #include "common/logging.h" +#include "lib/lttng-ust-common/fd-tracker.h" + /* Operations on the fd set. */ #define IS_FD_VALID(fd) ((fd) >= 0 && (fd) < lttng_ust_max_fd) #define GET_FD_SET_FOR_FD(fd, fd_sets) (&((fd_sets)[(fd) / FD_SETSIZE])) @@ -87,7 +89,7 @@ void lttng_ust_fixup_fd_tracker_tls(void) * process. This will be called during the constructor execution * and will also be called in the child after fork via lttng_ust_init. */ -void lttng_ust_init_fd_tracker(void) +void lttng_ust_fd_tracker_init(void) { struct rlimit rlim; int i; @@ -269,7 +271,7 @@ int lttng_ust_add_fd_to_tracker(int fd) * Ensure the tracker is initialized when called from * constructors. */ - lttng_ust_init_fd_tracker(); + lttng_ust_fd_tracker_init(); assert(URCU_TLS(ust_fd_mutex_nest)); if (IS_FD_STD(fd)) { @@ -301,7 +303,7 @@ void lttng_ust_delete_fd_from_tracker(int fd) * Ensure the tracker is initialized when called from * constructors. */ - lttng_ust_init_fd_tracker(); + lttng_ust_fd_tracker_init(); assert(URCU_TLS(ust_fd_mutex_nest)); /* Not a valid fd. */ @@ -327,7 +329,7 @@ int lttng_ust_safe_close_fd(int fd, int (*close_cb)(int fd)) * Ensure the tracker is initialized when called from * constructors. */ - lttng_ust_init_fd_tracker(); + lttng_ust_fd_tracker_init(); /* * If called from lttng-ust, we directly call close without @@ -363,7 +365,7 @@ int lttng_ust_safe_fclose_stream(FILE *stream, int (*fclose_cb)(FILE *stream)) * Ensure the tracker is initialized when called from * constructors. */ - lttng_ust_init_fd_tracker(); + lttng_ust_fd_tracker_init(); /* * If called from lttng-ust, we directly call fclose without @@ -418,7 +420,7 @@ int lttng_ust_safe_closefrom_fd(int lowfd, int (*close_cb)(int fd)) * Ensure the tracker is initialized when called from * constructors. */ - lttng_ust_init_fd_tracker(); + lttng_ust_fd_tracker_init(); if (lowfd < 0) { /* diff --git a/src/lib/lttng-ust-common/fd-tracker.h b/src/lib/lttng-ust-common/fd-tracker.h new file mode 100644 index 00000000..07c13724 --- /dev/null +++ b/src/lib/lttng-ust-common/fd-tracker.h @@ -0,0 +1,13 @@ +/* + * SPDX-License-Identifier: LGPL-2.1-only + * + * Copyright (C) 2021 Michael Jeanson + */ + +#ifndef _LTTNG_UST_COMMON_FD_TRACKER_H +#define _LTTNG_UST_COMMON_FD_TRACKER_H + +void lttng_ust_fd_tracker_init(void) + __attribute__((visibility("hidden"))); + +#endif diff --git a/src/lib/lttng-ust-common/ust-common.c b/src/lib/lttng-ust-common/ust-common.c index cefff67a..e163383d 100644 --- a/src/lib/lttng-ust-common/ust-common.c +++ b/src/lib/lttng-ust-common/ust-common.c @@ -4,18 +4,24 @@ * Copyright (C) 2021 Michael Jeanson */ +#include + #include "common/logging.h" #include "common/ust-fd.h" +#include "common/getenv.h" + +#include "lib/lttng-ust-common/fd-tracker.h" -static -void lttng_ust_common_init(void) - __attribute__((constructor)); -static -void lttng_ust_common_init(void) +/* + * The liblttng-ust-common constructor, initialize the internal shared state. + * Libraries linking on liblttng-ust-common should also call this early in + * their constructor since there is no reliable way to guarantee the execution + * order of constructors across shared library. + */ +void lttng_ust_common_ctor(void) { /* - * Initialize the fd-tracker, other libraries using it should also call - * this in their constructor in case it gets executed before this one. + * Initialize the shared state of the fd tracker. */ - lttng_ust_init_fd_tracker(); + lttng_ust_fd_tracker_init(); } diff --git a/src/lib/lttng-ust-ctl/ustctl.c b/src/lib/lttng-ust-ctl/ustctl.c index 394f1970..75b3a25e 100644 --- a/src/lib/lttng-ust-ctl/ustctl.c +++ b/src/lib/lttng-ust-ctl/ustctl.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "common/logging.h" #include "common/ustcomm.h" @@ -2901,11 +2902,16 @@ int ustctl_counter_clear(struct ustctl_daemon_counter *counter, } static -void ustctl_init(void) +void lttng_ust_ctl_ctor(void) __attribute__((constructor)); static -void ustctl_init(void) +void lttng_ust_ctl_ctor(void) { + /* + * Call the liblttng-ust-common constructor to ensure it runs first. + */ + lttng_ust_common_ctor(); + lttng_ust_clock_init(); lttng_ust_ring_buffer_clients_init(); lttng_ust_counter_clients_init(); diff --git a/src/lib/lttng-ust-fd/Makefile.am b/src/lib/lttng-ust-fd/Makefile.am index 145240d6..23c4d136 100644 --- a/src/lib/lttng-ust-fd/Makefile.am +++ b/src/lib/lttng-ust-fd/Makefile.am @@ -8,6 +8,8 @@ liblttng_ust_fd_la_SOURCES = \ liblttng_ust_fd_la_LIBADD = \ $(top_builddir)/src/lib/lttng-ust/liblttng-ust.la \ + $(top_builddir)/src/lib/lttng-ust-common/liblttng-ust-common.la \ + $(top_builddir)/src/common/libcommon.la \ $(DL_LIBS) liblttng_ust_fd_la_LDFLAGS = -version-info $(LTTNG_UST_LIBRARY_VERSION) diff --git a/src/lib/lttng-ust-fd/lttng-ust-fd.c b/src/lib/lttng-ust-fd/lttng-ust-fd.c index 5efc0acd..56efb457 100644 --- a/src/lib/lttng-ust-fd/lttng-ust-fd.c +++ b/src/lib/lttng-ust-fd/lttng-ust-fd.c @@ -9,14 +9,25 @@ #include #include #include -#include "common/ust-fd.h" #include +#include + #include "common/macros.h" +#include "common/ust-fd.h" static int (*__lttng_ust_fd_plibc_close)(int fd); static int (*__lttng_ust_fd_plibc_fclose)(FILE *stream); +static +void _lttng_ust_fd_ctor(void) + __attribute__((constructor)); +static +void _lttng_ust_fd_ctor(void) +{ + lttng_ust_common_ctor(); +} + static int _lttng_ust_fd_libc_close(int fd) { diff --git a/src/lib/lttng-ust-libc-wrapper/lttng-ust-malloc.c b/src/lib/lttng-ust-libc-wrapper/lttng-ust-malloc.c index a93c7c1a..03069399 100644 --- a/src/lib/lttng-ust-libc-wrapper/lttng-ust-malloc.c +++ b/src/lib/lttng-ust-libc-wrapper/lttng-ust-malloc.c @@ -428,7 +428,7 @@ void lttng_ust_fixup_malloc_nesting_tls(void) asm volatile ("" : : "m" (URCU_TLS(malloc_nesting))); } -void lttng_ust_libc_wrapper_malloc_init(void) +void lttng_ust_libc_wrapper_malloc_ctor(void) { /* Initialization already done */ if (cur_alloc.calloc) { diff --git a/src/lib/lttng-ust-tracepoint/tracepoint.c b/src/lib/lttng-ust-tracepoint/tracepoint.c index e43c1aeb..b84604d1 100644 --- a/src/lib/lttng-ust-tracepoint/tracepoint.c +++ b/src/lib/lttng-ust-tracepoint/tracepoint.c @@ -22,6 +22,7 @@ #include #include /* for LTTNG_UST_ABI_SYM_NAME_LEN */ +#include #include "common/logging.h" #include "common/macros.h" @@ -963,6 +964,7 @@ void lttng_ust_tp_init(void) if (uatomic_xchg(&initialized, 1) == 1) return; lttng_ust_logging_init(); + lttng_ust_common_ctor(); check_weak_hidden(); } diff --git a/src/lib/lttng-ust/lttng-ust-comm.c b/src/lib/lttng-ust/lttng-ust-comm.c index cd5b378c..2f96167e 100644 --- a/src/lib/lttng-ust/lttng-ust-comm.c +++ b/src/lib/lttng-ust/lttng-ust-comm.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include "common/compat/futex.h" #include "common/ustcomm.h" @@ -2061,7 +2062,7 @@ quit: * Weak symbol to call when the ust malloc wrapper is not loaded. */ __attribute__((weak)) -void lttng_ust_libc_wrapper_malloc_init(void) +void lttng_ust_libc_wrapper_malloc_ctor(void) { } @@ -2070,10 +2071,10 @@ void lttng_ust_libc_wrapper_malloc_init(void) * sessiond by polling the application common named pipe. */ static -void lttng_ust_init(void) +void lttng_ust_ctor(void) __attribute__((constructor)); static -void lttng_ust_init(void) +void lttng_ust_ctor(void) { struct timespec constructor_timeout; sigset_t sig_all_blocked, orig_parent_mask; @@ -2131,8 +2132,10 @@ void lttng_ust_init(void) lttng_ust_logging_init(); lttng_ust_getenv_init(); + /* Call the liblttng-ust-common constructor. */ + lttng_ust_common_ctor(); + lttng_ust_tp_init(); - lttng_ust_init_fd_tracker(); lttng_ust_clock_init(); lttng_ust_getcpu_plugin_init(); lttng_ust_statedump_init(); @@ -2142,7 +2145,7 @@ void lttng_ust_init(void) /* * Invoke ust malloc wrapper init before starting other threads. */ - lttng_ust_libc_wrapper_malloc_init(); + lttng_ust_libc_wrapper_malloc_ctor(); timeout_mode = get_constructor_timeout(&constructor_timeout); @@ -2445,7 +2448,7 @@ void lttng_ust_after_fork_parent(sigset_t *restore_sigset) * After fork, in the child, we need to cleanup all the leftover state, * except the worker thread which already magically disappeared thanks * to the weird Linux fork semantics. After tyding up, we call - * lttng_ust_init() again to start over as a new PID. + * lttng_ust_ctor() again to start over as a new PID. * * This is meant for forks() that have tracing in the child between the * fork and following exec call (if there is any). @@ -2466,7 +2469,7 @@ void lttng_ust_after_fork_child(sigset_t *restore_sigset) lttng_ust_cleanup(0); /* Release mutexes and reenable signals */ ust_after_fork_common(restore_sigset); - lttng_ust_init(); + lttng_ust_ctor(); } void lttng_ust_after_setns(void) -- 2.34.1