[lttng-dev] [PATCH lttng-ust 6/8] Manually dlopen() liblttng-ust.so to prevent unloading

Francis Deslauriers francis.deslauriers at efficios.com
Fri Feb 2 19:48:09 UTC 2018


dlopen() increments the refcount of the library thus preventing the
refcount to reach zero in the case of dlclose;

Signed-off-by: Francis Deslauriers <francis.deslauriers at efficios.com>
---
 configure.ac                  |  1 +
 liblttng-ust/Makefile.am      |  2 ++
 liblttng-ust/lttng-ust-comm.c | 22 ++++++++++++++++++++++
 3 files changed, 25 insertions(+)

diff --git a/configure.ac b/configure.ac
index b0b4157..4fc6f9c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -25,6 +25,7 @@ m4_define([UST_LIB_V_MINOR], [0])
 m4_define([UST_LIB_V_PATCH], [0])
 
 AC_SUBST([LTTNG_UST_LIBRARY_VERSION], [UST_LIB_V_MAJOR:UST_LIB_V_MINOR:UST_LIB_V_PATCH])
+AC_SUBST([LTTNG_UST_LIBRARY_VERSION_MAJOR], [UST_LIB_V_MAJOR])
 # note: remember to update tracepoint.h dlopen() to match this version
 # number. TODO: eventually automate by exporting the major number.
 
diff --git a/liblttng-ust/Makefile.am b/liblttng-ust/Makefile.am
index 982be69..a7edfd5 100644
--- a/liblttng-ust/Makefile.am
+++ b/liblttng-ust/Makefile.am
@@ -60,6 +60,8 @@ liblttng_ust_runtime_la_SOURCES = \
 	string-utils.c \
 	string-utils.h
 
+liblttng_ust_runtime_la_CFLAGS = -DLTTNG_UST_LIBRARY_VERSION_MAJOR=\"$(LTTNG_UST_LIBRARY_VERSION_MAJOR)\"
+
 if HAVE_PERF_EVENT
 liblttng_ust_runtime_la_SOURCES += \
 	lttng-context-perf-counters.c \
diff --git a/liblttng-ust/lttng-ust-comm.c b/liblttng-ust/lttng-ust-comm.c
index 511b9cf..ed912b8 100644
--- a/liblttng-ust/lttng-ust-comm.c
+++ b/liblttng-ust/lttng-ust-comm.c
@@ -27,6 +27,7 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/wait.h>
+#include <dlfcn.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <errno.h>
@@ -59,6 +60,9 @@
 #include "../libringbuffer/getcpu.h"
 #include "getenv.h"
 
+/* Concatenate lttng ust shared library name with its major version number. */
+#define LTTNG_UST_LIB_SO_NAME "liblttng-ust.so." LTTNG_UST_LIBRARY_VERSION_MAJOR
+
 /*
  * Has lttng ust comm constructor been called ?
  */
@@ -1648,6 +1652,7 @@ void __attribute__((constructor)) lttng_ust_init(void)
 	pthread_attr_t thread_attr;
 	int timeout_mode;
 	int ret;
+	void *handle;
 
 	if (uatomic_xchg(&initialized, 1) == 1)
 		return;
@@ -1662,6 +1667,23 @@ void __attribute__((constructor)) lttng_ust_init(void)
 	lttng_ust_loaded = 1;
 
 	/*
+	 * Manually load liblttng-ust.so to increment the dynamic loader's internal
+	 * refcount for 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_SO_NAME library, calling
+	 * dlopen will simply increment the refcount and no additionnal 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 never happen). Do the return value check but discard the
+	 * handle at the end of the function as it's not needed.
+	 */
+	handle = dlopen(LTTNG_UST_LIB_SO_NAME, RTLD_LAZY | RTLD_NODELETE);
+	if (!handle) {
+		ERR("dlopen of liblttng-ust shared library (%s).", LTTNG_UST_LIB_SO_NAME);
+	}
+
+	/*
 	 * We want precise control over the order in which we construct
 	 * our sub-libraries vs starting to receive commands from
 	 * sessiond (otherwise leading to errors when trying to create
-- 
2.7.4



More information about the lttng-dev mailing list