[lttng-dev] [RFC PATCH lttng-tools] Test library load/unload events

Mathieu Desnoyers mathieu.desnoyers at efficios.com
Mon Jul 4 22:54:31 UTC 2016


Test the lttng_ust_lib:load, lttng_ust_lib:build_id,
lttng_ust_lib:debug_link, and lttng_ust_lib:unload events from
lttng-ust, which track the state of loaded libraries. This ensures we
correctly handle dlopen of libraries with direct dependencies.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
---
 .gitignore                                 |  1 +
 tests/regression/ust/ust-dl/Makefile.am    | 33 +++++++++++--
 tests/regression/ust/ust-dl/libbar.c       |  6 +++
 tests/regression/ust/ust-dl/libbar.h       |  6 +++
 tests/regression/ust/ust-dl/libfoo.c       |  4 +-
 tests/regression/ust/ust-dl/libfoo.h       |  2 +-
 tests/regression/ust/ust-dl/libzzz.c       |  6 +++
 tests/regression/ust/ust-dl/libzzz.h       |  6 +++
 tests/regression/ust/ust-dl/prog.c         | 72 ++++++++++++++++++++++++---
 tests/regression/ust/ust-dl/run.sh         |  3 ++
 tests/regression/ust/ust-dl/test_ust-dl.py | 78 +++++++++++++++++++++++-------
 11 files changed, 185 insertions(+), 32 deletions(-)
 create mode 100644 tests/regression/ust/ust-dl/libbar.c
 create mode 100644 tests/regression/ust/ust-dl/libbar.h
 create mode 100644 tests/regression/ust/ust-dl/libzzz.c
 create mode 100644 tests/regression/ust/ust-dl/libzzz.h
 create mode 100755 tests/regression/ust/ust-dl/run.sh

diff --git a/.gitignore b/.gitignore
index ac78292..263b2a0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -102,6 +102,7 @@ tests/regression/ust/python-logging/test_python_logging
 /tests/regression/ust/type-declarations/type-declarations
 /tests/regression/ust/ust-dl/prog
 /tests/regression/ust/ust-dl/libfoo.so.debug
+/tests/regression/ust/ust-dl/libbar.so.debug
 /tests/utils/testapp/gen-ust-nevents/gen-ust-nevents
 /tests/utils/testapp/gen-ust-tracef/gen-ust-tracef
 /tests/regression/tools/live/live_test
diff --git a/tests/regression/ust/ust-dl/Makefile.am b/tests/regression/ust/ust-dl/Makefile.am
index bcd7001..5230007 100644
--- a/tests/regression/ust/ust-dl/Makefile.am
+++ b/tests/regression/ust/ust-dl/Makefile.am
@@ -2,10 +2,11 @@ if NO_SHARED
 # Do not build this test if shared libraries support was
 # explicitly disabled.
 
-CLEANFILES = libfoo.so libfoo.so.debug prog
+CLEANFILES = libfoo.so libfoo.so.debug libbar.so libbar.so.debug \
+	libzzz.so libzzz.so.debug prog
 
 EXTRA_DIST = test_ust-dl test_ust-dl.py libfoo.c libfoo.h \
-	prog.c
+	libbar.c libbar.h libzzz.c libzzz.h prog.c
 
 else
 
@@ -19,26 +20,48 @@ noinst_PROGRAMS = prog
 prog_SOURCES = prog.c
 prog_LDADD = -ldl
 
-noinst_LTLIBRARIES = libfoo.la
+noinst_LTLIBRARIES = libzzz.la libbar.la libfoo.la
+
+libzzz_la_SOURCES = libzzz.c libzzz.h
+libzzz_la_LDFLAGS = -module -shared -avoid-version \
+		-rpath $(abs_builddir)
+
+libbar_la_SOURCES = libbar.c libbar.h
+libbar_la_LDFLAGS = -module -shared -avoid-version \
+		-rpath $(abs_builddir)
+libbar_la_LIBADD = libzzz.la
+
 libfoo_la_SOURCES = libfoo.c libfoo.h
 libfoo_la_LDFLAGS = -module -shared -avoid-version \
 		-rpath $(abs_builddir)
+libfoo_la_LIBADD = libbar.la
 
