Signed-off-by: Francis Deslauriers <francis.deslauri...@efficios.com>
---
 configure.ac                                    |   1 +
 tests/fast_regression                           |   1 +
 tests/regression/ust/multi-lib/Makefile.am      | 114 +++++++++++
 tests/regression/ust/multi-lib/README           |  21 ++
 tests/regression/ust/multi-lib/callsites.c      |  34 +++
 tests/regression/ust/multi-lib/callsites.h      |  21 ++
 tests/regression/ust/multi-lib/multi-lib-test.c | 251 +++++++++++++++++++++++
 tests/regression/ust/multi-lib/probes.c         |  18 ++
 tests/regression/ust/multi-lib/probes.h         | 195 ++++++++++++++++++
 tests/regression/ust/multi-lib/test_multi_lib   | 262 ++++++++++++++++++++++++
 10 files changed, 918 insertions(+)
 create mode 100644 tests/regression/ust/multi-lib/Makefile.am
 create mode 100644 tests/regression/ust/multi-lib/README
 create mode 100644 tests/regression/ust/multi-lib/callsites.c
 create mode 100644 tests/regression/ust/multi-lib/callsites.h
 create mode 100644 tests/regression/ust/multi-lib/multi-lib-test.c
 create mode 100644 tests/regression/ust/multi-lib/probes.c
 create mode 100644 tests/regression/ust/multi-lib/probes.h
 create mode 100755 tests/regression/ust/multi-lib/test_multi_lib

