[lttng-dev] [RFC PATCH lttng-tools] Test library load/unload events
Jérémie Galarneau
jeremie.galarneau at efficios.com
Tue Jul 5 03:00:31 UTC 2016
Looks good to me!
Jérémie
On Mon, Jul 4, 2016 at 6:54 PM, Mathieu Desnoyers
<mathieu.desnoyers at efficios.com> wrote:
> 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
>
--
Jérémie Galarneau
EfficiOS Inc.
http://www.efficios.com
More information about the lttng-dev
mailing list