From d8ed06afceb2d0517633814f7f2a04f69ac71da6 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Mon, 4 Jul 2016 18:54:31 -0400 Subject: [PATCH] Test library load/unload events MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 Signed-off-by: Jérémie Galarneau --- .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 ac78292e8..263b2a05c 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 bcd700109..5230007d4 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 000000000..4ebd6b109 --- /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 000000000..0f8b0bfdc --- /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 0c918b1f0..c03fb2898 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 d6c59aa98..e1b6eac01 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 000000000..c3abc7f97 --- /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 000000000..4bd03012e --- /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 015eee626..e8e4b2641 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 +#include +#include +#include +#include -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 000000000..d489ad4db --- /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 d9bc60a75..e60a65a93 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)) @@ -64,42 +64,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.34.1