From a9c2df2bfce7a27b53ee5d5101f259f3e1f506b1 Mon Sep 17 00:00:00 2001 From: Francis Deslauriers Date: Fri, 29 Jun 2018 16:09:15 -0400 Subject: [PATCH] Implement userspace-probe regression tests MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This adds regression testcases for the following userspace probe features and should-fail scenarios. Features: * ELF function location tracing works, * ELF C++ mangled function and method location tracing works, * SDT tracepoint location tracing works, * Implicit location type defaults to ELF location, * Binary found $PATH, * Binary found using full path, * Binary with colon in file name, * Disabling of all location types, * Listing of all location types, * Saving and loading of all location types, * SDT probe with one or more callsites, * SDT probe with arguments, * SDT probe in shared object, * SDT probe in dlopen()ed and ldpreload()ed shared object. Should-fail: * Target binary does not exist, * Target binary not ELF file, * ELF symbol not found in target binary, * ELF symbol not a function, * SDT provider name not found, * SDT probe name not found, * SDT probe guarded by a semaphore. We also make sure to disable testcases when the necessary files/tools for them are not found: * Disables C++ testcases if no C++ compiler is found. * Disables SDT testcases if the Systemtap header files are not found. This is tested by trying to compile a simple C program with a SDT probe. If it fails, it will only disable the testcases and not the feature since the SDT userspace probe feature does not use this header for parsing. Signed-off-by: Francis Deslauriers Signed-off-by: Erica Bugden Signed-off-by: Jérémie Galarneau --- .gitignore | 5 + configure.ac | 9 + m4/ax_check_sdt_works.m4 | 20 + m4/rw_prog_cxx_works.m4 | 37 + tests/regression/kernel/test_userspace_probe | 846 ++++++++++++++++++ tests/root_regression | 1 + tests/utils/testapp/Makefile.am | 11 +- .../userspace-probe-elf-binary/Makefile.am | 4 + .../userspace-probe-elf-binary.c | 28 + .../Makefile.am | 4 + .../test_class.cpp | 23 + .../test_class.h | 26 + .../userspace-probe-elf-cxx-binary.cpp | 36 + .../userspace-probe-sdt-binary/Makefile.am | 35 + .../foobar_provider.d | 9 + .../userspace-probe-sdt-binary/libbar.c | 23 + .../userspace-probe-sdt-binary/libbar.h | 18 + .../userspace-probe-sdt-binary/libfoo.c | 24 + .../userspace-probe-sdt-binary/libfoo.h | 19 + .../userspace-probe-sdt-binary/libzzz.c | 22 + .../userspace-probe-sdt-binary/libzzz.h | 19 + .../testapp/userspace-probe-sdt-binary/sema.c | 23 + .../testapp/userspace-probe-sdt-binary/sema.h | 18 + .../userspace-probe-sdt-binary.c | 81 ++ tests/utils/utils.sh | 35 + 25 files changed, 1375 insertions(+), 1 deletion(-) create mode 100644 m4/ax_check_sdt_works.m4 create mode 100644 m4/rw_prog_cxx_works.m4 create mode 100755 tests/regression/kernel/test_userspace_probe create mode 100644 tests/utils/testapp/userspace-probe-elf-binary/Makefile.am create mode 100644 tests/utils/testapp/userspace-probe-elf-binary/userspace-probe-elf-binary.c create mode 100644 tests/utils/testapp/userspace-probe-elf-cxx-binary/Makefile.am create mode 100644 tests/utils/testapp/userspace-probe-elf-cxx-binary/test_class.cpp create mode 100644 tests/utils/testapp/userspace-probe-elf-cxx-binary/test_class.h create mode 100644 tests/utils/testapp/userspace-probe-elf-cxx-binary/userspace-probe-elf-cxx-binary.cpp create mode 100644 tests/utils/testapp/userspace-probe-sdt-binary/Makefile.am create mode 100644 tests/utils/testapp/userspace-probe-sdt-binary/foobar_provider.d create mode 100644 tests/utils/testapp/userspace-probe-sdt-binary/libbar.c create mode 100644 tests/utils/testapp/userspace-probe-sdt-binary/libbar.h create mode 100644 tests/utils/testapp/userspace-probe-sdt-binary/libfoo.c create mode 100644 tests/utils/testapp/userspace-probe-sdt-binary/libfoo.h create mode 100644 tests/utils/testapp/userspace-probe-sdt-binary/libzzz.c create mode 100644 tests/utils/testapp/userspace-probe-sdt-binary/libzzz.h create mode 100644 tests/utils/testapp/userspace-probe-sdt-binary/sema.c create mode 100644 tests/utils/testapp/userspace-probe-sdt-binary/sema.h create mode 100644 tests/utils/testapp/userspace-probe-sdt-binary/userspace-probe-sdt-binary.c diff --git a/.gitignore b/.gitignore index 224f6d4f4..c25fb7008 100644 --- a/.gitignore +++ b/.gitignore @@ -125,6 +125,11 @@ health_check /tests/perf/find_event /tests/perf/test_perf_raw /tests/unit/test_string_utils +/tests/utils/testapp/gen-ust-nevents-str/gen-ust-nevents-str +/tests/utils/testapp/userspace-probe-elf-binary/userspace-probe-elf-binary +/tests/utils/testapp/userspace-probe-elf-cxx-binary/userspace-probe-elf-cxx-binary +/tests/utils/testapp/userspace-probe-sdt-binary/foobar_provider.h +/tests/utils/testapp/userspace-probe-sdt-binary/userspace-probe-sdt-binary # man pages /doc/man/*.1 diff --git a/configure.ac b/configure.ac index fb2a31f9b..87b48ee3f 100644 --- a/configure.ac +++ b/configure.ac @@ -21,6 +21,12 @@ AC_USE_SYSTEM_EXTENSIONS AC_SYS_LARGEFILE AC_PROG_CC AC_PROG_CC_STDC +AC_PROG_CXX +rw_PROG_CXX_WORKS +AM_CONDITIONAL([CXX_WORKS], [test "x$rw_cv_prog_cxx_works" = "xyes"]) + +ax_CHECK_SDT_WORKS +AM_CONDITIONAL([SDT_WORKS], [test "x$ax_check_sdt_works" = "xyes"]) # Checks for programs. AC_PROG_GREP @@ -1166,6 +1172,9 @@ AC_CONFIG_FILES([ tests/utils/testapp/gen-ust-nevents-str/Makefile tests/utils/testapp/gen-syscall-events/Makefile tests/utils/testapp/gen-ust-tracef/Makefile + tests/utils/testapp/userspace-probe-elf-binary/Makefile + tests/utils/testapp/userspace-probe-elf-cxx-binary/Makefile + tests/utils/testapp/userspace-probe-sdt-binary/Makefile ]) # Inject variable into python test script. diff --git a/m4/ax_check_sdt_works.m4 b/m4/ax_check_sdt_works.m4 new file mode 100644 index 000000000..49ee68444 --- /dev/null +++ b/m4/ax_check_sdt_works.m4 @@ -0,0 +1,20 @@ +# ac_CHECK_SDT_WORKS +# +# Check whether it's possible to build a binary with Systemtap SDT probes. + +AC_DEFUN([ax_CHECK_SDT_WORKS], [ +AC_COMPILE_IFELSE( +[AC_LANG_SOURCE([[ + #define SDT_USE_VARIADIC + #include + void fct(void) + { + STAP_PROBEV(provider,name,1,2,3,4,5,6,7,8,9,10); + } + ]])], [ + ax_check_sdt_works=yes + ], [ + ax_check_sdt_works=no + ] +) +]) diff --git a/m4/rw_prog_cxx_works.m4 b/m4/rw_prog_cxx_works.m4 new file mode 100644 index 000000000..1950d94d0 --- /dev/null +++ b/m4/rw_prog_cxx_works.m4 @@ -0,0 +1,37 @@ +# rw_PROG_CXX_WORKS +# +# Check whether the C++ compiler works. There's a bit of oversight in +# autoconf that will set the C++ compiler to g++ if no compiler is found, +# even if g++ is not present! So we need an extra test to make sure that +# the compiler works. +# Script copied from the lttng-ust project. +# +AC_DEFUN([rw_PROG_CXX_WORKS], [ +AC_REQUIRE([AC_PROG_CXX]) +AC_CACHE_CHECK([whether the C++ compiler works], + [rw_cv_prog_cxx_works], + [AC_LANG_PUSH([C++]) + + AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])], [ + check_cxx_designated_initializers=yes + ], [ + rw_cv_prog_cxx_works=no + ]) + + AS_IF([test "x$check_cxx_designated_initializers" = "xyes"], [ + AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ + struct foo { int a; int b; }; + void fct(void) + { + struct foo f = { .a = 0, .b = 1 }; + } + ]])], [ + rw_cv_prog_cxx_works=yes + ], [ + rw_cv_prog_cxx_works=no + ]) + ]) + + AC_LANG_POP([C++]) +]) +]) diff --git a/tests/regression/kernel/test_userspace_probe b/tests/regression/kernel/test_userspace_probe new file mode 100755 index 000000000..fb8ce303f --- /dev/null +++ b/tests/regression/kernel/test_userspace_probe @@ -0,0 +1,846 @@ +#!/bin/bash +# +# Copyright (C) - 2017 Erica Bugden +# Copyright (C) - 2017 Francis Deslauriers +# +# This library is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; version 2.1 of the License. +# +# This library 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 Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +TEST_DESC="Userspace probe - Testing userspace probe on ELF symbol" + +CURDIR=$(dirname "$0")/ +TESTDIR=$CURDIR/../.. +TESTAPP_DIR="$TESTDIR/utils/testapp/" +ELF_TEST_BIN_DIR="$TESTAPP_DIR/userspace-probe-elf-binary/" +ELF_TEST_BIN_NAME="userspace-probe-elf-binary" +ELF_TEST_BIN="$ELF_TEST_BIN_DIR/$ELF_TEST_BIN_NAME" +ELF_CXX_TEST_BIN_DIR="$TESTAPP_DIR/userspace-probe-elf-cxx-binary/" +ELF_CXX_TEST_BIN_NAME="userspace-probe-elf-cxx-binary" +ELF_CXX_TEST_BIN="$ELF_CXX_TEST_BIN_DIR/$ELF_CXX_TEST_BIN_NAME" +SDT_TEST_BIN_DIR="$TESTAPP_DIR/userspace-probe-sdt-binary/.libs/" +SDT_TEST_BIN_NAME="userspace-probe-sdt-binary" +SDT_TEST_BIN="$SDT_TEST_BIN_DIR/$SDT_TEST_BIN_NAME" +ELF_SYMBOL="test_function" +PROBE_EVENT_NAME=userspace_probe_test_event +NUM_TESTS=81 +OUTPUT_DEST=/dev/null +ERROR_OUTPUT_DEST=/dev/null + +source "$TESTDIR/utils/utils.sh" + +function validate_list() +{ + local session_name=$1 + local event_name=$2 + + out=$("$TESTDIR/../src/bin/lttng/$LTTNG_BIN" list "$session_name" | grep "$event_name") + if [ -z "$out" ]; then + fail "Validate userspace probe listing" + diag "$event_name not found when listing $session_name" + else + pass "Validate userspace probe listing. Found $event_name." + fi +} + +function test_userspace_probe_enable_file_noexist () +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="test_userspace_probe_enable_file_noexist" + ENABLE_EXPR="elf:/etc/file-not-exist:$ELF_SYMBOL" + + diag "Userspace probe enable on non-existant file" + + create_lttng_session_ok $SESSION_NAME "$TRACE_PATH" + + lttng_enable_kernel_userspace_probe_event_fail $SESSION_NAME $ENABLE_EXPR $PROBE_EVENT_NAME + + destroy_lttng_session_ok $SESSION_NAME + + rm -rf "$TRACE_PATH" +} + +function test_userspace_probe_enable_file_not_elf () +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="test_userspace_probe_enable_file_not_elf" + ENABLE_EXPR="elf:/etc/passwd:$ELF_SYMBOL" + + diag "Userspace probe enable on a non ELF file" + + create_lttng_session_ok $SESSION_NAME "$TRACE_PATH" + + lttng_enable_kernel_userspace_probe_event_fail $SESSION_NAME $ENABLE_EXPR $PROBE_EVENT_NAME + + destroy_lttng_session_ok $SESSION_NAME + + rm -rf "$TRACE_PATH" +} + +function test_userspace_probe_enable_elf_missing_symbol_name () +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="test_userspace_probe_enable_elf_missing_symbol" + ENABLE_EXPR="elf:$ELF_TEST_BIN:" + + diag "Userspace probe enable with unspecified ELF symbol" + + create_lttng_session_ok $SESSION_NAME "$TRACE_PATH" + + lttng_enable_kernel_userspace_probe_event_fail $SESSION_NAME "$ENABLE_EXPR" $PROBE_EVENT_NAME + + destroy_lttng_session_ok $SESSION_NAME + + rm -rf "$TRACE_PATH" +} + +function test_userspace_probe_enable_elf_nonexistant_symbol () +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="test_userspace_probe_enable_elf_nonexistant_symbol" + ELF_SYMBOL_NO_EXIST="function_doesnt_exist" + ENABLE_EXPR="elf:$ELF_TEST_BIN:$ELF_SYMBOL_NO_EXIST" + + diag "Userspace probe enable with nonexistant ELF symbol" + + create_lttng_session_ok $SESSION_NAME "$TRACE_PATH" + + lttng_enable_kernel_userspace_probe_event_fail $SESSION_NAME "$ENABLE_EXPR" $PROBE_EVENT_NAME + + destroy_lttng_session_ok $SESSION_NAME + + rm -rf "$TRACE_PATH" +} + +function test_userspace_probe_enable_elf_symbol_not_function () +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="test_userspace_probe_enable_elf_symbol_not_function" + ELF_SYMBOL_NO_FUNC="not_a_function" + ENABLE_EXPR="elf:$ELF_TEST_BIN:$ELF_SYMBOL_NO_FUNC" + + diag "Userspace probe enable with non-function ELF symbol" + + create_lttng_session_ok $SESSION_NAME "$TRACE_PATH" + + lttng_enable_kernel_userspace_probe_event_fail $SESSION_NAME "$ENABLE_EXPR" $PROBE_EVENT_NAME + + destroy_lttng_session_ok $SESSION_NAME + + rm -rf "$TRACE_PATH" +} + +function test_userspace_probe_enable_implicit_probe_type () +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="test_userspace_probe_enable_implicit_probe_type" + ENABLE_EXPR="$ELF_TEST_BIN:$ELF_SYMBOL" + + diag "Userspace probe enabled successfully with implicit probe type" + + create_lttng_session_ok $SESSION_NAME "$TRACE_PATH" + + lttng_enable_kernel_userspace_probe_event_ok $SESSION_NAME "$ENABLE_EXPR" $PROBE_EVENT_NAME + + validate_list $SESSION_NAME $ELF_SYMBOL + validate_list $SESSION_NAME $ELF_TEST_BIN_NAME + validate_list $SESSION_NAME "ELF" + validate_list $SESSION_NAME "Function" + + destroy_lttng_session_ok $SESSION_NAME + + rm -rf "$TRACE_PATH" +} + +function test_userspace_probe_enable_elf_symbol_exists () +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="test_userspace_probe_enable_elf_symbol_exists" + ENABLE_EXPR="elf:$ELF_TEST_BIN:$ELF_SYMBOL" + + diag "Userspace probe enabled successfully" + + create_lttng_session_ok $SESSION_NAME "$TRACE_PATH" + + lttng_enable_kernel_userspace_probe_event_ok $SESSION_NAME "$ENABLE_EXPR" $PROBE_EVENT_NAME + + validate_list $SESSION_NAME $ELF_SYMBOL + validate_list $SESSION_NAME $ELF_TEST_BIN_NAME + validate_list $SESSION_NAME "ELF" + validate_list $SESSION_NAME "Function" + + destroy_lttng_session_ok $SESSION_NAME + + rm -rf "$TRACE_PATH" +} + +function test_userspace_probe_enable_in_path () +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="test_userspace_probe_enable_in_path" + ENABLE_EXPR="elf:$ELF_TEST_BIN_NAME:$ELF_SYMBOL" + + diag "Userspace probe on binary in PATH enabled successfully" + + create_lttng_session_ok $SESSION_NAME "$TRACE_PATH" + + # Save old PATH and add the test directory to the PATH. + OLDPATH="$PATH" + export PATH="$PATH:$(realpath $ELF_TEST_BIN_DIR)" + + lttng_enable_kernel_userspace_probe_event_ok $SESSION_NAME "$ENABLE_EXPR" $PROBE_EVENT_NAME + + validate_list $SESSION_NAME $ELF_SYMBOL + validate_list $SESSION_NAME $ELF_TEST_BIN_NAME + validate_list $SESSION_NAME "ELF" + validate_list $SESSION_NAME "Function" + + # Reset the previously saved PATH. + export PATH="$OLDPATH" + + destroy_lttng_session_ok $SESSION_NAME + + rm -rf "$TRACE_PATH" +} + +function test_userspace_probe_enable_full_path () +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="test_userspace_probe_enable_full_path" + ENABLE_EXPR="elf:$(realpath $ELF_TEST_BIN):$ELF_SYMBOL" + diag "Userspace probe with full path enabled successfully" + + create_lttng_session_ok $SESSION_NAME "$TRACE_PATH" + + lttng_enable_kernel_userspace_probe_event_ok $SESSION_NAME "$ENABLE_EXPR" $PROBE_EVENT_NAME + + validate_list $SESSION_NAME $ELF_SYMBOL + validate_list $SESSION_NAME $ELF_TEST_BIN_NAME + validate_list $SESSION_NAME "ELF" + validate_list $SESSION_NAME "Function" + + destroy_lttng_session_ok $SESSION_NAME + + rm -rf "$TRACE_PATH" +} + +function test_userspace_probe_enable_colon_in_path () +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="test_userspace_probe_enable_colon_in_path" + COLON_FILE_PATH=$(mktemp -d) + ELF_BIN_SYMLINK="$COLON_FILE_PATH/colon_:_in_name" + ELF_BIN_WITH_COLON_IN_NAME_ESCAPED="$COLON_FILE_PATH/colon_\:_in_name" + ENABLE_EXPR="elf:"$ELF_BIN_WITH_COLON_IN_NAME_ESCAPED":$ELF_SYMBOL" + + ln -s $(realpath $ELF_TEST_BIN) $ELF_BIN_SYMLINK + + diag "Userspace probe with binary with colon in name enabled successfully" + + create_lttng_session_ok $SESSION_NAME "$TRACE_PATH" + + lttng_enable_kernel_userspace_probe_event_ok $SESSION_NAME "$ENABLE_EXPR" $PROBE_EVENT_NAME + + validate_list $SESSION_NAME $ELF_SYMBOL + validate_list $SESSION_NAME $ELF_TEST_BIN_NAME + validate_list $SESSION_NAME "ELF" + validate_list $SESSION_NAME "Function" + + destroy_lttng_session_ok $SESSION_NAME + + rm -rf "$TRACE_PATH" + rm -rf "$COLON_FILE_PATH" +} + +function test_userspace_probe_elf () +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="test_userprobe_elf" + ENABLE_EXPR="elf:$ELF_TEST_BIN:$ELF_SYMBOL" + + diag "Userspace probe on Elf symbol enabled and traced" + + create_lttng_session_ok $SESSION_NAME "$TRACE_PATH" + + lttng_enable_kernel_userspace_probe_event_ok $SESSION_NAME "$ENABLE_EXPR" $PROBE_EVENT_NAME + + start_lttng_tracing_ok $SESSION_NAME + eval "$ELF_TEST_BIN" > /dev/null + stop_lttng_tracing_ok $SESSION_NAME + + validate_trace $PROBE_EVENT_NAME "$TRACE_PATH" + + destroy_lttng_session_ok $SESSION_NAME + + rm -rf "$TRACE_PATH" +} + +function test_userspace_probe_elf_cxx_function () +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="test_userprobe_elf_cxx_function" + # Probing C++ mangled symbols should work the same way as regular Elf + # symbols + ELF_SYMBOL_CXX="_Z17test_cxx_functionv" + ENABLE_EXPR="elf:$ELF_CXX_TEST_BIN:$ELF_SYMBOL_CXX" + + diag "Userspace probe on C++ mangled function enabled and traced" + + create_lttng_session_ok $SESSION_NAME "$TRACE_PATH" + + lttng_enable_kernel_userspace_probe_event_ok $SESSION_NAME "$ENABLE_EXPR" $PROBE_EVENT_NAME + + start_lttng_tracing_ok $SESSION_NAME + eval "$ELF_CXX_TEST_BIN" > /dev/null + stop_lttng_tracing_ok $SESSION_NAME + + validate_trace $PROBE_EVENT_NAME "$TRACE_PATH" + + destroy_lttng_session_ok $SESSION_NAME + + rm -rf "$TRACE_PATH" +} + +function test_userspace_probe_elf_cxx_method () +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="test_userprobe_elf_cxx_method" + # Probing C++ mangled symbols should work the same way as regular Elf + # symbols + ELF_SYMBOL_CXX="_ZN10test_class11test_methodEv" + ENABLE_EXPR="elf:$ELF_CXX_TEST_BIN:$ELF_SYMBOL_CXX" + + diag "Userspace probe on C++ mangled method enabled and traced" + + create_lttng_session_ok $SESSION_NAME "$TRACE_PATH" + + lttng_enable_kernel_userspace_probe_event_ok $SESSION_NAME "$ENABLE_EXPR" $PROBE_EVENT_NAME + + start_lttng_tracing_ok $SESSION_NAME + eval "$ELF_CXX_TEST_BIN" > /dev/null + stop_lttng_tracing_ok $SESSION_NAME + + validate_trace $PROBE_EVENT_NAME "$TRACE_PATH" + + destroy_lttng_session_ok $SESSION_NAME + + rm -rf "$TRACE_PATH" +} + +function test_userspace_probe_elf_disable () +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="test_userprobe_elf_disable" + ENABLE_EXPR="elf:$ELF_TEST_BIN:$ELF_SYMBOL" + + diag "Userspace probe on Elf symbol disabled and traced" + + create_lttng_session_ok $SESSION_NAME "$TRACE_PATH" + + # Activate and disable event + lttng_enable_kernel_userspace_probe_event_ok $SESSION_NAME "$ENABLE_EXPR" $PROBE_EVENT_NAME + disable_kernel_lttng_userspace_probe_event_ok $SESSION_NAME $PROBE_EVENT_NAME + + start_lttng_tracing_ok $SESSION_NAME + eval "$ELF_TEST_BIN" > /dev/null + stop_lttng_tracing_ok $SESSION_NAME + + # Verify that the trace contains zero event. + validate_trace_empty "$TRACE_PATH" + + destroy_lttng_session_ok $SESSION_NAME + + rm -rf "$TRACE_PATH" +} + +function test_userspace_probe_elf_list () +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="test_userprobe_elf_list" + ENABLE_EXPR="elf:$ELF_TEST_BIN:$ELF_SYMBOL" + + diag "Userspace probe ELF enabled and listed" + + create_lttng_session_ok $SESSION_NAME "$TRACE_PATH" + + lttng_enable_kernel_userspace_probe_event_ok $SESSION_NAME "$ENABLE_EXPR" $PROBE_EVENT_NAME + + validate_list $SESSION_NAME $PROBE_EVENT_NAME + validate_list $SESSION_NAME $ELF_SYMBOL + validate_list $SESSION_NAME $ELF_TEST_BIN_NAME + validate_list $SESSION_NAME "ELF" + validate_list $SESSION_NAME "Function" + + destroy_lttng_session_ok $SESSION_NAME + + rm -rf "$TRACE_PATH" +} + +function test_userspace_probe_save_load_elf() +{ + # Test that the load and save works for userspace probes AND that when + # a userspace probe is placed on a symlink by the user the save command + # saves the path to the link and not to the actual file. This is to + # support instrumentation of shared objects that are often accessed + # through symlinks and updated. + TRACE_PATH=$(mktemp -d) + TMP_LINK_DIR=$(mktemp -d) + TMP_SAVE_DIR=$(mktemp -d) + + SESSION_NAME="test_userprobe_save_load_elf" + + ELF_BIN_SYMLINK="$TMP_LINK_DIR"/bin_elf_symlink + + ENABLE_EXPR_ELF="elf:$ELF_BIN_SYMLINK:$ELF_SYMBOL" + PROBE_EVENT_NAME_ELF="$PROBE_EVENT_NAME"_elf + + # Create symlinks to the target binaries. + ln -s $(realpath $ELF_TEST_BIN) $ELF_BIN_SYMLINK + + diag "Userspace probes Elf are saved and loaded" + + create_lttng_session_ok $SESSION_NAME "$TRACE_PATH" + + # Enable userspace prove events. + lttng_enable_kernel_userspace_probe_event_ok $SESSION_NAME "$ENABLE_EXPR_ELF" "$PROBE_EVENT_NAME_ELF" + + # Confirm that the events were enabled. + validate_list $SESSION_NAME $ELF_TEST_BIN_NAME + + # Save the session to a file. + lttng_save $SESSION_NAME "--output-path=$TMP_SAVE_DIR" + + destroy_lttng_session_ok $SESSION_NAME + + # Confirm that the userspace probe are save to the xml file. + local count=$(cat $TMP_SAVE_DIR/* | grep --count -E "$ELF_BIN_SYMLINK") + if [[ $count -eq "1" ]]; then + pass "Symlink found in saved session" + else + fail "Symlink to binary not found in saved session" + fi + + # Load the saved session. + lttng_load_ok "--input-path=$TMP_SAVE_DIR" + + # Confirm that the userspace probes event are enabled in the newly + # loaded session. + validate_list $SESSION_NAME $ELF_TEST_BIN_NAME + + # Cleanup temp files and folders. + rm -rf "$TRACE_PATH" + rm -rf "$TMP_LINK_DIR" + rm -rf "$TMP_SAVE_DIR" +} +function test_userspace_probe_save_load_sdt() +{ + # Test that the load and save works for userspace probes AND that when + # a userspace probe is placed on a symlink by the user the save command + # saves the path to the link and not to the actual file. This is to + # support instrumentation of shared objects that are often accessed + # through symlinks and updated. + TRACE_PATH=$(mktemp -d) + TMP_LINK_DIR=$(mktemp -d) + TMP_SAVE_DIR=$(mktemp -d) + + SESSION_NAME="test_userprobe_save_load_sdt" + PROVIDER="foobar" + PROBE="tp1" + + SDT_BIN_SYMLINK="$TMP_LINK_DIR"/bin_sdt_symlink + + ENABLE_EXPR_SDT="sdt:$SDT_BIN_SYMLINK:$PROVIDER:$PROBE" + PROBE_EVENT_NAME_SDT="$PROBE_EVENT_NAME"_sdt + + # Create symlinks to the target binaries. + ln -s $(realpath $SDT_TEST_BIN) $SDT_BIN_SYMLINK + + diag "Userspace probes SDT are saved and loaded" + + create_lttng_session_ok $SESSION_NAME "$TRACE_PATH" + + # Enable userspace prove events. + lttng_enable_kernel_userspace_probe_event_ok $SESSION_NAME "$ENABLE_EXPR_SDT" "$PROBE_EVENT_NAME_SDT" + + # Confirm that the events were enabled. + validate_list $SESSION_NAME $SDT_TEST_BIN_NAME + + # Save the session to a file. + lttng_save $SESSION_NAME "--output-path=$TMP_SAVE_DIR" + + destroy_lttng_session_ok $SESSION_NAME + + # Confirm that the userspace probe are save to the xml file. + local count=$(cat $TMP_SAVE_DIR/* | grep --count -E "$SDT_BIN_SYMLINK") + if [[ $count -eq "1" ]]; then + pass "Symlink found in saved session" + else + fail "Symlink to binary not found in saved session" + fi + + # Load the saved session. + lttng_load_ok "--input-path=$TMP_SAVE_DIR" + + # Confirm that the userspace probes event are enabled in the newly + # loaded session. + validate_list $SESSION_NAME $SDT_TEST_BIN_NAME + + # Cleanup temp files and folders. + rm -rf "$TRACE_PATH" + rm -rf "$TMP_LINK_DIR" + rm -rf "$TMP_SAVE_DIR" +} + +function test_userspace_probe_sdt () +{ + TRACE_PATH=$(mktemp -d) + PROVIDER="foobar" + PROBE="tp1" + ENABLE_EXPR="sdt:$SDT_TEST_BIN:$PROVIDER:$PROBE" + + diag "Userspace probe on SDT tracepoint enabled and traced" + + create_lttng_session_ok $SESSION_NAME "$TRACE_PATH" + + lttng_enable_kernel_userspace_probe_event_ok $SESSION_NAME "$ENABLE_EXPR" $PROBE_EVENT_NAME + + start_lttng_tracing_ok $SESSION_NAME + eval "$SDT_TEST_BIN" > /dev/null + stop_lttng_tracing_ok $SESSION_NAME + + validate_trace $PROBE_EVENT_NAME "$TRACE_PATH" + + destroy_lttng_session_ok $SESSION_NAME + + rm -rf "$TRACE_PATH" +} + +function test_userspace_probe_sdt_list () +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="test_userprobe_sdt_list" + PROVIDER="foobar" + PROBE="tp1" + ENABLE_EXPR="sdt:$SDT_TEST_BIN:$PROVIDER:$PROBE" + + diag "Userspace probe SDT enabled and listed" + + create_lttng_session_ok $SESSION_NAME "$TRACE_PATH" + + lttng_enable_kernel_userspace_probe_event_ok $SESSION_NAME "$ENABLE_EXPR" $PROBE_EVENT_NAME + + validate_list $SESSION_NAME $PROBE_EVENT_NAME + validate_list $SESSION_NAME $PROVIDER + validate_list $SESSION_NAME $PROBE + validate_list $SESSION_NAME $SDT_TEST_BIN_NAME + validate_list $SESSION_NAME "SDT" + validate_list $SESSION_NAME "Tracepoint" + + destroy_lttng_session_ok $SESSION_NAME + + rm -rf "$TRACE_PATH" +} + +function test_userspace_probe_enable_sdt_nonexistant_provider () +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="test_userprobe_sdt_nonexistand_provider" + PROVIDER="not_provider" + PROBE="tp1" + ENABLE_EXPR="sdt:$SDT_TEST_BIN:$PROVIDER:$PROBE" + + diag "Userspace probe SDT on tracepoint non existant provider" + + create_lttng_session_ok $SESSION_NAME "$TRACE_PATH" + + lttng_enable_kernel_userspace_probe_event_fail $SESSION_NAME "$ENABLE_EXPR" $PROBE_EVENT_NAME + + destroy_lttng_session_ok $SESSION_NAME + + rm -rf "$TRACE_PATH" +} + +function test_userspace_probe_enable_sdt_nonexistant_probe () +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="test_userprobe_sdt_nonexistant_probe" + PROVIDER="foobar" + PROBE="not_a_tracepoint" + ENABLE_EXPR="sdt:$SDT_TEST_BIN:$PROVIDER:$PROBE" + + diag "Userspace probe SDT on non existant probe" + + create_lttng_session_ok $SESSION_NAME "$TRACE_PATH" + + lttng_enable_kernel_userspace_probe_event_fail $SESSION_NAME "$ENABLE_EXPR" $PROBE_EVENT_NAME + + destroy_lttng_session_ok $SESSION_NAME + + rm -rf "$TRACE_PATH" +} + +function test_userspace_probe_enable_sdt_with_sema () +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="test_userprobe_sdt_with_sema" + PROVIDER="foobar" + PROBE="tp_with_semaphore" + ENABLE_EXPR="sdt:$SDT_TEST_BIN:$PROVIDER:$PROBE" + + diag "Userspace probe SDT on non existant probe" + + create_lttng_session_ok $SESSION_NAME "$TRACE_PATH" + + lttng_enable_kernel_userspace_probe_event_fail $SESSION_NAME "$ENABLE_EXPR" $PROBE_EVENT_NAME + + destroy_lttng_session_ok $SESSION_NAME + + rm -rf "$TRACE_PATH" +} + +function test_userspace_probe_sdt_one_probe () +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="test_userprobe_sdt_one_probe" + PROVIDER="foobar" + PROBE="tp1" + ENABLE_EXPR="sdt:$SDT_TEST_BIN:$PROVIDER:$PROBE" + + diag "Userspace probe SDT on tracepoint with one callsite" + + create_lttng_session_ok $SESSION_NAME "$TRACE_PATH" + + lttng_enable_kernel_userspace_probe_event_ok $SESSION_NAME "$ENABLE_EXPR" $PROBE_EVENT_NAME + + start_lttng_tracing_ok $SESSION_NAME + eval "$SDT_TEST_BIN" > /dev/null + stop_lttng_tracing_ok $SESSION_NAME + + validate_trace $PROBE_EVENT_NAME "$TRACE_PATH" + + destroy_lttng_session_ok $SESSION_NAME + + rm -rf "$TRACE_PATH" +} + +function test_userspace_probe_sdt_two_probes () +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="test_userprobe_sdt_two_probes" + PROVIDER="foobar" + PROBE="tp2" + ENABLE_EXPR="sdt:$SDT_TEST_BIN:$PROVIDER:$PROBE" + + diag "Userspace probe SDT on tracepoint with two callsites" + + create_lttng_session_ok $SESSION_NAME "$TRACE_PATH" + + lttng_enable_kernel_userspace_probe_event_ok $SESSION_NAME "$ENABLE_EXPR" $PROBE_EVENT_NAME + + start_lttng_tracing_ok $SESSION_NAME + eval "$SDT_TEST_BIN" > /dev/null + stop_lttng_tracing_ok $SESSION_NAME + + validate_trace $PROBE_EVENT_NAME "$TRACE_PATH" + + destroy_lttng_session_ok $SESSION_NAME + + rm -rf "$TRACE_PATH" +} + +function test_userspace_probe_sdt_in_shared_object () +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="test_userprobe_sdt_shared_object" + PROVIDER="foobar" + PROBE="tp_in_shared_object" + ENABLE_EXPR="sdt:$SDT_TEST_BIN_DIR/libfoo.so:$PROVIDER:$PROBE" + + diag "Userspace probe SDT on tracepoint in shared object" + + create_lttng_session_ok $SESSION_NAME "$TRACE_PATH" + + lttng_enable_kernel_userspace_probe_event_ok $SESSION_NAME "$ENABLE_EXPR" $PROBE_EVENT_NAME + + start_lttng_tracing_ok $SESSION_NAME + eval "$SDT_TEST_BIN" > /dev/null + stop_lttng_tracing_ok $SESSION_NAME + + validate_trace $PROBE_EVENT_NAME "$TRACE_PATH" + + destroy_lttng_session_ok $SESSION_NAME + + rm -rf "$TRACE_PATH" +} + +function test_userspace_probe_sdt_in_shared_object_dlopen () +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="test_userprobe_sdt_shared_object_dlopen" + PROVIDER="foobar" + PROBE="tp_in_dlopen" + ENABLE_EXPR="sdt:$SDT_TEST_BIN_DIR/libbar.so:$PROVIDER:$PROBE" + + diag "Userspace probe SDT on tracepoint in dlopen()ed shared object" + + create_lttng_session_ok $SESSION_NAME "$TRACE_PATH" + + lttng_enable_kernel_userspace_probe_event_ok $SESSION_NAME "$ENABLE_EXPR" $PROBE_EVENT_NAME + + start_lttng_tracing_ok $SESSION_NAME + eval "$SDT_TEST_BIN" > /dev/null + stop_lttng_tracing_ok $SESSION_NAME + + validate_trace $PROBE_EVENT_NAME "$TRACE_PATH" + + destroy_lttng_session_ok $SESSION_NAME + + rm -rf "$TRACE_PATH" +} + +function test_userspace_probe_sdt_in_shared_object_ldpreload () +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="test_userprobe_sdt_shared_object_ldpreload" + PROVIDER="foobar" + PROBE="tp_in_ldpreload" + ENABLE_EXPR="sdt:$SDT_TEST_BIN_DIR/libzzz.so:$PROVIDER:$PROBE" + + diag "Userspace probe SDT on tracepoint in an LD_PRELOADed shared object" + + create_lttng_session_ok $SESSION_NAME "$TRACE_PATH" + + lttng_enable_kernel_userspace_probe_event_ok $SESSION_NAME "$ENABLE_EXPR" $PROBE_EVENT_NAME + + start_lttng_tracing_ok $SESSION_NAME + LD_PRELOAD="$SDT_TEST_BIN_DIR/libzzz.so" eval "$SDT_TEST_BIN" > /dev/null + stop_lttng_tracing_ok $SESSION_NAME + + validate_trace $PROBE_EVENT_NAME "$TRACE_PATH" + + destroy_lttng_session_ok $SESSION_NAME + + rm -rf "$TRACE_PATH" +} + +function test_userspace_probe_sdt_with_arg () +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="test_userprobe_sdt_arg" + PROVIDER="foobar" + PROBE="tp_with_arg" + ENABLE_EXPR="sdt:$SDT_TEST_BIN:$PROVIDER:$PROBE" + + diag "Userspace probe SDT on tracepoint with argument" + + create_lttng_session_ok $SESSION_NAME "$TRACE_PATH" + + lttng_enable_kernel_userspace_probe_event_ok $SESSION_NAME "$ENABLE_EXPR" $PROBE_EVENT_NAME + + start_lttng_tracing_ok $SESSION_NAME + eval "$SDT_TEST_BIN" > /dev/null + stop_lttng_tracing_ok $SESSION_NAME + + validate_trace $PROBE_EVENT_NAME "$TRACE_PATH" + + destroy_lttng_session_ok $SESSION_NAME + + rm -rf "$TRACE_PATH" +} + +ls "$SDT_TEST_BIN" >/dev/null 2>&1 +if test $? == 0; then + NUM_TESTS=$((NUM_TESTS+68)) + RUN_SDT_TESTS=1 +else + RUN_SDT_TESTS=0 +fi + +ls "$ELF_CXX_TEST_BIN" >/dev/null 2>&1 +if test $? == 0; then + NUM_TESTS=$((NUM_TESTS+12)) + RUN_ELF_CXX_TESTS=1 +else + RUN_ELF_CXX_TESTS=0 +fi +plan_tests $NUM_TESTS +print_test_banner "$TEST_DESC" + +if [ "$(id -u)" == "0" ]; then + isroot=1 +else + isroot=0 +fi + +skip $isroot "Root access is needed. Skipping all tests." $NUM_TESTS || +{ + start_lttng_sessiond + + # Unsuccessful event enabling + test_userspace_probe_enable_file_noexist + test_userspace_probe_enable_file_not_elf + + test_userspace_probe_enable_elf_missing_symbol_name + test_userspace_probe_enable_elf_nonexistant_symbol + test_userspace_probe_enable_elf_symbol_not_function + + # Successful userspace probe elf enabling + test_userspace_probe_enable_implicit_probe_type + test_userspace_probe_enable_in_path + test_userspace_probe_enable_full_path + test_userspace_probe_enable_elf_symbol_exists + test_userspace_probe_enable_colon_in_path + + # Successful tracing userspace probe elf + test_userspace_probe_elf + + # Disable userspace-probe elf + test_userspace_probe_elf_disable + + # Successful listing of userspace probe elf + test_userspace_probe_elf_list + + # Successful save and load of userspace probe elf + test_userspace_probe_save_load_elf + + if test $RUN_ELF_CXX_TESTS == 1; then + # Successful tracing of userspace probe elf on C++ symbol + test_userspace_probe_elf_cxx_function + test_userspace_probe_elf_cxx_method + fi + + if test $RUN_SDT_TESTS == 1; then + # Unsuccessful event enabling + test_userspace_probe_enable_sdt_nonexistant_provider + test_userspace_probe_enable_sdt_nonexistant_probe + test_userspace_probe_enable_sdt_with_sema + + # Successful userspace probe sdt enabling + test_userspace_probe_sdt_one_probe + test_userspace_probe_sdt_two_probes + test_userspace_probe_sdt_with_arg + test_userspace_probe_sdt_in_shared_object + test_userspace_probe_sdt_in_shared_object_dlopen + test_userspace_probe_sdt_in_shared_object_ldpreload + + # Successful tracing of userspace probe sdt + test_userspace_probe_sdt + + # Successful listing of userspace probe sdt + test_userspace_probe_sdt_list + + # Successful save and load of userspace probe sdt + test_userspace_probe_save_load_sdt + fi + + stop_lttng_sessiond +} diff --git a/tests/root_regression b/tests/root_regression index 40bb7a59a..1fc5bbfe8 100644 --- a/tests/root_regression +++ b/tests/root_regression @@ -6,6 +6,7 @@ regression/kernel/test_rotation_destroy_flush regression/kernel/test_select_poll_epoll regression/kernel/test_lttng_logger regression/kernel/test_callstack +regression/kernel/test_userspace_probe regression/tools/live/test_kernel regression/tools/live/test_lttng_kernel regression/tools/streaming/test_high_throughput_limits diff --git a/tests/utils/testapp/Makefile.am b/tests/utils/testapp/Makefile.am index 9bfe53666..e54ac890a 100644 --- a/tests/utils/testapp/Makefile.am +++ b/tests/utils/testapp/Makefile.am @@ -2,7 +2,16 @@ SUBDIRS = gen-ust-events \ gen-ust-nevents \ gen-ust-nevents-str \ gen-ust-tracef \ - gen-syscall-events + gen-syscall-events \ + userspace-probe-elf-binary + +if CXX_WORKS +SUBDIRS += userspace-probe-elf-cxx-binary +endif # CXX_WORKS + +if SDT_WORKS +SUBDIRS += userspace-probe-sdt-binary +endif # SDT_WORKS if HAVE_MODULES_USERSPACE_CALLSTACK_CONTEXT SUBDIRS += gen-syscall-events-callstack diff --git a/tests/utils/testapp/userspace-probe-elf-binary/Makefile.am b/tests/utils/testapp/userspace-probe-elf-binary/Makefile.am new file mode 100644 index 000000000..9d4696b56 --- /dev/null +++ b/tests/utils/testapp/userspace-probe-elf-binary/Makefile.am @@ -0,0 +1,4 @@ +# no optimization +AM_CFLAGS = -O0 +noinst_PROGRAMS = userspace-probe-elf-binary +userspace_probe_elf_binary_SOURCES = userspace-probe-elf-binary.c diff --git a/tests/utils/testapp/userspace-probe-elf-binary/userspace-probe-elf-binary.c b/tests/utils/testapp/userspace-probe-elf-binary/userspace-probe-elf-binary.c new file mode 100644 index 000000000..76f44027f --- /dev/null +++ b/tests/utils/testapp/userspace-probe-elf-binary/userspace-probe-elf-binary.c @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2017 Francis Deslauriers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +volatile int not_a_function = 0; +void __attribute__ ((noinline)) test_function() +{ + not_a_function += 1; +} +int main(int argc, char *argv[]) +{ + test_function(); + return 0; +} diff --git a/tests/utils/testapp/userspace-probe-elf-cxx-binary/Makefile.am b/tests/utils/testapp/userspace-probe-elf-cxx-binary/Makefile.am new file mode 100644 index 000000000..c11c1a68e --- /dev/null +++ b/tests/utils/testapp/userspace-probe-elf-cxx-binary/Makefile.am @@ -0,0 +1,4 @@ +# no optimization +AM_CPPFLAGS = -O0 +noinst_PROGRAMS = userspace-probe-elf-cxx-binary +userspace_probe_elf_cxx_binary_SOURCES = userspace-probe-elf-cxx-binary.cpp test_class.cpp test_class.h diff --git a/tests/utils/testapp/userspace-probe-elf-cxx-binary/test_class.cpp b/tests/utils/testapp/userspace-probe-elf-cxx-binary/test_class.cpp new file mode 100644 index 000000000..8c25f5145 --- /dev/null +++ b/tests/utils/testapp/userspace-probe-elf-cxx-binary/test_class.cpp @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2018 Francis Deslauriers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "test_class.h" + +void test_class::test_method() { + test_member += 1; +} diff --git a/tests/utils/testapp/userspace-probe-elf-cxx-binary/test_class.h b/tests/utils/testapp/userspace-probe-elf-cxx-binary/test_class.h new file mode 100644 index 000000000..889792dc5 --- /dev/null +++ b/tests/utils/testapp/userspace-probe-elf-cxx-binary/test_class.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2018 Francis Deslauriers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +class test_class +{ +public: + void test_method(); + volatile int test_member; +}; + + diff --git a/tests/utils/testapp/userspace-probe-elf-cxx-binary/userspace-probe-elf-cxx-binary.cpp b/tests/utils/testapp/userspace-probe-elf-cxx-binary/userspace-probe-elf-cxx-binary.cpp new file mode 100644 index 000000000..c1f44ee95 --- /dev/null +++ b/tests/utils/testapp/userspace-probe-elf-cxx-binary/userspace-probe-elf-cxx-binary.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2018 Francis Deslauriers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "test_class.h" + +volatile int not_a_function = 0; +void __attribute__ ((noinline)) test_cxx_function() +{ + not_a_function += 1; +} + +int main(int argc, char *argv[]) +{ + test_class my_test_class; + /* Call test function. */ + test_cxx_function(); + + /* Call test method. */ + my_test_class.test_method(); + return 0; +} diff --git a/tests/utils/testapp/userspace-probe-sdt-binary/Makefile.am b/tests/utils/testapp/userspace-probe-sdt-binary/Makefile.am new file mode 100644 index 000000000..e86939b4c --- /dev/null +++ b/tests/utils/testapp/userspace-probe-sdt-binary/Makefile.am @@ -0,0 +1,35 @@ +EXTRA_DIST = foobar_provider.d +BUILT_SOURCES = foobar_provider.h + +noinst_PROGRAMS = userspace-probe-sdt-binary +userspace_probe_sdt_binary_SOURCES = userspace-probe-sdt-binary.c sema.h sema.c +userspace_probe_sdt_binary_LDADD = foobar_provider.o libfoo.la libbar.la -ldl +userspace_probe_sdt_binary_CFLAGS = -I$(abs_builddir) +nodist_userspace_probe_sdt_binary_SOURCES = $(abs_builddir)/foobar_provider.h + +noinst_LTLIBRARIES = libfoo.la libbar.la libzzz.la +libfoo_la_SOURCES = libfoo.h libfoo.c +libfoo_la_LIBADD = foobar_provider.o +libfoo_la_CFLAGS = -I$(abs_builddir) +libfoo_la_LDFLAGS = -module -shared -avoid-version -rpath $(abs_builddir)/.libs/ +nodist_libfoo_la_SOURCES = $(abs_builddir)/foobar_provider.h + +libbar_la_SOURCES = libbar.h libbar.c +libbar_la_LIBADD = foobar_provider.o +libbar_la_CFLAGS = -I$(abs_builddir) +libbar_la_LDFLAGS = -module -shared -avoid-version -rpath $(abs_builddir)/.libs/ +nodist_libbar_la_SOURCES = $(abs_builddir)/foobar_provider.h + +libzzz_la_SOURCES = libzzz.h libzzz.c +libzzz_la_LIBADD = foobar_provider.o +libzzz_la_CFLAGS = -I$(abs_builddir) +libzzz_la_LDFLAGS = -module -shared -avoid-version -rpath $(abs_builddir)/.libs/ +nodist_libzzz_la_SOURCES = $(abs_builddir)/foobar_provider.h + +foobar_provider.h: foobar_provider.d + dtrace -s $< -o $@ -h + +foobar_provider.o: foobar_provider.d + dtrace -s $< -o $@ -G + +CLEANFILES = foobar_provider.h diff --git a/tests/utils/testapp/userspace-probe-sdt-binary/foobar_provider.d b/tests/utils/testapp/userspace-probe-sdt-binary/foobar_provider.d new file mode 100644 index 000000000..0d376af6e --- /dev/null +++ b/tests/utils/testapp/userspace-probe-sdt-binary/foobar_provider.d @@ -0,0 +1,9 @@ +provider foobar { + probe tp1(); + probe tp2(); + probe tp_in_shared_object(); + probe tp_in_dlopen(); + probe tp_in_ldpreload(); + probe tp_with_arg(int); + probe tp_with_semaphore(); +}; diff --git a/tests/utils/testapp/userspace-probe-sdt-binary/libbar.c b/tests/utils/testapp/userspace-probe-sdt-binary/libbar.c new file mode 100644 index 000000000..af84825b9 --- /dev/null +++ b/tests/utils/testapp/userspace-probe-sdt-binary/libbar.c @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2017 Francis Deslauriers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include "foobar_provider.h" +void bar_function() { + FOOBAR_TP_IN_DLOPEN(); +} diff --git a/tests/utils/testapp/userspace-probe-sdt-binary/libbar.h b/tests/utils/testapp/userspace-probe-sdt-binary/libbar.h new file mode 100644 index 000000000..00d96458f --- /dev/null +++ b/tests/utils/testapp/userspace-probe-sdt-binary/libbar.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2017 Francis Deslauriers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +int bar_function(); diff --git a/tests/utils/testapp/userspace-probe-sdt-binary/libfoo.c b/tests/utils/testapp/userspace-probe-sdt-binary/libfoo.c new file mode 100644 index 000000000..a1bf63246 --- /dev/null +++ b/tests/utils/testapp/userspace-probe-sdt-binary/libfoo.c @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2017 Francis Deslauriers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include +#include "foobar_provider.h" +void foo_function() { + FOOBAR_TP_IN_SHARED_OBJECT(); +} +void overridable_function() { +} diff --git a/tests/utils/testapp/userspace-probe-sdt-binary/libfoo.h b/tests/utils/testapp/userspace-probe-sdt-binary/libfoo.h new file mode 100644 index 000000000..3cdc61f05 --- /dev/null +++ b/tests/utils/testapp/userspace-probe-sdt-binary/libfoo.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2017 Francis Deslauriers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +int foo_function(); +void overridable_function(); diff --git a/tests/utils/testapp/userspace-probe-sdt-binary/libzzz.c b/tests/utils/testapp/userspace-probe-sdt-binary/libzzz.c new file mode 100644 index 000000000..f49569d12 --- /dev/null +++ b/tests/utils/testapp/userspace-probe-sdt-binary/libzzz.c @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2017 Francis Deslauriers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include +#include "foobar_provider.h" +void overridable_function() { + FOOBAR_TP_IN_LDPRELOAD(); +} diff --git a/tests/utils/testapp/userspace-probe-sdt-binary/libzzz.h b/tests/utils/testapp/userspace-probe-sdt-binary/libzzz.h new file mode 100644 index 000000000..84f46af6c --- /dev/null +++ b/tests/utils/testapp/userspace-probe-sdt-binary/libzzz.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2017 Francis Deslauriers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +int bar_function(); +void overridable_function(); diff --git a/tests/utils/testapp/userspace-probe-sdt-binary/sema.c b/tests/utils/testapp/userspace-probe-sdt-binary/sema.c new file mode 100644 index 000000000..a52921444 --- /dev/null +++ b/tests/utils/testapp/userspace-probe-sdt-binary/sema.c @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2017 Francis Deslauriers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "foobar_provider.h" +#include +void sema_function() { + FOOBAR_TP_WITH_SEMAPHORE(); +} diff --git a/tests/utils/testapp/userspace-probe-sdt-binary/sema.h b/tests/utils/testapp/userspace-probe-sdt-binary/sema.h new file mode 100644 index 000000000..4ca34bba0 --- /dev/null +++ b/tests/utils/testapp/userspace-probe-sdt-binary/sema.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2017 Francis Deslauriers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +void sema_function(); diff --git a/tests/utils/testapp/userspace-probe-sdt-binary/userspace-probe-sdt-binary.c b/tests/utils/testapp/userspace-probe-sdt-binary/userspace-probe-sdt-binary.c new file mode 100644 index 000000000..c70713979 --- /dev/null +++ b/tests/utils/testapp/userspace-probe-sdt-binary/userspace-probe-sdt-binary.c @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2017 Francis Deslauriers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "foobar_provider.h" +#include "libfoo.h" +#include "sema.h" + +int main(int argc, char *argv[]) +{ + void *handle; + void (*bar_function)(); + + FOOBAR_TP1(); + FOOBAR_TP2(); + /* + * This SDT tracepoint has an argument. Argument extraction is not support + * at the moment but tracing of the tracepoint should work. + */ + FOOBAR_TP_WITH_ARG(42); + + /* Call function containing an SDT tracepoint in shared object */ + foo_function(); + + /* + * Load a show shared object and call a function containing an SDT + * tracepoint + */ + handle = dlopen("libbar.so", RTLD_LAZY); + if (!handle) { + fprintf(stderr, "Can't dlopen libbar.so"); + return -1; + } + bar_function = (void (*)())dlsym(handle, "bar_function"); + bar_function(); + dlclose(handle); + + /* This tracepoint has 2 callsites in this binary */ + FOOBAR_TP2(); + + /* + * This function is defined in libfoo AND in libzzz. For a test, libzzz is + * LD_PRELOADed and should override this function + */ + overridable_function(); + + /* + * This function is calling a SDT tracepoint that is guarded by a + * semaphore. + */ + sema_function(); + return 0; +} + diff --git a/tests/utils/utils.sh b/tests/utils/utils.sh index 2343b4b28..f2393b9cf 100644 --- a/tests/utils/utils.sh +++ b/tests/utils/utils.sh @@ -270,6 +270,41 @@ function lttng_disable_kernel_syscall_fail() lttng_disable_kernel_syscall 1 "$@" } +function lttng_enable_kernel_userspace_probe_event () +{ + local expected_to_fail="$1" + local sess_name="$2" + local target="$3" + local event_name="$4" + + "$TESTDIR/../src/bin/lttng/$LTTNG_BIN" enable-event --kernel --userspace-probe="$target" "$event_name" -s "$sess_name" > "$OUTPUT_DEST" 2> "$ERROR_OUTPUT_DEST" + ret=$? + if [[ $expected_to_fail -eq "1" ]]; then + test $ret -ne "0" + ok $? "Enable kernel userspace probe event for session $sess_name failed as expected" + else + ok $ret "Enable kernel userspace probe event for session $sess_name" + fi +} + +function lttng_enable_kernel_userspace_probe_event_fail () +{ + lttng_enable_kernel_userspace_probe_event 1 "$@" +} + +function lttng_enable_kernel_userspace_probe_event_ok () +{ + lttng_enable_kernel_userspace_probe_event 0 "$@" +} + +function disable_kernel_lttng_userspace_probe_event_ok () +{ + local sess_name="$1" + local event_name="$2" + + "$TESTDIR/../src/bin/lttng/$LTTNG_BIN" disable-event --kernel "$event_name" -s "$sess_name" > "$OUTPUT_DEST" 2> "$ERROR_OUTPUT_DEST" + ok $? "Disable kernel event $target for session $sess_name" +} function lttng_enable_kernel_channel() { local withtap=$1 -- 2.34.1