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
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
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
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
--- /dev/null
+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
--- /dev/null
+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.
--- /dev/null
+/*
+ * Copyright (C) - 2018 Francis Deslauriers <francis.deslauriers@efficios.com>
+ *
+ * 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 <stdint.h>
+#include <stdio.h>
+#include <time.h>
+#include <pthread.h>
+
+#ifndef VALUE
+#define VALUE (-1)
+#endif
+
+void call_tracepoint(void) {
+ tracepoint(multi, tp, VALUE);
+}
+
--- /dev/null
+/*
+ * Copyright (C) - 2018 Francis Deslauriers <francis.deslauriers@efficios.com>
+ *
+ * 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 */
--- /dev/null
+/*
+ * Copyright (C) - 2018 Francis Deslauriers <francis.deslauriers@efficios.com>
+ *
+ * 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 <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <popt.h>
+
+#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;
+}
--- /dev/null
+/*
+ * Copyright (C) - 2018 Francis Deslauriers <francis.deslauriers@efficios.com>
+ *
+ * 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"
--- /dev/null
+/*
+ * Copyright (C) - 2018 Francis Deslauriers <francis.deslauriers@efficios.com>
+ *
+ * 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 <lttng/tracepoint.h>
+#include <stdint.h>
+
+#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 <lttng/tracepoint-event.h>
--- /dev/null
+#!/bin/bash
+#
+# Copyright (C) - 2018 Francis Deslauriers <francis.deslauriers@efficios.com>
+#
+# 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