From c70c42cca32058806a5c7d96d7cf2fae4d4fb75f Mon Sep 17 00:00:00 2001 From: Antoine Busque Date: Tue, 4 Aug 2015 17:55:12 -0400 Subject: [PATCH] Test: add UST dl helper test MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Antoine Busque Signed-off-by: Jérémie Galarneau --- .gitignore | 1 + configure.ac | 1 + tests/regression/ust/Makefile.am | 2 +- tests/regression/ust/ust-dl/Makefile.am | 31 ++++++ tests/regression/ust/ust-dl/README | 28 +++++ tests/regression/ust/ust-dl/libfoo.c | 6 ++ tests/regression/ust/ust-dl/libfoo.h | 6 ++ tests/regression/ust/ust-dl/prog.c | 16 +++ tests/regression/ust/ust-dl/test_ust-dl | 27 +++++ tests/regression/ust/ust-dl/test_ust-dl.py | 113 +++++++++++++++++++++ tests/with_bindings_regression | 1 + 11 files changed, 231 insertions(+), 1 deletion(-) create mode 100644 tests/regression/ust/ust-dl/Makefile.am create mode 100644 tests/regression/ust/ust-dl/README create mode 100644 tests/regression/ust/ust-dl/libfoo.c create mode 100644 tests/regression/ust/ust-dl/libfoo.h create mode 100644 tests/regression/ust/ust-dl/prog.c create mode 100755 tests/regression/ust/ust-dl/test_ust-dl create mode 100644 tests/regression/ust/ust-dl/test_ust-dl.py diff --git a/.gitignore b/.gitignore index 295b69677..0efccfa9e 100644 --- a/.gitignore +++ b/.gitignore @@ -95,6 +95,7 @@ health_check tests/regression/ust/python-logging/test_python_logging /tests/regression/ust/baddr-statedump/prog /tests/regression/ust/baddr-statedump/prog.debug +/tests/regression/ust/ust-dl/prog /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/configure.ac b/configure.ac index d7bac224d..9cc411ea0 100644 --- a/configure.ac +++ b/configure.ac @@ -806,6 +806,7 @@ AC_CONFIG_FILES([ tests/regression/ust/fork/Makefile tests/regression/ust/libc-wrapper/Makefile tests/regression/ust/baddr-statedump/Makefile + tests/regression/ust/ust-dl/Makefile tests/regression/ust/java-jul/Makefile tests/regression/ust/java-log4j/Makefile tests/regression/ust/python-logging/Makefile diff --git a/tests/regression/ust/Makefile.am b/tests/regression/ust/Makefile.am index 01404f7dc..9fcbda6d9 100644 --- a/tests/regression/ust/Makefile.am +++ b/tests/regression/ust/Makefile.am @@ -2,7 +2,7 @@ if HAVE_LIBLTTNG_UST_CTL SUBDIRS = nprocesses high-throughput low-throughput before-after multi-session \ overlap buffers-pid linking daemon exit-fast fork libc-wrapper \ periodical-metadata-flush java-jul java-log4j python-logging \ - getcpu-override clock-override baddr-statedump + getcpu-override clock-override baddr-statedump ust-dl EXTRA_DIST = test_event_basic test_event_tracef test_event_perf diff --git a/tests/regression/ust/ust-dl/Makefile.am b/tests/regression/ust/ust-dl/Makefile.am new file mode 100644 index 000000000..4893a97e4 --- /dev/null +++ b/tests/regression/ust/ust-dl/Makefile.am @@ -0,0 +1,31 @@ +AM_CPPFLAGS = -I$(srcdir) -g + +noinst_PROGRAMS = prog +prog_SOURCES = prog.c +prog_LDADD = -ldl + +noinst_LTLIBRARIES = libfoo.la +libfoo_la_SOURCES = libfoo.c libfoo.h +libfoo_la_LDFLAGS = -module -shared -avoid-version \ + -rpath $(abs_builddir) + +noinst_SCRIPTS = test_ust-dl test_ust-dl.py +EXTRA_DIST = test_ust-dl test_ust-dl.py + +all-local: libfoo.la + @if [ x"$(srcdir)" != x"$(builddir)" ]; then \ + for script in $(EXTRA_DIST); do \ + cp -f $(srcdir)/$$script $(builddir); \ + done; \ + fi + objcopy --only-keep-debug .libs/libfoo.so .libs/libfoo.so.debug + strip -g .libs/libfoo.so + objcopy --add-gnu-debuglink .libs/libfoo.so.debug .libs/libfoo.so + +clean-local: + @if [ x"$(srcdir)" != x"$(builddir)" ]; then \ + for script in $(EXTRA_DIST); do \ + rm -f $(builddir)/$$script; \ + done; \ + fi + rm -f .libs/libfoo.so.debug diff --git a/tests/regression/ust/ust-dl/README b/tests/regression/ust/ust-dl/README new file mode 100644 index 000000000..1db35a6ba --- /dev/null +++ b/tests/regression/ust/ust-dl/README @@ -0,0 +1,28 @@ +UST dynamic linker tracing test +------------------------------- + +This test verifies that the `liblttng-ust-dl.so` helper works as +intended. Indeed, once preloaded, this helper should produce events +for all calls made by the application to dlopen along with with extra +debug information for the given shared object, such as build id or +debug link if it exists, as well as dlclose. + + +DESCRIPTION +----------- + +The test application is run with the environment variable +LD_PRELOAD="liblttng-ust-dl.so" to preload the helper. It then dlopens +a shared library (`libfoo.so`), calls a function from it, and dlclose +it. This should produce `dlopen` and `dlclose` events, as well as +`build_id` and `debug_link`, because the shared library has been built +to contain all this extra debug information. + +DEPENDENCIES +------------ + +To run this test, you will need: + + - lttng-tools (with python bindings) + - babeltrace + - python 3.0 or later diff --git a/tests/regression/ust/ust-dl/libfoo.c b/tests/regression/ust/ust-dl/libfoo.c new file mode 100644 index 000000000..0c918b1f0 --- /dev/null +++ b/tests/regression/ust/ust-dl/libfoo.c @@ -0,0 +1,6 @@ +#include "libfoo.h" + +int foo() +{ + return 1; +} diff --git a/tests/regression/ust/ust-dl/libfoo.h b/tests/regression/ust/ust-dl/libfoo.h new file mode 100644 index 000000000..d6c59aa98 --- /dev/null +++ b/tests/regression/ust/ust-dl/libfoo.h @@ -0,0 +1,6 @@ +#ifndef _LIBFOO_H +#define _LIBFOO_H + +int foo(); + +#endif /* _LIBFOO_H */ diff --git a/tests/regression/ust/ust-dl/prog.c b/tests/regression/ust/ust-dl/prog.c new file mode 100644 index 000000000..015eee626 --- /dev/null +++ b/tests/regression/ust/ust-dl/prog.c @@ -0,0 +1,16 @@ +#include + +int main() +{ + void *handle; + int (*foo)(); + + handle = dlopen("libfoo.so", RTLD_LAZY); + foo = dlsym(handle, "foo"); + + (*foo)(); + + dlclose(handle); + + return 0; +} diff --git a/tests/regression/ust/ust-dl/test_ust-dl b/tests/regression/ust/ust-dl/test_ust-dl new file mode 100755 index 000000000..4794745b5 --- /dev/null +++ b/tests/regression/ust/ust-dl/test_ust-dl @@ -0,0 +1,27 @@ +#!/bin/sh +# +# Copyright (C) - 2013 Jérémie Galarneau +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License, version 2 only, as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., 51 +# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +CURDIR=$(dirname $0) +TESTDIR=${CURDIR}/../../.. + +source $TESTDIR/utils/utils.sh + +start_lttng_sessiond_notap + +python3 ${CURDIR}/test_ust-dl.py + +stop_lttng_sessiond_notap diff --git a/tests/regression/ust/ust-dl/test_ust-dl.py b/tests/regression/ust/ust-dl/test_ust-dl.py new file mode 100644 index 000000000..1e5e96bb9 --- /dev/null +++ b/tests/regression/ust/ust-dl/test_ust-dl.py @@ -0,0 +1,113 @@ +#!/usr/bin/env python3 +# +# Copyright (C) - 2013 Jérémie Galarneau +# Copyright (C) - 2015 Antoine Busque +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License, version 2 only, as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., 51 +# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +import os +import subprocess +import re +import shutil +import sys + +test_path = os.path.dirname(os.path.abspath(__file__)) + "/" +test_utils_path = test_path +for i in range(4): + test_utils_path = os.path.dirname(test_utils_path) +test_utils_path = test_utils_path + "/utils" +sys.path.append(test_utils_path) +from test_utils import * + + +NR_TESTS = 6 +current_test = 1 +print("1..{0}".format(NR_TESTS)) + +# Check if a sessiond is running... bail out if none found. +if session_daemon_alive() == 0: + bail("""No sessiond running. Please make sure you are running this test + with the "run" shell script and verify that the lttng tools are + properly installed.""") + +session_info = create_session() +enable_ust_tracepoint_event(session_info, "*") +start_session(session_info) + +test_env = os.environ.copy() +test_env["LD_PRELOAD"] = "liblttng-ust-dl.so" +test_env["LD_LIBRARY_PATH"] = test_path + ".libs/" +test_process = subprocess.Popen(test_path + "prog", + stdout=subprocess.PIPE, stderr=subprocess.PIPE, + env=test_env) + +if sys.version_info >= (3, 3): + try: + test_process.wait(5) + except subprocess.TimeoutExpired: + test_process.kill() + bail("Failed to run ust-dl test application.", session_info) +else: + test_process.wait() + +print_test_result(test_process.returncode == 0, current_test, "Test application exited normally") +current_test += 1 + +stop_session(session_info) + +# Check for dl events in the resulting trace +try: + babeltrace_process = subprocess.Popen(["babeltrace", session_info.trace_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE) +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 + +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 + elif re.search(r".*lttng_ust_dl:build_id.*", event_line) is not None: + build_id_event_found = True + elif re.search(r".*lttng_ust_dl:debug_link.*", event_line) is not None: + debug_link_event_found = True + elif re.search(r".*lttng_ust_dl:dlclose.*", event_line) is not None: + dlclose_event_found = True + +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") +current_test += 1 + +print_test_result(build_id_event_found, current_test, "lttng_ust_dl:build_id 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") +current_test += 1 + +print_test_result(dlclose_event_found, current_test, "lttng_ust_dl:dlclose event found in resulting trace") +current_test += 1 + +shutil.rmtree(session_info.tmp_directory) diff --git a/tests/with_bindings_regression b/tests/with_bindings_regression index 2097e5c20..d4057fb35 100644 --- a/tests/with_bindings_regression +++ b/tests/with_bindings_regression @@ -4,3 +4,4 @@ regression/ust/exit-fast/test_exit-fast regression/ust/fork/test_fork regression/ust/libc-wrapper/test_libc-wrapper regression/ust/baddr-statedump/test_baddr-statedump +regression/ust/ust-dl/test_ust-dl -- 2.34.1