+/*
+ * 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__);
+}
+