From: Francis Deslauriers Date: Fri, 9 Feb 2018 21:56:52 +0000 (-0500) Subject: Tests: add duplicated providers tests X-Git-Tag: v2.11.0-rc1~221 X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=3f7f208a0150d93363cbf7755e890a9839114ab5;p=lttng-tools.git Tests: add duplicated providers tests Signed-off-by: Francis Deslauriers Signed-off-by: Jérémie Galarneau --- diff --git a/configure.ac b/configure.ac index f5b105e4b..60e76b03b 100644 --- a/configure.ac +++ b/configure.ac @@ -1088,6 +1088,7 @@ AC_CONFIG_FILES([ tests/regression/ust/buffers-pid/Makefile tests/regression/ust/periodical-metadata-flush/Makefile tests/regression/ust/multi-session/Makefile + tests/regression/ust/multi-lib/Makefile tests/regression/ust/overlap/Makefile tests/regression/ust/overlap/demo/Makefile tests/regression/ust/linking/Makefile diff --git a/tests/fast_regression b/tests/fast_regression index bbce068f7..f76b53dc2 100644 --- a/tests/fast_regression +++ b/tests/fast_regression @@ -21,6 +21,7 @@ regression/tools/regen-statedump/test_ust regression/ust/before-after/test_before_after regression/ust/buffers-pid/test_buffers_pid regression/ust/multi-session/test_multi_session +regression/ust/multi-lib/test_multi_lib regression/ust/nprocesses/test_nprocesses regression/ust/overlap/test_overlap regression/ust/java-jul/test_java_jul diff --git a/tests/regression/Makefile.am b/tests/regression/Makefile.am index b1642812a..50e89e4c5 100644 --- a/tests/regression/Makefile.am +++ b/tests/regression/Makefile.am @@ -46,7 +46,8 @@ TESTS += ust/before-after/test_before_after \ ust/test_event_basic \ ust/test_event_tracef \ ust/test_event_perf \ - ust/blocking/test_blocking + ust/blocking/test_blocking \ + ust/multi-lib/test_multi_lib endif # HAVE_LIBLTTNG_UST_CTL if PYTHON_BINDING diff --git a/tests/regression/ust/Makefile.am b/tests/regression/ust/Makefile.am index 06cf97a47..6237b1610 100644 --- a/tests/regression/ust/Makefile.am +++ b/tests/regression/ust/Makefile.am @@ -3,7 +3,7 @@ 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 type-declarations \ - rotation-destroy-flush blocking + rotation-destroy-flush blocking multi-lib if HAVE_OBJCOPY SUBDIRS += baddr-statedump ust-dl diff --git a/tests/regression/ust/multi-lib/Makefile.am b/tests/regression/ust/multi-lib/Makefile.am new file mode 100644 index 000000000..3fb4ae74e --- /dev/null +++ b/tests/regression/ust/multi-lib/Makefile.am @@ -0,0 +1,129 @@ +noinst_SCRIPTS = test_multi_lib +EXTRA_DIST = test_multi_lib +noinst_PROGRAMS = exec-with-callsites exec-without-callsites + +exec_with_callsites_SOURCES = multi-lib-test.c callsites.c +exec_with_callsites_LDFLAGS = -ldl -lpopt +exec_with_callsites_CFLAGS = $(AM_CFLAGS) -DHAS_CALLSITES=1 + +exec_without_callsites_SOURCES = multi-lib-test.c +exec_without_callsites_LDFLAGS = -ldl -lpopt -llttng-ust +exec_without_callsites_LDADD = probes.o +exec_without_callsites_CFLAGS = $(AM_CFLAGS) -DHAS_CALLSITES=0 + +PROBES_SRC=probes.c probes.h +PROBES_LDF=-shared -module -llttng-ust -avoid-version -rpath $(abs_builddir)/.libs/ +PROBES_CF=$(AM_CFLAGS) $(AM_CPPFLAGS) $(CFLAGS) $(CPPFLAGS) -c -I$(srcdir)/ + +probes.o: probes.c probes.h + $(CC) $(PROBES_CF) -o $@ $< + +noinst_LTLIBRARIES = libprobes_a.la libprobes_a_prime.la \ + libprobes_b.la libprobes_c.la libprobes_c_prime.la \ + libprobes_d.la libprobes_e.la libprobes_f.la \ + libprobes_g.la libprobes_h.la libprobes_i.la \ + libprobes_j.la libprobes_k.la libprobes_l.la \ + libprobes_m.la libprobes_n.la libprobes_o.la \ + libprobes_p.la + +noinst_LTLIBRARIES += libcallsites_1.la libcallsites_2.la + +CALLSITES_SRC=callsites.c callsites.h +CALLSITES_LDF=-shared -module -llttng-ust -avoid-version -rpath $(abs_builddir)/.libs/ +CALLSITES_CF=-c -I. + +libprobes_a_la_SOURCES = $(PROBES_SRC) +libprobes_a_la_LDFLAGS = $(PROBES_LDF) +libprobes_a_la_CFLAGS = $(AM_CFLAGS) $(PROBES_CF) -DACTIVATE_PROBES_A + +libprobes_a_prime_la_SOURCES = $(PROBES_SRC) +libprobes_a_prime_la_LDFLAGS = $(PROBES_LDF) +libprobes_a_prime_la_CFLAGS = $(AM_CFLAGS) $(PROBES_CF) -DACTIVATE_PROBES_A + +libprobes_b_la_SOURCES = $(PROBES_SRC) +libprobes_b_la_LDFLAGS = $(PROBES_LDF) +libprobes_b_la_CFLAGS = $(AM_CFLAGS) $(PROBES_CF) -DACTIVATE_PROBES_B + +libprobes_c_la_SOURCES = $(PROBES_SRC) +libprobes_c_la_LDFLAGS = $(PROBES_LDF) +libprobes_c_la_CFLAGS = $(AM_CFLAGS) $(PROBES_CF) -DACTIVATE_PROBES_C + +libprobes_c_prime_la_SOURCES = $(PROBES_SRC) +libprobes_c_prime_la_LDFLAGS = $(PROBES_LDF) +libprobes_c_prime_la_CFLAGS = $(AM_CFLAGS) $(PROBES_CF) -DACTIVATE_PROBES_C + +libprobes_d_la_SOURCES = $(PROBES_SRC) +libprobes_d_la_LDFLAGS = $(PROBES_LDF) +libprobes_d_la_CFLAGS = $(AM_CFLAGS) $(PROBES_CF) -DACTIVATE_PROBES_D + +libprobes_e_la_SOURCES = $(PROBES_SRC) +libprobes_e_la_LDFLAGS = $(PROBES_LDF) +libprobes_e_la_CFLAGS = $(AM_CFLAGS) $(PROBES_CF) -DACTIVATE_PROBES_E + +libprobes_f_la_SOURCES = $(PROBES_SRC) +libprobes_f_la_LDFLAGS = $(PROBES_LDF) +libprobes_f_la_CFLAGS = $(AM_CFLAGS) $(PROBES_CF) -DACTIVATE_PROBES_F + +libprobes_g_la_SOURCES = $(PROBES_SRC) +libprobes_g_la_LDFLAGS = $(PROBES_LDF) +libprobes_g_la_CFLAGS = $(AM_CFLAGS) $(PROBES_CF) -DACTIVATE_PROBES_G + +libprobes_h_la_SOURCES = $(PROBES_SRC) +libprobes_h_la_LDFLAGS = $(PROBES_LDF) +libprobes_h_la_CFLAGS = $(AM_CFLAGS) $(PROBES_CF) -DACTIVATE_PROBES_H + +libprobes_i_la_SOURCES = $(PROBES_SRC) +libprobes_i_la_LDFLAGS = $(PROBES_LDF) +libprobes_i_la_CFLAGS = $(AM_CFLAGS) $(PROBES_CF) -DACTIVATE_PROBES_I + +libprobes_j_la_SOURCES = $(PROBES_SRC) +libprobes_j_la_LDFLAGS = $(PROBES_LDF) +libprobes_j_la_CFLAGS = $(AM_CFLAGS) $(PROBES_CF) -DACTIVATE_PROBES_J + +libprobes_k_la_SOURCES = $(PROBES_SRC) +libprobes_k_la_LDFLAGS = $(PROBES_LDF) +libprobes_k_la_CFLAGS = $(AM_CFLAGS) $(PROBES_CF) -DACTIVATE_PROBES_K + +libprobes_l_la_SOURCES = $(PROBES_SRC) +libprobes_l_la_LDFLAGS = $(PROBES_LDF) +libprobes_l_la_CFLAGS = $(AM_CFLAGS) $(PROBES_CF) -DACTIVATE_PROBES_L + +libprobes_m_la_SOURCES = $(PROBES_SRC) +libprobes_m_la_LDFLAGS = $(PROBES_LDF) +libprobes_m_la_CFLAGS = $(AM_CFLAGS) $(PROBES_CF) -DACTIVATE_PROBES_M + +libprobes_n_la_SOURCES = $(PROBES_SRC) +libprobes_n_la_LDFLAGS = $(PROBES_LDF) +libprobes_n_la_CFLAGS = $(AM_CFLAGS) $(PROBES_CF) -DACTIVATE_PROBES_N + +libprobes_o_la_SOURCES = $(PROBES_SRC) +libprobes_o_la_LDFLAGS = $(PROBES_LDF) +libprobes_o_la_CFLAGS = $(AM_CFLAGS) $(PROBES_CF) -DACTIVATE_PROBES_O + +libprobes_p_la_SOURCES = $(PROBES_SRC) +libprobes_p_la_LDFLAGS = $(PROBES_LDF) +libprobes_p_la_CFLAGS = $(AM_CFLAGS) $(PROBES_CF) -DACTIVATE_PROBES_P + +libcallsites_1_la_SOURCES = $(CALLSITES_SRC) +libcallsites_1_la_LDFLAGS = $(CALLSITES_LDF) +libcallsites_1_la_CFLAGS = $(AM_CFLAGS) $(CALLSITES_CF) -DVALUE=11111 + +libcallsites_2_la_SOURCES = $(CALLSITES_SRC) +libcallsites_2_la_LDFLAGS = $(CALLSITES_LDF) +libcallsites_2_la_CFLAGS = $(AM_CFLAGS) $(CALLSITES_CF) -DVALUE=22222 + +CLEANFILES=probes.o + +all-local: + @if [ x"$(srcdir)" != x"$(builddir)" ]; then \ + for script in $(EXTRA_DIST); do \ + cp -f $(srcdir)/$$script $(builddir); \ + done; \ + fi + +clean-local: + @if [ x"$(srcdir)" != x"$(builddir)" ]; then \ + for script in $(EXTRA_DIST); do \ + rm -f $(builddir)/$$script; \ + done; \ + fi diff --git a/tests/regression/ust/multi-lib/README b/tests/regression/ust/multi-lib/README new file mode 100644 index 000000000..15b969f81 --- /dev/null +++ b/tests/regression/ust/multi-lib/README @@ -0,0 +1,21 @@ +Those test cases are designed to test the support for loading and unloading +probe providers and callsites at run time during tracing. One test case also +tests the event payload comparaison functions. + +Testing build artefacts: +------------------------ + +./exec-with-callsites + Test binary built with tracepoint callsites + +./exec-without-callsites + Test binary built without tracepoint callsites + +/.libs/libprobe_*.so: + Libraries containing slight variations of probe providers for the same + tracepoint name. Note that the file /.libs/libprobes_a_prime.so has the same + content as .libs/libprobes_a.so likewise for libprobes_c_prime.so + +/.libs/libcallsites_*.so + Libraries containing tracepoint callsites. The user must dlopen the library + and use dlsym to get an handle on the function that calls the tracepoint. diff --git a/tests/regression/ust/multi-lib/callsites.c b/tests/regression/ust/multi-lib/callsites.c new file mode 100644 index 000000000..4b61ac203 --- /dev/null +++ b/tests/regression/ust/multi-lib/callsites.c @@ -0,0 +1,34 @@ +/* + * 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; 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 + */ + +#define TRACEPOINT_DEFINE +#define TRACEPOINT_PROBE_DYNAMIC_LINKAGE +#include "probes.h" + +#include +#include +#include +#include + +#ifndef VALUE +#define VALUE (-1) +#endif + +void call_tracepoint(void) { + tracepoint(multi, tp, VALUE); +} + diff --git a/tests/regression/ust/multi-lib/callsites.h b/tests/regression/ust/multi-lib/callsites.h new file mode 100644 index 000000000..547a6a659 --- /dev/null +++ b/tests/regression/ust/multi-lib/callsites.h @@ -0,0 +1,21 @@ +/* + * 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; 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 + */ + +#ifndef CALLSITES_H +#define CALLSITES_H +void call_tracepoint(); +#endif /* CALLSITES_H */ diff --git a/tests/regression/ust/multi-lib/multi-lib-test.c b/tests/regression/ust/multi-lib/multi-lib-test.c new file mode 100644 index 000000000..e145aa21a --- /dev/null +++ b/tests/regression/ust/multi-lib/multi-lib-test.c @@ -0,0 +1,247 @@ +/* + * 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; 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 + */ + +#include +#include +#include +#include +#include + +#if HAS_CALLSITES +#include "callsites.h" +#endif + +void exec_callsite() +{ +#if HAS_CALLSITES + call_tracepoint(); +#endif +} + +void print_list(void) +{ + fprintf(stderr, "Test list (-t X):\n"); + fprintf(stderr, "\t0: dlopen() all libraries pass in arguments and execute " + "the callsite.\n"); + fprintf(stderr, "\t1: simulate the upgrade of a probe provider using dlopen() and dlclose(). \n"); + fprintf(stderr, "\t2: simulate the upgrade of a library containing the callsites using dlopen() and dlclose(). \n"); +} + +int dl_open_all(int nb_libraries, char **libraries) +{ + int i, ret = 0; + void **handles; + + handles = malloc(nb_libraries * sizeof(void *)); + if (!handles) { + ret = -1; + goto error; + } + + /* Iterate over the libs to dlopen and save the handles. */ + for (i = 0; i < nb_libraries; i++) { + handles[i] = dlopen(libraries[i], RTLD_NOW); + if (!handles[i]) { + ret = -1; + goto error; + } + } + + exec_callsite(); +error: + free(handles); + return ret; +} + +/* + * Takes 2 paths to libraries, dlopen() the first, trace, dlopen() the second, + * and dlclose the first to simulate the upgrade of a library. + */ +int upgrade_lib(int nb_libraries, char **libraries) +{ + int i, ret = 0; + void *handles[2]; + + if (nb_libraries != 2) { + ret = -1; + goto error; + } + + /* Iterate over the libs to dlopen and save the handles. */ + for (i = 0; i < nb_libraries; i++) { + handles[i] = dlopen(libraries[i], RTLD_NOW); + if (!handles[i]) { + ret = -1; + goto error; + } + + exec_callsite(); + } + + ret = dlclose(handles[0]); + if (ret) { + goto error; + } + + exec_callsite(); + +error: + return ret; +} + +/* + * Simulate the upgrade of a library containing a callsite. + * Receives two libraries containing callsites for the same tracepoint. + */ +int upgrade_callsite(int nb_libraries, char **libraries) +{ + int ret = 0; + void *handles[2]; + void (*fct_ptr[2])(void); + + if (nb_libraries != 2) { + ret = -1; + goto error; + } + + /* Load the probes in the first library. */ + handles[0] = dlopen(libraries[0], RTLD_NOW); + if (!handles[0]) { + ret = -1; + goto error; + } + + /* + * Get the pointer to the old function containing the callsite and call it. + */ + fct_ptr[0] = dlsym(handles[0], "call_tracepoint"); + if (!fct_ptr[0]) { + ret = -1; + goto error; + } + fct_ptr[0](); + + /* Load the new callsite library. */ + handles[1] = dlopen(libraries[1], RTLD_NOW); + if (!handles[1]) { + ret = -1; + goto error; + } + + /* + * Get the pointer to the new function containing the callsite and call it. + */ + fct_ptr[1] = dlsym(handles[1], "call_tracepoint"); + if (!fct_ptr[1]) { + ret = -1; + goto error; + } + fct_ptr[1](); + + /* Unload the old callsite library. */ + ret = dlclose(handles[0]); + if (ret) { + goto error; + } + + /* Call the function containing the callsite in the new library. */ + fct_ptr[1](); + + ret = dlclose(handles[1]); + if (ret) { + goto error; + } + +error: + return ret; +} + +int main(int argc, const char **argv) +{ + int c, ret = 0, test = -1, nb_libraries = 0; + char **libraries = NULL; + poptContext optCon; + struct poptOption optionsTable[] = { + { "test", 't', POPT_ARG_INT, &test, 0, "Test to run", NULL }, + { "list", 'l', 0, 0, 'l', "List of tests (-t X)", NULL }, + POPT_AUTOHELP + { NULL, 0, 0, NULL, 0 } + }; + + optCon = poptGetContext(NULL, argc, argv, optionsTable, 0); + if (argc < 2) { + poptPrintUsage(optCon, stderr, 0); + ret = -1; + goto error; + } + + while ((c = poptGetNextOpt(optCon)) >= 0) { + switch(c) { + case 'l': + print_list(); + goto error; + } + } + + /* + * Populate the libraries array with the arguments passed to the process. + */ + while (poptPeekArg(optCon) != NULL) { + nb_libraries++; + libraries = realloc(libraries, nb_libraries * sizeof(char *)); + if (!libraries) { + ret = -1; + goto error; + } + libraries[nb_libraries - 1] = (char *) poptGetArg(optCon); + } + + switch(test) { + case 0: +#if HAS_CALLSITES + ret = dl_open_all(nb_libraries, libraries); +#else + fprintf(stderr, "Test not implemented for configuration " + "(HAS_CALLSITES=%d)\n", HAS_CALLSITES == 1); +#endif + break; + case 1: +#if HAS_CALLSITES + ret = upgrade_lib(nb_libraries, libraries); +#else + fprintf(stderr, "Test not implemented for configuration " + "(HAS_CALLSITES=%d)\n", HAS_CALLSITES == 1); +#endif + break; + case 2: +#if !HAS_CALLSITES + ret = upgrade_callsite(nb_libraries, libraries); +#else + fprintf(stderr, "Test not implemented for configuration " + "(HAS_CALLSITES=%d)\n", HAS_CALLSITES == 1); +#endif + break; + default: + fprintf(stderr, "Test %d not implemented\n", test); + ret = -1; + break; + } +error: + free(libraries); + poptFreeContext(optCon); + return ret; +} diff --git a/tests/regression/ust/multi-lib/probes.c b/tests/regression/ust/multi-lib/probes.c new file mode 100644 index 000000000..3ee9164ad --- /dev/null +++ b/tests/regression/ust/multi-lib/probes.c @@ -0,0 +1,18 @@ +/* + * 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; 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 + */ +#define TRACEPOINT_CREATE_PROBES +#include "probes.h" diff --git a/tests/regression/ust/multi-lib/probes.h b/tests/regression/ust/multi-lib/probes.h new file mode 100644 index 000000000..31e6ec3b3 --- /dev/null +++ b/tests/regression/ust/multi-lib/probes.h @@ -0,0 +1,196 @@ +/* + * 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; 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 + */ + +#undef TRACEPOINT_PROVIDER +#define TRACEPOINT_PROVIDER multi + +#undef TRACEPOINT_INCLUDE +#define TRACEPOINT_INCLUDE "./probes.h" + +#if !defined(PROBES_H) || defined(TRACEPOINT_HEADER_MULTI_READ) +#define PROBES_H + +#include +#include + +#if defined(ACTIVATE_PROBES_A) +TRACEPOINT_EVENT(multi, tp, + TP_ARGS(uint64_t, arg), + TP_FIELDS( + ctf_integer(uint64_t, arg_long_A, arg) + ) +) +#elif defined(ACTIVATE_PROBES_B) +TRACEPOINT_EVENT(multi, tp, + TP_ARGS(uint64_t, arg), + TP_FIELDS( + ctf_integer(uint64_t, arg_long_B, arg) + ctf_float(float, arg_float_B, (float) arg) + ) +) +#elif defined(ACTIVATE_PROBES_C) +TRACEPOINT_ENUM(multi, enum_a, + TP_ENUM_VALUES( + ctf_enum_value("FIELD_A", 0) + ctf_enum_value("FIELD_B", 1) + ctf_enum_range("RANGE_C", 2, 10) + ) +) +TRACEPOINT_EVENT(multi, tp, + TP_ARGS(uint64_t, arg), + TP_FIELDS( + ctf_enum(multi, enum_a, int16_t, enum_short_C, 0) + ctf_enum(multi, enum_a, int32_t, enum_int_C, 1) + ctf_enum(multi, enum_a, uint64_t, enum_long_C, 2) + ) +) +#elif defined(ACTIVATE_PROBES_D) +TRACEPOINT_ENUM(multi, enum_a, + TP_ENUM_VALUES( + ctf_enum_value("FIELD_A", 0) + ctf_enum_value("FIELD_B", 1) + ctf_enum_range("RANGE_C_PRIME", 2, 10) + ) +) +TRACEPOINT_EVENT(multi, tp, + TP_ARGS(uint64_t, arg), + TP_FIELDS( + ctf_enum(multi, enum_a, int32_t, enum_int_D, 1) + ctf_enum(multi, enum_a, int16_t, enum_short_D, 0) + ctf_enum(multi, enum_a, uint64_t, enum_long_D, 2) + ) +) +#elif defined(ACTIVATE_PROBES_E) +/* + * Here we declare tracepoints really similar to one another but are different. + * This is meant to test tracepoint comparaison code. + */ +TRACEPOINT_EVENT(multi, tp, + TP_ARGS(uint64_t, arg), + TP_FIELDS( + ctf_integer(uint64_t, arg_long, arg) + ) +) +#elif defined(ACTIVATE_PROBES_F) +TRACEPOINT_EVENT(multi, tp, + TP_ARGS(uint64_t, arg), + TP_FIELDS( + ctf_integer(int64_t, arg_long, arg) + ) +) +#elif defined(ACTIVATE_PROBES_G) +TRACEPOINT_EVENT(multi, tp, + TP_ARGS(uint64_t, arg), + TP_FIELDS( + ctf_integer_hex(int64_t, arg_long, arg) + ) +) +#elif defined(ACTIVATE_PROBES_H) +TRACEPOINT_EVENT(multi, tp, + TP_ARGS(uint64_t, arg), + TP_FIELDS( + ctf_integer_hex(int16_t, arg_long, arg) + ) +) +#elif defined(ACTIVATE_PROBES_I) +TRACEPOINT_EVENT(multi, tp, + TP_ARGS(uint64_t, arg), + TP_FIELDS( + ctf_integer_hex(int32_t, arg_long, arg) + ) +) +#elif defined(ACTIVATE_PROBES_J) +TRACEPOINT_EVENT(multi, tp, + TP_ARGS(uint64_t, arg), + TP_FIELDS( + ctf_float(float, arg_float, (float) arg) + ) +) +#elif defined(ACTIVATE_PROBES_K) +TRACEPOINT_EVENT(multi, tp, + TP_ARGS(uint64_t, arg), + TP_FIELDS( + ctf_float(double, arg_float, (double) arg) + ) +) +#elif defined(ACTIVATE_PROBES_L) +TRACEPOINT_ENUM(multi, enum_a, + TP_ENUM_VALUES( + ctf_enum_value("FIELD_A", 0) + ctf_enum_value("FIELD_B", 1) + ctf_enum_range("RANGE_C", 2, 10) + ) +) +TRACEPOINT_EVENT(multi, tp, + TP_ARGS(uint64_t, arg), + TP_FIELDS( + ctf_enum(multi, enum_a, int32_t, enum_int, 1) + ) +) +#elif defined(ACTIVATE_PROBES_M) +TRACEPOINT_ENUM(multi, enum_a, + TP_ENUM_VALUES( + ctf_enum_value("FIELD_A", 0) + ctf_enum_value("FIELD_B", 1) + ctf_enum_range("RANGE_C", 2, 10) + ) +) +TRACEPOINT_EVENT(multi, tp, + TP_ARGS(uint64_t, arg), + TP_FIELDS( + ctf_enum(multi, enum_a, int64_t, enum_int, 1) + ) +) +#elif defined(ACTIVATE_PROBES_N) +TRACEPOINT_ENUM(multi, enum_a, + TP_ENUM_VALUES( + ctf_enum_value("FIELD_A", 0) + ctf_enum_value("FIELD_B", 1) + ctf_enum_range("RANGE_C", 2, 10) + ) +) +TRACEPOINT_EVENT(multi, tp, + TP_ARGS(uint64_t, arg), + TP_FIELDS( + ctf_enum(multi, enum_a, int16_t, enum_int, 1) + ) +) +#elif defined(ACTIVATE_PROBES_O) +TRACEPOINT_EVENT(multi, tp, + TP_ARGS(uint64_t, arg), + TP_FIELDS( + ctf_string(arg_string, "string") + ) +) +#elif defined(ACTIVATE_PROBES_P) +TRACEPOINT_EVENT(multi, tp, + TP_ARGS(uint64_t, arg), + TP_FIELDS( + ctf_string(my_arg_string, "string") + ) +) +#else +TRACEPOINT_EVENT(multi, tp, + TP_ARGS(uint64_t, arg), + TP_FIELDS( + ) +) +#endif + +#endif /* PROBES_H */ + +#include diff --git a/tests/regression/ust/multi-lib/test_multi_lib b/tests/regression/ust/multi-lib/test_multi_lib new file mode 100755 index 000000000..d66230ac8 --- /dev/null +++ b/tests/regression/ust/multi-lib/test_multi_lib @@ -0,0 +1,262 @@ +#!/bin/bash +# +# 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; 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="UST - Dynamic loading and unloading of libraries" + +CURDIR=$(dirname $0)/ +TESTDIR=$CURDIR/../../.. +SESSION_NAME="multi_lib" + +EXEC_NAME_WITH_CALLSITES=./$CURDIR/exec-with-callsites +EXEC_NAME_WITHOUT_CALLSITES=./$CURDIR/exec-without-callsites +SO_DIR=$CURDIR/.libs/ +SO_PROBES_A=$SO_DIR/libprobes_a.so +SO_PROBES_A_PRIME=$SO_DIR/libprobes_a_prime.so +SO_PROBES_B=$SO_DIR/libprobes_b.so +SO_PROBES_C=$SO_DIR/libprobes_c.so +SO_PROBES_C_PRIME=$SO_DIR/libprobes_c_prime.so +SO_PROBES_D=$SO_DIR/libprobes_d.so +SO_CALLSITE_1=$SO_DIR/libcallsites_1.so +SO_CALLSITE_2=$SO_DIR/libcallsites_2.so + +NUM_TESTS=55 + +source $TESTDIR/utils/utils.sh + +test_dlopen_same_provider_name_same_event() +{ + local event_name="multi:tp" + diag "dlopen 2 providers, same event name, same payload" + + enable_ust_lttng_event_ok $SESSION_NAME "$event_name" + + start_lttng_tracing_ok $SESSION_NAME + + $EXEC_NAME_WITH_CALLSITES -t 0 $SO_PROBES_A $SO_PROBES_A_PRIME + + stop_lttng_tracing_ok $SESSION_NAME + + # Expect 2 identical events in the trace + trace_match_only $event_name 2 $TRACE_PATH + + # Expect a single event ID in the metadata + validate_metadata_event $event_name 1 $TRACE_PATH + + return $? +} + +test_dlopen_same_provider_name_different_event() +{ + local event_name="multi:tp" + # Regular expression for event tp with one argument: arg_long + local event_a_payload_exp="^.*$event_name.*arg_long_A.*" + # Regular expression for event tp with two arguments: arg_long and + # arg_float + local event_b_payload_exp="^.*$event_name.*arg_long_B.*arg_float_B.*" + diag "dlopen 2 providers, same event name, different payload" + + enable_ust_lttng_event_ok $SESSION_NAME "$event_name" + + start_lttng_tracing_ok $SESSION_NAME + + $EXEC_NAME_WITH_CALLSITES -t 0 $SO_PROBES_A $SO_PROBES_B + + stop_lttng_tracing_ok $SESSION_NAME + + # Expect 2 identical events in the trace + trace_match_only $event_name 2 $TRACE_PATH + + # Expect 2 events ID in the metadata + validate_metadata_event $event_name 2 $TRACE_PATH + + # Expect 2 events with different payloads + validate_trace_exp $event_a_payload_exp $TRACE_PATH + validate_trace_exp $event_b_payload_exp $TRACE_PATH + + return $? +} + +test_dlopen_same_provider_name_same_enum() +{ + local event_name="multi:tp" + # Regular expression for event tp with one argument: arg_long + local event_c_payload_exp="^.*$event_name.*enum_int_C.*" + # Regular expression for event tp with two arguments: arg_long and + # arg_float + local event_d_payload_exp="^.*$event_name.*enum_int_D.*" + diag "dlopen 2 providers, same event name, same enum definition" + + enable_ust_lttng_event_ok $SESSION_NAME "$event_name" + + start_lttng_tracing_ok $SESSION_NAME + + $EXEC_NAME_WITH_CALLSITES -t 0 $SO_PROBES_C $SO_PROBES_C_PRIME + + stop_lttng_tracing_ok $SESSION_NAME + + # Expect 2 identical events in the trace + trace_match_only $event_name 2 $TRACE_PATH + + # Expect 2 events ID in the metadata + validate_metadata_event $event_name 1 $TRACE_PATH + + return $? +} + +test_dlopen_same_provider_name_different_enum() +{ + local event_name="multi:tp" + # Regular expression for event tp with one argument: arg_long + local event_c_payload_exp="^.*$event_name.*enum_int_C.*" + # Regular expression for event tp with two arguments: arg_long and + # arg_float + local event_d_payload_exp="^.*$event_name.*enum_int_D.*" + diag "dlopen 2 providers, same event name, different enum definition" + + enable_ust_lttng_event_ok $SESSION_NAME "$event_name" + + start_lttng_tracing_ok $SESSION_NAME + + $EXEC_NAME_WITH_CALLSITES -t 0 $SO_PROBES_C $SO_PROBES_D + + stop_lttng_tracing_ok $SESSION_NAME + + # Expect 2 identical events in the trace + trace_match_only $event_name 2 $TRACE_PATH + + # Expect 2 events ID in the metadata + validate_metadata_event $event_name 2 $TRACE_PATH + + # Expect 2 events with different payloads + validate_trace_exp $event_c_payload_exp $TRACE_PATH + validate_trace_exp $event_d_payload_exp $TRACE_PATH + + return $? +} + +test_upgrade_probes_dlopen_dclose() +{ + local event_name="multi:tp" + diag "Upgrade probe provider using dlopen/dlclose during tracing" + + enable_ust_lttng_event_ok $SESSION_NAME "$event_name" + + start_lttng_tracing_ok $SESSION_NAME + + $EXEC_NAME_WITH_CALLSITES -t 1 $SO_PROBES_A $SO_PROBES_B + + stop_lttng_tracing_ok $SESSION_NAME + + # Expect 2 identical events in the trace + trace_match_only $event_name 4 $TRACE_PATH + + # Expect 2 events ID in the metadata + validate_metadata_event $event_name 2 $TRACE_PATH + + return $? +} + +test_upgrade_callsites_dlopen_dclose() +{ + local event_name="multi:tp" + diag "Upgrade callsite using dlopen/dlclose during tracing" + + enable_ust_lttng_event_ok $SESSION_NAME "$event_name" + + start_lttng_tracing_ok $SESSION_NAME + + $EXEC_NAME_WITHOUT_CALLSITES -t 2 $SO_CALLSITE_1 $SO_CALLSITE_2 + + stop_lttng_tracing_ok $SESSION_NAME + + # Expect 2 identical events in the trace + trace_match_only $event_name 3 $TRACE_PATH + + # Expect 2 events ID in the metadata + validate_metadata_event $event_name 1 $TRACE_PATH + + return $? +} + +test_event_field_comparison() +{ + local event_name="multi:tp" + diag "Load mutliple events with slight variations in the field descriptions." + + local library_prefix="libprobes_" + local nb_libs=0 + local library_list=" " + # Concatenate all the probe libraries in a string. + for postfix in {a..p}; do + library_list="$library_list $SO_DIR/$library_prefix$postfix.so" + let nb_libs+=1 + done + + enable_ust_lttng_event_ok $SESSION_NAME "$event_name" + + start_lttng_tracing_ok $SESSION_NAME + + $EXEC_NAME_WITH_CALLSITES -t 0 $library_list + + stop_lttng_tracing_ok $SESSION_NAME + + # Expect $nb_libs identical events in the trace + trace_match_only $event_name $nb_libs $TRACE_PATH + + # Expect $nb_libs events ID in the metadata + validate_metadata_event $event_name $nb_libs $TRACE_PATH + + return $? +} + + +plan_tests $NUM_TESTS + +print_test_banner "$TEST_DESC" + +TESTS=( + "test_dlopen_same_provider_name_same_event" + "test_dlopen_same_provider_name_different_event" + "test_dlopen_same_provider_name_different_enum" + "test_dlopen_same_provider_name_same_enum" + "test_event_field_comparison" + "test_upgrade_probes_dlopen_dclose" + "test_upgrade_callsites_dlopen_dclose" +) + +TEST_COUNT=${#TESTS[@]} +i=0 + +start_lttng_sessiond + +while [ "$i" -lt "$TEST_COUNT" ]; do + + TRACE_PATH=$(mktemp -d) + + create_lttng_session_ok $SESSION_NAME $TRACE_PATH + + # Execute test + ${TESTS[$i]} + + destroy_lttng_session_ok $SESSION_NAME + + rm -rf $TRACE_PATH + + let "i++" +done + +stop_lttng_sessiond