X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=src%2Flib%2Flttng-ust%2Flttng-ust-comm.c;h=6a1dc37658e9c2e176cb958f785bbc7ea481aadf;hb=f350e97fc52c3b50f87493d28b41cbadd7db2e95;hp=5330e5c2a0c9ed2c6e63170203cc862d80199075;hpb=662d05907560345f06a19463ce5bf24ca72a442c;p=lttng-ust.git diff --git a/src/lib/lttng-ust/lttng-ust-comm.c b/src/lib/lttng-ust/lttng-ust-comm.c index 5330e5c2..6a1dc376 100644 --- a/src/lib/lttng-ust/lttng-ust-comm.c +++ b/src/lib/lttng-ust/lttng-ust-comm.c @@ -1,7 +1,7 @@ /* * SPDX-License-Identifier: LGPL-2.1-only * - * Copyright (C) 2011 David Goulet + * Copyright (C) 2011 EfficiOS Inc. * Copyright (C) 2011 Mathieu Desnoyers */ @@ -38,6 +38,7 @@ #include #include #include +#include #include #include "lib/lttng-ust/futex.h" #include "common/ustcomm.h" @@ -125,14 +126,10 @@ int lttng_ust_loaded __attribute__((weak)); int ust_lock(void) { sigset_t sig_all_blocked, orig_mask; - int ret, oldstate; + int ret; - ret = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate); - if (ret) { - ERR("pthread_setcancelstate: %s", strerror(ret)); - } - if (oldstate != PTHREAD_CANCEL_ENABLE) { - ERR("pthread_setcancelstate: unexpected oldstate"); + if (lttng_ust_cancelstate_disable_push()) { + ERR("lttng_ust_cancelstate_disable_push"); } sigfillset(&sig_all_blocked); ret = pthread_sigmask(SIG_SETMASK, &sig_all_blocked, &orig_mask); @@ -161,14 +158,10 @@ int ust_lock(void) void ust_lock_nocheck(void) { sigset_t sig_all_blocked, orig_mask; - int ret, oldstate; + int ret; - ret = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate); - if (ret) { - ERR("pthread_setcancelstate: %s", strerror(ret)); - } - if (oldstate != PTHREAD_CANCEL_ENABLE) { - ERR("pthread_setcancelstate: unexpected oldstate"); + if (lttng_ust_cancelstate_disable_push()) { + ERR("lttng_ust_cancelstate_disable_push"); } sigfillset(&sig_all_blocked); ret = pthread_sigmask(SIG_SETMASK, &sig_all_blocked, &orig_mask); @@ -189,7 +182,7 @@ void ust_lock_nocheck(void) void ust_unlock(void) { sigset_t sig_all_blocked, orig_mask; - int ret, oldstate; + int ret; sigfillset(&sig_all_blocked); ret = pthread_sigmask(SIG_SETMASK, &sig_all_blocked, &orig_mask); @@ -202,12 +195,8 @@ void ust_unlock(void) if (ret) { ERR("pthread_sigmask: %s", strerror(ret)); } - ret = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate); - if (ret) { - ERR("pthread_setcancelstate: %s", strerror(ret)); - } - if (oldstate != PTHREAD_CANCEL_DISABLE) { - ERR("pthread_setcancelstate: unexpected oldstate"); + if (lttng_ust_cancelstate_disable_pop()) { + ERR("lttng_ust_cancelstate_disable_pop"); } } @@ -259,7 +248,7 @@ struct sock_info { int statedump_pending; int initial_statedump_done; /* Keep procname for statedump */ - char procname[LTTNG_UST_ABI_PROCNAME_LEN]; + char procname[LTTNG_UST_CONTEXT_PROCNAME_LEN]; }; /* Socket from app (connect) to session daemon (listen) for communication */ @@ -482,7 +471,7 @@ int setup_global_apps(void) } global_apps.allowed = 1; - lttng_pthread_getname_np(global_apps.procname, LTTNG_UST_ABI_PROCNAME_LEN); + lttng_pthread_getname_np(global_apps.procname, LTTNG_UST_CONTEXT_PROCNAME_LEN); error: return ret; } @@ -528,7 +517,7 @@ int setup_local_apps(void) goto end; } - lttng_pthread_getname_np(local_apps.procname, LTTNG_UST_ABI_PROCNAME_LEN); + lttng_pthread_getname_np(local_apps.procname, LTTNG_UST_CONTEXT_PROCNAME_LEN); end: return ret; } @@ -620,7 +609,8 @@ void get_allow_blocking(void) } static -int register_to_sessiond(int socket, enum lttng_ust_ctl_socket_type type) +int register_to_sessiond(int socket, enum lttng_ust_ctl_socket_type type, + const char *procname) { return ustcomm_send_reg_msg(socket, type, @@ -629,7 +619,8 @@ int register_to_sessiond(int socket, enum lttng_ust_ctl_socket_type type) lttng_ust_rb_alignof(uint16_t) * CHAR_BIT, lttng_ust_rb_alignof(uint32_t) * CHAR_BIT, lttng_ust_rb_alignof(uint64_t) * CHAR_BIT, - lttng_ust_rb_alignof(unsigned long) * CHAR_BIT); + lttng_ust_rb_alignof(unsigned long) * CHAR_BIT, + procname); } static @@ -1457,8 +1448,7 @@ void cleanup_sock_info(struct sock_info *sock_info, int exiting) } sock_info->root_handle = -1; } - sock_info->registration_done = 0; - sock_info->initial_statedump_done = 0; + /* * wait_shm_mmap, socket and notify socket are used by listener @@ -1470,6 +1460,9 @@ void cleanup_sock_info(struct sock_info *sock_info, int exiting) if (exiting) return; + sock_info->registration_done = 0; + sock_info->initial_statedump_done = 0; + if (sock_info->socket != -1) { ret = ustcomm_close_unix_sock(sock_info->socket); if (ret) { @@ -1911,7 +1904,8 @@ restart: sock_info->root_handle = ret; } - ret = register_to_sessiond(sock_info->socket, LTTNG_UST_CTL_SOCKET_CMD); + ret = register_to_sessiond(sock_info->socket, LTTNG_UST_CTL_SOCKET_CMD, + sock_info->procname); if (ret < 0) { ERR("Error registering to %s ust cmd socket", sock_info->name); @@ -2004,7 +1998,7 @@ restart: } ret = register_to_sessiond(sock_info->notify_socket, - LTTNG_UST_CTL_SOCKET_NOTIFY); + LTTNG_UST_CTL_SOCKET_NOTIFY, sock_info->procname); if (ret < 0) { ERR("Error registering to %s ust notify socket", sock_info->name); @@ -2100,6 +2094,41 @@ void lttng_ust_libc_wrapper_malloc_ctor(void) { } +/* + * Use a symbol of the previous ABI to detect if liblttng-ust.so.0 is loaded in + * the current process. + */ +#define LTTNG_UST_SONAME_0_SYM "ltt_probe_register" + +static +void lttng_ust_check_soname_0(void) +{ + if (!dlsym(RTLD_DEFAULT, LTTNG_UST_SONAME_0_SYM)) + return; + + CRIT("Incompatible library ABIs detected within the same process. " + "The process is likely linked against different major soname of LTTng-UST which is unsupported. " + "The detection was triggered by lookup of ABI 0 symbol \"%s\" in the Global Symbol Table\n", + LTTNG_UST_SONAME_0_SYM); +} + +/* + * Expose a canary symbol of the previous ABI to ensure we catch uses of a + * liblttng-ust.so.0 dlopen'd after .so.1 has been loaded. Use a different + * symbol than the detection code to ensure we don't detect ourself. + * + * This scheme will only work on systems where the global symbol table has + * priority when resolving the symbols of a dlopened shared object, which is + * the case on Linux but not on FreeBSD. + */ +void init_usterr(void); +void init_usterr(void) +{ + CRIT("Incompatible library ABIs detected within the same process. " + "The process is likely linked against different major soname of LTTng-UST which is unsupported. " + "The detection was triggered by canary symbol \"%s\"\n", __func__); +} + /* * sessiond monitoring thread: monitor presence of global and per-user * sessiond by polling the application common named pipe. @@ -2129,6 +2158,14 @@ void lttng_ust_ctor(void) lttng_ust_loaded = 1; + /* + * Check if we find a symbol of the previous ABI in the current process + * as different ABIs of liblttng-ust can't co-exist in a process. If we + * do so, emit a critical log message which will also abort if the + * LTTNG_UST_ABORT_ON_CRITICAL environment variable is set. + */ + lttng_ust_check_soname_0(); + /* * We need to ensure that the liblttng-ust library is not unloaded to avoid * the unloading of code used by the ust_listener_threads as we can not @@ -2147,6 +2184,8 @@ void lttng_ust_ctor(void) handle = dlopen(LTTNG_UST_LIB_SONAME, RTLD_LAZY | RTLD_NODELETE); if (!handle) { ERR("dlopen of liblttng-ust shared library (%s).", LTTNG_UST_LIB_SONAME); + } else { + DBG("dlopened liblttng-ust shared library (%s).", LTTNG_UST_LIB_SONAME); } /*