-CLEANFILES = libfoo.so libfoo.so.debug
+CLEANFILES = libfoo.so libfoo.so.debug libbar.so libbar.so.debug \
+	libzzz.so libzzz.so.debug
 
 # Extract debug symbols
 libfoo.so.debug: libfoo.la
 	$(objcopy_verbose)$(OBJCOPY) --only-keep-debug .libs/libfoo.so libfoo.so.debug
+libbar.so.debug: libbar.la
+	$(objcopy_verbose)$(OBJCOPY) --only-keep-debug .libs/libbar.so libbar.so.debug
+libzzz.so.debug: libzzz.la
+	$(objcopy_verbose)$(OBJCOPY) --only-keep-debug .libs/libzzz.so libzzz.so.debug
 
 # Strip and add debuglink
 libfoo.so: libfoo.so.debug
 	@cp -f .libs/libfoo.so libfoo.so
 	$(objcopy_verbose)$(OBJCOPY) --strip-debug --add-gnu-debuglink=libfoo.so.debug libfoo.so
+libbar.so: libbar.so.debug
+	@cp -f .libs/libbar.so libbar.so
+	$(objcopy_verbose)$(OBJCOPY) --strip-debug --add-gnu-debuglink=libbar.so.debug libbar.so
+libzzz.so: libzzz.so.debug
+	@cp -f .libs/libzzz.so libzzz.so
+	$(objcopy_verbose)$(OBJCOPY) --strip-debug --add-gnu-debuglink=libzzz.so.debug libzzz.so
 
 noinst_SCRIPTS = test_ust-dl test_ust-dl.py
 EXTRA_DIST = test_ust-dl test_ust-dl.py
 
-all-local: libfoo.so
+all-local: libfoo.so libbar.so libzzz.so
 	@if [ x"$(srcdir)" != x"$(builddir)" ]; then \
 		for script in $(EXTRA_DIST); do \
 			cp -f $(srcdir)/$$script $(builddir); \
diff --git a/tests/regression/ust/ust-dl/libbar.c b/tests/regression/ust/ust-dl/libbar.c
new file mode 100644
index 0000000..4ebd6b1
--- /dev/null
+++ b/tests/regression/ust/ust-dl/libbar.c
@@ -0,0 +1,6 @@
+#include "libbar.h"
+
+int bar(void)
+{
+	return 1;
+}
diff --git a/tests/regression/ust/ust-dl/libbar.h b/tests/regression/ust/ust-dl/libbar.h
new file mode 100644
index 0000000..0f8b0bf
--- /dev/null
+++ b/tests/regression/ust/ust-dl/libbar.h
@@ -0,0 +1,6 @@
+#ifndef _LIBBAR_H
+#define _LIBBAR_H
+
+int bar(void);
+
+#endif  /* _LIBBAR_H */
diff --git a/tests/regression/ust/ust-dl/libfoo.c b/tests/regression/ust/ust-dl/libfoo.c
index 0c918b1..c03fb28 100644
--- a/tests/regression/ust/ust-dl/libfoo.c
+++ b/tests/regression/ust/ust-dl/libfoo.c
@@ -1,6 +1,8 @@
 #include "libfoo.h"
+#include "libbar.h"
 
-int foo()
+int foo(void)
 {
+	bar();
 	return 1;
 }
diff --git a/tests/regression/ust/ust-dl/libfoo.h b/tests/regression/ust/ust-dl/libfoo.h
index d6c59aa..e1b6eac 100644
--- a/tests/regression/ust/ust-dl/libfoo.h
+++ b/tests/regression/ust/ust-dl/libfoo.h
@@ -1,6 +1,6 @@
 #ifndef _LIBFOO_H
 #define _LIBFOO_H
 
-int foo();
+int foo(void);
 
 #endif  /* _LIBFOO_H */
diff --git a/tests/regression/ust/ust-dl/libzzz.c b/tests/regression/ust/ust-dl/libzzz.c
new file mode 100644
index 0000000..c3abc7f
--- /dev/null
+++ b/tests/regression/ust/ust-dl/libzzz.c
@@ -0,0 +1,6 @@
+#include "libzzz.h"
+
+int zzz(void)
+{
+	return 1;
+}
diff --git a/tests/regression/ust/ust-dl/libzzz.h b/tests/regression/ust/ust-dl/libzzz.h
new file mode 100644
index 0000000..4bd0301
--- /dev/null
+++ b/tests/regression/ust/ust-dl/libzzz.h
@@ -0,0 +1,6 @@
+#ifndef _LIBZZZ_H
+#define _LIBZZZ_H
+
+int zzz(void);
+
+#endif  /* _LIBZZZ_H */
diff --git a/tests/regression/ust/ust-dl/prog.c b/tests/regression/ust/ust-dl/prog.c
index 015eee6..e8e4b26 100644
--- a/tests/regression/ust/ust-dl/prog.c
+++ b/tests/regression/ust/ust-dl/prog.c
@@ -1,16 +1,72 @@
+/* _GNU_SOURCE is defined by config.h */
 #include <dlfcn.h>
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
 