diff --git a/configure.ac b/configure.ac
index b6ea39c..e22872c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1090,6 +1090,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 bbce068..f76b53d 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/ust/multi-lib/Makefile.am 
b/tests/regression/ust/multi-lib/Makefile.am
new file mode 100644
index 0000000..f78ce7f
--- /dev/null
+++ b/tests/regression/ust/multi-lib/Makefile.am
@@ -0,0 +1,114 @@
+noinst_SCRIPTS = 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 = -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 = -DHAS_CALLSITES=0
+
+PROBES_SRC=probes.c probes.h
+PROBES_LDF=-shared -module -llttng-ust -avoid-version -rpath 
$(abs_builddir)/.libs/
+PROBES_CF=-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 = $(PROBES_CF) -DACTIVATE_PROBES_A
+
+libprobes_a_prime_la_SOURCES = $(PROBES_SRC)
+libprobes_a_prime_la_LDFLAGS = $(PROBES_LDF)
+libprobes_a_prime_la_CFLAGS = $(PROBES_CF) -DACTIVATE_PROBES_A
+
+libprobes_b_la_SOURCES = $(PROBES_SRC)
+libprobes_b_la_LDFLAGS = $(PROBES_LDF)
+libprobes_b_la_CFLAGS = $(PROBES_CF) -DACTIVATE_PROBES_B
+
+libprobes_c_la_SOURCES = $(PROBES_SRC)
+libprobes_c_la_LDFLAGS = $(PROBES_LDF)
+libprobes_c_la_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 = $(PROBES_CF) -DACTIVATE_PROBES_C
+
+libprobes_d_la_SOURCES = $(PROBES_SRC)
+libprobes_d_la_LDFLAGS = $(PROBES_LDF)
+libprobes_d_la_CFLAGS = $(PROBES_CF) -DACTIVATE_PROBES_D
+
+libprobes_e_la_SOURCES = $(PROBES_SRC)
+libprobes_e_la_LDFLAGS = $(PROBES_LDF)
+libprobes_e_la_CFLAGS = $(PROBES_CF) -DACTIVATE_PROBES_E
+
+libprobes_f_la_SOURCES = $(PROBES_SRC)
+libprobes_f_la_LDFLAGS = $(PROBES_LDF)
+libprobes_f_la_CFLAGS = $(PROBES_CF) -DACTIVATE_PROBES_F
+
+libprobes_g_la_SOURCES = $(PROBES_SRC)
+libprobes_g_la_LDFLAGS = $(PROBES_LDF)
+libprobes_g_la_CFLAGS = $(PROBES_CF) -DACTIVATE_PROBES_G
+
+libprobes_h_la_SOURCES = $(PROBES_SRC)
+libprobes_h_la_LDFLAGS = $(PROBES_LDF)
+libprobes_h_la_CFLAGS = $(PROBES_CF) -DACTIVATE_PROBES_H
+
+libprobes_i_la_SOURCES = $(PROBES_SRC)
+libprobes_i_la_LDFLAGS = $(PROBES_LDF)
+libprobes_i_la_CFLAGS = $(PROBES_CF) -DACTIVATE_PROBES_I
+
+libprobes_j_la_SOURCES = $(PROBES_SRC)
+libprobes_j_la_LDFLAGS = $(PROBES_LDF)
+libprobes_j_la_CFLAGS = $(PROBES_CF) -DACTIVATE_PROBES_J
+
+libprobes_k_la_SOURCES = $(PROBES_SRC)
+libprobes_k_la_LDFLAGS = $(PROBES_LDF)
+libprobes_k_la_CFLAGS = $(PROBES_CF) -DACTIVATE_PROBES_K
+
+libprobes_l_la_SOURCES = $(PROBES_SRC)
+libprobes_l_la_LDFLAGS = $(PROBES_LDF)
+libprobes_l_la_CFLAGS = $(PROBES_CF) -DACTIVATE_PROBES_L
+
+libprobes_m_la_SOURCES = $(PROBES_SRC)
+libprobes_m_la_LDFLAGS = $(PROBES_LDF)
+libprobes_m_la_CFLAGS = $(PROBES_CF) -DACTIVATE_PROBES_M
+
+libprobes_n_la_SOURCES = $(PROBES_SRC)
+libprobes_n_la_LDFLAGS = $(PROBES_LDF)
+libprobes_n_la_CFLAGS = $(PROBES_CF) -DACTIVATE_PROBES_N
+
+libprobes_o_la_SOURCES = $(PROBES_SRC)
+libprobes_o_la_LDFLAGS = $(PROBES_LDF)
+libprobes_o_la_CFLAGS = $(PROBES_CF) -DACTIVATE_PROBES_O
+
+libprobes_p_la_SOURCES = $(PROBES_SRC)
+libprobes_p_la_LDFLAGS = $(PROBES_LDF)
+libprobes_p_la_CFLAGS = $(PROBES_CF) -DACTIVATE_PROBES_P
+
+libcallsites_1_la_SOURCES = $(CALLSITES_SRC)
+libcallsites_1_la_LDFLAGS = $(CALLSITES_LDF)
+libcallsites_1_la_CFLAGS = $(CALLSITES_CF) -DVALUE=11111
+
+libcallsites_2_la_SOURCES = $(CALLSITES_SRC)
+libcallsites_2_la_LDFLAGS = $(CALLSITES_LDF)
+libcallsites_2_la_CFLAGS = $(CALLSITES_CF) -DVALUE=22222
+
+CLEANFILES=probes.o
diff --git a/tests/regression/ust/multi-lib/README 
b/tests/regression/ust/multi-lib/README
new file mode 100644
index 0000000..15b969f
--- /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 0000000..4b61ac2
--- /dev/null
+++ b/tests/regression/ust/multi-lib/callsites.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) - 2018 Francis Deslauriers <francis.deslauri...@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);
+}
+
diff --git a/tests/regression/ust/multi-lib/callsites.h 
b/tests/regression/ust/multi-lib/callsites.h
new file mode 100644
index 0000000..547a6a6
--- /dev/null
+++ b/tests/regression/ust/multi-lib/callsites.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) - 2018 Francis Deslauriers <francis.deslauri...@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 */
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 0000000..856b6d1
--- /dev/null
+++ b/tests/regression/ust/multi-lib/multi-lib-test.c
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) - 2018 Francis Deslauriers <francis.deslauri...@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:
+       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;
+       if (nb_libraries != 2) {
+               ret = -1;
+               goto error;
+       }
+
+       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();
+       }
+       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 i, 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, i, 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;
+       }
+
+       ret = 0;
+
+       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:
+       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 0000000..3ee9164
--- /dev/null
+++ b/tests/regression/ust/multi-lib/probes.c
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) - 2018 Francis Deslauriers <francis.deslauri...@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"
diff --git a/tests/regression/ust/multi-lib/probes.h 
b/tests/regression/ust/multi-lib/probes.h
new file mode 100644
index 0000000..110686c
--- /dev/null
+++ b/tests/regression/ust/multi-lib/probes.h
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) - 2018 Francis Deslauriers <francis.deslauri...@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>
+
+#if defined(ACTIVATE_PROBES_A)
+TRACEPOINT_EVENT(multi, tp,
+    TP_ARGS(unsigned long, arg),
+    TP_FIELDS(
+        ctf_integer(unsigned long, arg_long_A, arg)
+    )
+)
+#elif defined(ACTIVATE_PROBES_B)
+TRACEPOINT_EVENT(multi, tp,
+    TP_ARGS(unsigned long, arg),
+    TP_FIELDS(
+        ctf_integer(unsigned long, 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(unsigned long, arg),
+    TP_FIELDS(
+        ctf_enum(multi, enum_a, short, enum_short_C,  0)
+        ctf_enum(multi, enum_a, int, enum_int_C,  1)
+        ctf_enum(multi, enum_a, unsigned long, 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(unsigned long, arg),
+    TP_FIELDS(
+        ctf_enum(multi, enum_a, int, enum_int_D,  1)
+        ctf_enum(multi, enum_a, short, enum_short_D,  0)
+        ctf_enum(multi, enum_a, unsigned long, 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(unsigned long, arg),
+    TP_FIELDS(
+        ctf_integer(unsigned long, arg_long, arg)
+    )
+)
+#elif defined(ACTIVATE_PROBES_F)
+TRACEPOINT_EVENT(multi, tp,
+    TP_ARGS(unsigned long, arg),
+    TP_FIELDS(
+        ctf_integer(long, arg_long, arg)
+    )
+)
+#elif defined(ACTIVATE_PROBES_G)
+TRACEPOINT_EVENT(multi, tp,
+    TP_ARGS(unsigned long, arg),
+    TP_FIELDS(
+        ctf_integer_hex(long, arg_long, arg)
+    )
+)
+#elif defined(ACTIVATE_PROBES_H)
+TRACEPOINT_EVENT(multi, tp,
+    TP_ARGS(unsigned long, arg),
+    TP_FIELDS(
+        ctf_integer_hex(short, arg_long, arg)
+    )
+)
+#elif defined(ACTIVATE_PROBES_I)
+TRACEPOINT_EVENT(multi, tp,
+    TP_ARGS(unsigned long, arg),
+    TP_FIELDS(
+        ctf_integer_hex(int, arg_long, arg)
+    )
+)
+#elif defined(ACTIVATE_PROBES_J)
+TRACEPOINT_EVENT(multi, tp,
+    TP_ARGS(unsigned long, arg),
+    TP_FIELDS(
+        ctf_float(float, arg_float, (float) arg)
+    )
+)
+#elif defined(ACTIVATE_PROBES_K)
+TRACEPOINT_EVENT(multi, tp,
+    TP_ARGS(unsigned long, 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(unsigned long, arg),
+    TP_FIELDS(
+        ctf_enum(multi, enum_a, int, 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(unsigned long, arg),
+    TP_FIELDS(
+        ctf_enum(multi, enum_a, long, 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(unsigned long, arg),
+    TP_FIELDS(
+        ctf_enum(multi, enum_a, short, enum_int,  1)
+    )
+)
+#elif defined(ACTIVATE_PROBES_O)
+TRACEPOINT_EVENT(multi, tp,
+    TP_ARGS(unsigned long, arg),
+    TP_FIELDS(
+        ctf_string(arg_string, "string")
+    )
+)
+#elif defined(ACTIVATE_PROBES_P)
+TRACEPOINT_EVENT(multi, tp,
+    TP_ARGS(unsigned long, arg),
+    TP_FIELDS(
+        ctf_string(my_arg_string, "string")
+    )
+)
+#else
+TRACEPOINT_EVENT(multi, tp,
+    TP_ARGS(unsigned long, arg),
+    TP_FIELDS(
+    )
+)
+#endif
+
+#endif /* PROBES_H */
+
+#include <lttng/tracepoint-event.h>
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 0000000..d4c2880
--- /dev/null
+++ b/tests/regression/ust/multi-lib/test_multi_lib
@@ -0,0 +1,262 @@
+#!/bin/bash
+#
+# Copyright (C) - 2018 Francis Deslauriers <francis.deslauri...@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=./exec-with-callsites
+EXEC_NAME_WITHOUT_CALLSITES=./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_comparaison()
+{
+       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_comparaison"
+       "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
-- 
2.7.4

_______________________________________________
lttng-dev mailing list
lttng-dev@lists.lttng.org
https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev

Reply via email to