[lttng-dev] [PATCH lttng-ust] Perform the sem_wait on the constructor semaphore just before the main
Jérémie Galarneau
jeremie.galarneau at efficios.com
Sat Nov 15 15:32:33 EST 2014
After discussing this further, we have decided to not merge this patch
since it would prevent us from using dlopen() to load lttng-ust in an
application. While the dlopen() should succeed, there would be no
guarantee that the tracing is active/ready when it returns.
At this point, it seems that the appropriate fix requires a
non-trivial refactor of lttng-ust's registration and initialization
mechanism and threading model.
Jérémie
On Sat, Nov 15, 2014 at 2:18 PM, Mathieu Desnoyers
<mathieu.desnoyers at efficios.com> wrote:
> Can you extend the changelog by any chance, for instance by
> explaining why we need this ? Something along the lines of
> fixing deadlocks involving the glibc internal dynamic loader
> lock would be good.
>
> Thanks,
>
> Mathieu
>
> ----- Original Message -----
>> From: "Jérémie Galarneau" <jeremie.galarneau at efficios.com>
>> To: lttng-dev at lists.lttng.org
>> Cc: "mathieu desnoyers" <mathieu.desnoyers at efficios.com>, "Jérémie Galarneau" <jeremie.galarneau at efficios.com>
>> Sent: Saturday, November 15, 2014 8:12:38 PM
>> Subject: [PATCH lttng-ust] Perform the sem_wait on the constructor semaphore just before the main
>>
>> Signed-off-by: Jérémie Galarneau <jeremie.galarneau at efficios.com>
>> ---
>> liblttng-ust/Makefile.am | 7 ++++
>> liblttng-ust/lttng-ust-comm.c | 75
>> ++++++++++++++++++++++++++++---------------
>> 2 files changed, 56 insertions(+), 26 deletions(-)
>>
>> diff --git a/liblttng-ust/Makefile.am b/liblttng-ust/Makefile.am
>> index e2e1baa..802d32d 100644
>> --- a/liblttng-ust/Makefile.am
>> +++ b/liblttng-ust/Makefile.am
>> @@ -83,4 +83,11 @@ liblttng_ust_la_LIBADD = \
>> liblttng-ust-tracepoint.la \
>> liblttng-ust-runtime.la liblttng-ust-support.la
>>
>> +if LTTNG_UST_BUILD_WITH_LIBDL
>> +liblttng_ust_la_LIBADD += -ldl
>> +endif
>> +if LTTNG_UST_BUILD_WITH_LIBC_DL
>> +liblttng_ust_la_LIBADD += -lc
>> +endif
>> +
>> liblttng_ust_la_CFLAGS = -DUST_COMPONENT="liblttng_ust" -fno-strict-aliasing
>> diff --git a/liblttng-ust/lttng-ust-comm.c b/liblttng-ust/lttng-ust-comm.c
>> index 3df2adc..8258e85 100644
>> --- a/liblttng-ust/lttng-ust-comm.c
>> +++ b/liblttng-ust/lttng-ust-comm.c
>> @@ -20,6 +20,7 @@
>> */
>>
>> #define _LGPL_SOURCE
>> +#define _GNU_SOURCE
>> #include <sys/types.h>
>> #include <sys/socket.h>
>> #include <sys/mman.h>
>> @@ -52,6 +53,7 @@
>> #include "compat.h"
>> #include "../libringbuffer/tlsfixup.h"
>> #include "lttng-ust-baddr.h"
>> +#include <lttng/ust-dlfcn.h>
>>
>> /*
>> * Has lttng ust comm constructor been called ?
>> @@ -1405,10 +1407,8 @@ void lttng_ust_malloc_wrapper_init(void)
>> */
>> void __attribute__((constructor)) lttng_ust_init(void)
>> {
>> - struct timespec constructor_timeout;
>> sigset_t sig_all_blocked, orig_parent_mask;
>> pthread_attr_t thread_attr;
>> - int timeout_mode;
>> int ret;
>>
>> if (uatomic_xchg(&initialized, 1) == 1)
>> @@ -1446,8 +1446,6 @@ void __attribute__((constructor)) lttng_ust_init(void)
>> */
>> lttng_ust_malloc_wrapper_init();
>>
>> - timeout_mode = get_constructor_timeout(&constructor_timeout);
>> -
>> ret = sem_init(&constructor_wait, 0, 0);
>> assert(!ret);
>>
>> @@ -1507,28 +1505,6 @@ void __attribute__((constructor)) lttng_ust_init(void)
>> if (ret) {
>> ERR("pthread_sigmask: %s", strerror(ret));
>> }
>> -
>> - switch (timeout_mode) {
>> - case 1: /* timeout wait */
>> - do {
>> - ret = sem_timedwait(&constructor_wait,
>> - &constructor_timeout);
>> - } while (ret < 0 && errno == EINTR);
>> - if (ret < 0 && errno == ETIMEDOUT) {
>> - ERR("Timed out waiting for lttng-sessiond");
>> - } else {
>> - assert(!ret);
>> - }
>> - break;
>> - case -1:/* wait forever */
>> - do {
>> - ret = sem_wait(&constructor_wait);
>> - } while (ret < 0 && errno == EINTR);
>> - assert(!ret);
>> - break;
>> - case 0: /* no timeout */
>> - break;
>> - }
>> }
>>
>> static
>> @@ -1703,3 +1679,50 @@ void lttng_ust_sockinfo_session_enabled(void *owner)
>> struct sock_info *sock_info = owner;
>> sock_info->statedump_pending = 1;
>> }
>> +
>> +int __libc_start_main(int (*main) (int, char **, char **), int argc,
>> + char **ubp_av, void (*init) (void), void (*fini) (void),
>> + void (*rtld_fini) (void), void (*stack_end))
>> +{
>> + int ret;
>> + int timeout_mode;
>> + struct timespec constructor_timeout;
>> + int (*libc_main_func)(int (*main) (int, char **, char **),
>> + int argc, char **ubp_av, void (*init) (void),
>> + void (*fini) (void), void (*rtld_fini) (void),
>> + void (*stack_end));
>> +
>> + /* Retrieve the original __libc_start_main function */
>> + libc_main_func = dlsym(RTLD_NEXT, "__libc_start_main");
>> + if (libc_main_func == NULL) {
>> + ERR("unable to find \"__libc_start_main\" symbol\n");
>> + errno = ENOSYS;
>> + return -1;
>> + }
>> +
>> + timeout_mode = get_constructor_timeout(&constructor_timeout);
>> + switch (timeout_mode) {
>> + case 1: /* timeout wait */
>> + do {
>> + ret = sem_timedwait(&constructor_wait,
>> + &constructor_timeout);
>> + } while (ret < 0 && errno == EINTR);
>> + if (ret < 0 && errno == ETIMEDOUT) {
>> + ERR("Timed out waiting for lttng-sessiond");
>> + } else {
>> + assert(!ret);
>> + }
>> + break;
>> + case -1:/* wait forever */
>> + do {
>> + ret = sem_wait(&constructor_wait);
>> + } while (ret < 0 && errno == EINTR);
>> + assert(!ret);
>> + break;
>> + case 0: /* no timeout */
>> + break;
>> + }
>> +
>> + /* Call the original function */
>> + return libc_main_func(main, argc, ubp_av, init, fini, rtld_fini,
>> stack_end);
>> +}
>> --
>> 2.1.3
>>
>>
>
> --
> Mathieu Desnoyers
> EfficiOS Inc.
> http://www.efficios.com
--
Jérémie Galarneau
EfficiOS Inc.
http://www.efficios.com
More information about the lttng-dev
mailing list