-int main()
+/*
+ * libfoo has a direct dependency on libbar.
+ * libbar has a direct dependency on libzzz.
+ * This test is therefore a mix of dlopen/dlclose and dlmopen/dlclose of
+ * libfoo, and of its direct dependencies.
+ */
+int main(int argc, char **argv)
 {
-	void *handle;
-	int (*foo)();
+	void *h0, *h1, *h2, *h3, *h4;
+	char *error;
+	int (*foo)(void);
 
-	handle = dlopen("libfoo.so", RTLD_LAZY);
-	foo = dlsym(handle, "foo");
+	h0 = dlopen("libbar.so", RTLD_LAZY);
+	if (!h0) {
+		goto get_error;
+	}
+	h1 = dlmopen(LM_ID_BASE, "libfoo.so", RTLD_LAZY);
+	if (!h1) {
+		goto get_error;
+	}
+	h2 = dlopen("libzzz.so", RTLD_LAZY);
+	if (!h2) {
+		goto get_error;
+	}
+	h3 = dlopen("libfoo.so", RTLD_LAZY);
+	if (!h3) {
+		goto get_error;
+	}
+	h4 = dlopen("libfoo.so", RTLD_LAZY);
+	if (!h4) {
+		goto get_error;
+	}
 
-	(*foo)();
+	foo = dlsym(h1, "foo");
+	error = dlerror();
+	if (error != NULL) {
+		goto error;
+	}
 
-	dlclose(handle);
+	foo();
 
-	return 0;
+	if (dlclose(h0)) {
+		goto get_error;
+	}
+	if (dlclose(h1)) {
+		goto get_error;
+	}
+	if (dlclose(h2)) {
+		goto get_error;
+	}
+	if (dlclose(h3)) {
+		goto get_error;
+	}
+	if (dlclose(h4)) {
+		goto get_error;
+	}
+
+	exit(EXIT_SUCCESS);
+
+get_error:
+	error = dlerror();
+error:
+	fprintf(stderr, "%s\n", error);
+	exit(EXIT_FAILURE);
 }
diff --git a/tests/regression/ust/ust-dl/run.sh b/tests/regression/ust/ust-dl/run.sh
new file mode 100755
index 0000000..d489ad4
--- /dev/null
+++ b/tests/regression/ust/ust-dl/run.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+LD_PRELOAD=liblttng-ust-dl.so LD_LIBRARY_PATH=. ./prog
diff --git a/tests/regression/ust/ust-dl/test_ust-dl.py b/tests/regression/ust/ust-dl/test_ust-dl.py
index 9801012..5999da3 100644
--- a/tests/regression/ust/ust-dl/test_ust-dl.py
+++ b/tests/regression/ust/ust-dl/test_ust-dl.py
@@ -31,7 +31,7 @@ sys.path.append(test_utils_path)
 from test_utils import *
 
 
-NR_TESTS = 6
+NR_TESTS = 11
 current_test = 1
 print("1..{0}".format(NR_TESTS))
 
@@ -72,42 +72,86 @@ try:
 except FileNotFoundError:
     bail("Could not open babeltrace. Please make sure it is installed.", session_info)
 
-dlopen_event_found = False
-build_id_event_found = False
-debug_link_event_found = False
-dlclose_event_found = False
+dlopen_event_found = 0
+dlmopen_event_found = 0
+build_id_event_found = 0
+debug_link_event_found = 0
+dlclose_event_found = 0
+load_event_found = 0
+load_build_id_event_found = 0
+load_debug_link_event_found = 0
+unload_event_found = 0
+load_libfoo_found = 0
+load_libbar_found = 0
+load_libzzz_found = 0
 
 for event_line in babeltrace_process.stdout:
