Fix: abort on decrement_sem_count during concurrent tracing start and teardown
[lttng-ust.git] / src / lib / lttng-ust / lttng-ust-comm.c
index 5330e5c2a0c9ed2c6e63170203cc862d80199075..25d79d9f4dce4fc7f3f4518e796e270fa8fcf78a 100644 (file)
@@ -259,7 +259,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 +482,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 +528,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 +620,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 +630,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 +1459,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 +1471,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 +1915,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 +2009,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 +2105,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 +2169,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
@@ -2137,7 +2185,7 @@ void lttng_ust_ctor(void)
         * this library so it never becomes zero, thus never gets unloaded from the
         * address space of the process. Since we are already running in the
         * constructor of the LTTNG_UST_LIB_SONAME library, calling dlopen will
-        * simply increment the refcount and no additionnal work is needed by the
+        * simply increment the refcount and no additional work is needed by the
         * dynamic loader as the shared library is already loaded in the address
         * space. As a safe guard, we use the RTLD_NODELETE flag to prevent
         * unloading of the UST library if its refcount becomes zero (which should
@@ -2147,6 +2195,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);
        }
 
        /*
@@ -2472,7 +2522,7 @@ void lttng_ust_after_fork_parent(sigset_t *restore_sigset)
                return;
        DBG("process %d", getpid());
        lttng_ust_urcu_after_fork_parent();
-       /* Release mutexes and reenable signals */
+       /* Release mutexes and re-enable signals */
        ust_after_fork_common(restore_sigset);
 }
 
@@ -2499,7 +2549,7 @@ void lttng_ust_after_fork_child(sigset_t *restore_sigset)
        /* Release urcu mutexes */
        lttng_ust_urcu_after_fork_child();
        lttng_ust_cleanup(0);
-       /* Release mutexes and reenable signals */
+       /* Release mutexes and re-enable signals */
        ust_after_fork_common(restore_sigset);
        lttng_ust_ctor();
 }
This page took 0.044203 seconds and 4 git commands to generate.