Fix: ustcomm: application name uses the '-ust'-suffixed thread name
[lttng-ust.git] / src / lib / lttng-ust / lttng-ust-comm.c
index 323ccaea915e8330392c1b1044a23115eec84ca1..2c902dc2737e922204628293e806306fa08e174a 100644 (file)
@@ -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
@@ -854,6 +856,49 @@ end:
        return ret;
 }
 
+static
+void prepare_cmd_reply(struct ustcomm_ust_reply *lur, uint32_t handle, uint32_t cmd, int ret)
+{
+       lur->handle = handle;
+       lur->cmd = cmd;
+       lur->ret_val = ret;
+       if (ret >= 0) {
+               lur->ret_code = LTTNG_UST_OK;
+       } else {
+               /*
+                * Use -LTTNG_UST_ERR as wildcard for UST internal
+                * error that are not caused by the transport, except if
+                * we already have a more precise error message to
+                * report.
+                */
+               if (ret > -LTTNG_UST_ERR) {
+                       /* Translate code to UST error. */
+                       switch (ret) {
+                       case -EEXIST:
+                               lur->ret_code = -LTTNG_UST_ERR_EXIST;
+                               break;
+                       case -EINVAL:
+                               lur->ret_code = -LTTNG_UST_ERR_INVAL;
+                               break;
+                       case -ENOENT:
+                               lur->ret_code = -LTTNG_UST_ERR_NOENT;
+                               break;
+                       case -EPERM:
+                               lur->ret_code = -LTTNG_UST_ERR_PERM;
+                               break;
+                       case -ENOSYS:
+                               lur->ret_code = -LTTNG_UST_ERR_NOSYS;
+                               break;
+                       default:
+                               lur->ret_code = -LTTNG_UST_ERR;
+                               break;
+                       }
+               } else {
+                       lur->ret_code = ret;
+               }
+       }
+}
+
 static
 int handle_message(struct sock_info *sock_info,
                int sock, struct ustcomm_ust_msg *lum)
@@ -878,6 +923,52 @@ int handle_message(struct sock_info *sock_info,
                goto error;
        }
 
+       switch (lum->cmd) {
+       case LTTNG_UST_ABI_FILTER:
+       case LTTNG_UST_ABI_EXCLUSION:
+       case LTTNG_UST_ABI_CHANNEL:
+       case LTTNG_UST_ABI_STREAM:
+       case LTTNG_UST_ABI_CONTEXT:
+               /*
+                * Those commands send additional payload after struct
+                * ustcomm_ust_msg, which makes it pretty much impossible to
+                * deal with "unknown command" errors without leaving the
+                * communication pipe in a out-of-sync state. This is part of
+                * the ABI between liblttng-ust-ctl and liblttng-ust, and
+                * should be fixed on the next breaking
+                * LTTNG_UST_ABI_MAJOR_VERSION protocol bump by indicating the
+                * total command message length as part of a message header so
+                * that the protocol can recover from invalid command errors.
+                */
+               break;
+
+       case LTTNG_UST_ABI_CAPTURE:
+       case LTTNG_UST_ABI_COUNTER:
+       case LTTNG_UST_ABI_COUNTER_GLOBAL:
+       case LTTNG_UST_ABI_COUNTER_CPU:
+       case LTTNG_UST_ABI_EVENT_NOTIFIER_CREATE:
+       case LTTNG_UST_ABI_EVENT_NOTIFIER_GROUP_CREATE:
+               /*
+                * Those commands expect a reply to the struct ustcomm_ust_msg
+                * before sending additional payload.
+                */
+               prepare_cmd_reply(&lur, lum->handle, lum->cmd, 0);
+
+               ret = send_reply(sock, &lur);
+               if (ret < 0) {
+                       DBG("error sending reply");
+                       goto error;
+               }
+               break;
+
+       default:
+               /*
+                * Other commands either don't send additional payload, or are
+                * unknown.
+                */
+               break;
+       }
+
        switch (lum->cmd) {
        case LTTNG_UST_ABI_REGISTER_DONE:
                if (lum->handle == LTTNG_UST_ABI_ROOT_HANDLE)
@@ -1295,44 +1386,8 @@ int handle_message(struct sock_info *sock_info,
                break;
        }
 
-       lur.handle = lum->handle;
-       lur.cmd = lum->cmd;
-       lur.ret_val = ret;
-       if (ret >= 0) {
-               lur.ret_code = LTTNG_UST_OK;
-       } else {
-               /*
-                * Use -LTTNG_UST_ERR as wildcard for UST internal
-                * error that are not caused by the transport, except if
-                * we already have a more precise error message to
-                * report.
-                */
-               if (ret > -LTTNG_UST_ERR) {
-                       /* Translate code to UST error. */
-                       switch (ret) {
-                       case -EEXIST:
-                               lur.ret_code = -LTTNG_UST_ERR_EXIST;
-                               break;
-                       case -EINVAL:
-                               lur.ret_code = -LTTNG_UST_ERR_INVAL;
-                               break;
-                       case -ENOENT:
-                               lur.ret_code = -LTTNG_UST_ERR_NOENT;
-                               break;
-                       case -EPERM:
-                               lur.ret_code = -LTTNG_UST_ERR_PERM;
-                               break;
-                       case -ENOSYS:
-                               lur.ret_code = -LTTNG_UST_ERR_NOSYS;
-                               break;
-                       default:
-                               lur.ret_code = -LTTNG_UST_ERR;
-                               break;
-                       }
-               } else {
-                       lur.ret_code = ret;
-               }
-       }
+       prepare_cmd_reply(&lur, lum->handle, lum->cmd, ret);
+
        if (ret >= 0) {
                switch (lum->cmd) {
                case LTTNG_UST_ABI_TRACER_VERSION:
@@ -1858,7 +1913,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);
@@ -1951,7 +2007,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);
@@ -2047,6 +2103,37 @@ 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.
+ */
+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.
@@ -2076,6 +2163,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
@@ -2094,6 +2189,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);
        }
 
        /*
This page took 0.026425 seconds and 4 git commands to generate.