-    # Let babeltrace finish to get the return code
-    if dlopen_event_found and build_id_event_found and \
-       debug_link_event_found and dlclose_event_found:
-        continue
 
     event_line = event_line.decode('utf-8').replace("\n", "")
     if re.search(r".*lttng_ust_dl:dlopen.*", event_line) is not None:
-        dlopen_event_found = True
+        dlopen_event_found += 1
+    elif re.search(r".*lttng_ust_dl:dlmopen.*", event_line) is not None:
+        dlmopen_event_found += 1
     elif re.search(r".*lttng_ust_dl:build_id.*", event_line) is not None:
-        build_id_event_found = True
+        build_id_event_found += 1
     elif re.search(r".*lttng_ust_dl:debug_link.*", event_line) is not None:
-        debug_link_event_found = True
+        debug_link_event_found += 1
     elif re.search(r".*lttng_ust_dl:dlclose.*", event_line) is not None:
-        dlclose_event_found = True
+        dlclose_event_found += 1
+    elif re.search(r".*lttng_ust_lib:build_id.*", event_line) is not None:
+        load_build_id_event_found += 1
+    elif re.search(r".*lttng_ust_lib:debug_link.*", event_line) is not None:
+        load_debug_link_event_found += 1
+    elif re.search(r".*lttng_ust_lib:unload.*", event_line) is not None:
+        unload_event_found += 1
+    elif re.search(r".*lttng_ust_lib:load.*", event_line) is not None:
+        load_event_found += 1
+        if re.search(r".*lttng_ust_lib:load.*libfoo.*", event_line) is not None:
+            load_libfoo_found += 1
+        elif re.search(r".*lttng_ust_lib:load.*libbar.*", event_line) is not None:
+            load_libbar_found += 1
+        elif re.search(r".*lttng_ust_lib:load.*libzzz.*", event_line) is not None:
+            load_libzzz_found += 1
 
 babeltrace_process.wait()
 
 print_test_result(babeltrace_process.returncode == 0, current_test, "Resulting trace is readable")
 current_test += 1
 
-print_test_result(dlopen_event_found, current_test, "lttng_ust_dl:dlopen event found in resulting trace")
+print_test_result(dlopen_event_found > 0, current_test, "lttng_ust_dl:dlopen event found in resulting trace")
 current_test += 1
 
-print_test_result(build_id_event_found, current_test, "lttng_ust_dl:build_id event found in resulting trace")
+print_test_result(dlmopen_event_found > 0, current_test, "lttng_ust_dl:dlmopen event found in resulting trace")
 current_test += 1
 
-print_test_result(debug_link_event_found, current_test, "lttng_ust_dl:debug_link event found in resulting trace")
+print_test_result(build_id_event_found > 0, current_test, "lttng_ust_dl:build_id event found in resulting trace")
 current_test += 1
 
-print_test_result(dlclose_event_found, current_test, "lttng_ust_dl:dlclose event found in resulting trace")
+print_test_result(debug_link_event_found > 0, current_test, "lttng_ust_dl:debug_link event found in resulting trace")
+current_test += 1
+
+print_test_result(dlclose_event_found > 0, current_test, "lttng_ust_dl:dlclose event found in resulting trace")
+current_test += 1
+
+print_test_result(load_event_found > 0, current_test, "lttng_ust_lib:load event found in resulting trace")
+current_test += 1
+
+print_test_result(load_build_id_event_found > 0, current_test, "lttng_ust_lib:build_id event found in resulting trace")
+current_test += 1
+
+print_test_result(load_debug_link_event_found > 0, current_test, "lttng_ust_lib:debug_link event found in resulting trace")
+current_test += 1
+
+print_test_result(unload_event_found == 3, current_test, "lttng_ust_lib:unload event found 3 times in resulting trace")
+current_test += 1
+
+print_test_result(load_libfoo_found == 1, current_test, "lttng_ust_lib:load libfoo.so event found once in resulting trace")
+current_test += 1
+
+print_test_result(load_libbar_found == 1, current_test, "lttng_ust_lib:load libbar.so event found once in resulting trace")
+current_test += 1
+
+print_test_result(load_libzzz_found == 1, current_test, "lttng_ust_lib:load libzzz.so event found once in resulting trace")
 current_test += 1
 
 shutil.rmtree(session_info.tmp_directory)
-- 
2.1.4



More information about the lttng-dev mailing list