All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH lttng-tools 1/5] Fix: probes should not be compared by their names and callsite signatures
       [not found] <1518032219-28072-1-git-send-email-francis.deslauriers@efficios.com>
@ 2018-02-07 19:36 ` Francis Deslauriers
  2018-02-07 19:36 ` [PATCH lttng-tools 2/5] Fix: should pass the reg_enum_lookup pointer directly Francis Deslauriers
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 16+ messages in thread
From: Francis Deslauriers @ 2018-02-07 19:36 UTC (permalink / raw)
  To: lttng-dev; +Cc: jgalar

Events with different payloads but identical name and signatures could
lead to corrupted trace as the Session Daemon would consider them
identical and give them the same event ID.

Events should be compared using the name, loglevel, fields and
model_emf_uri to ensure that their serialized layout is the same.

Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
---
 src/bin/lttng-sessiond/Makefile.am       |   3 +-
 src/bin/lttng-sessiond/ust-field-utils.c | 261 +++++++++++++++++++++++++++++++
 src/bin/lttng-sessiond/ust-field-utils.h |  29 ++++
 src/bin/lttng-sessiond/ust-registry.c    |  40 ++++-
 tests/unit/Makefile.am                   |   1 +
 5 files changed, 325 insertions(+), 9 deletions(-)
 create mode 100644 src/bin/lttng-sessiond/ust-field-utils.c
 create mode 100644 src/bin/lttng-sessiond/ust-field-utils.h

diff --git a/src/bin/lttng-sessiond/Makefile.am b/src/bin/lttng-sessiond/Makefile.am
index 413fe75..6fc1809 100644
--- a/src/bin/lttng-sessiond/Makefile.am
+++ b/src/bin/lttng-sessiond/Makefile.am
@@ -40,7 +40,8 @@ lttng_sessiond_SOURCES = utils.c utils.h \
 if HAVE_LIBLTTNG_UST_CTL
 lttng_sessiond_SOURCES += trace-ust.c ust-registry.c ust-app.c \
 			ust-consumer.c ust-consumer.h ust-thread.c \
-			ust-metadata.c ust-clock.h agent-thread.c agent-thread.h
+			ust-metadata.c ust-clock.h agent-thread.c agent-thread.h \
+			ust-field-utils.h ust-field-utils.c
 endif
 
 # Add main.c at the end for compile order
diff --git a/src/bin/lttng-sessiond/ust-field-utils.c b/src/bin/lttng-sessiond/ust-field-utils.c
new file mode 100644
index 0000000..3c2da14
--- /dev/null
+++ b/src/bin/lttng-sessiond/ust-field-utils.c
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2018 - Francis Deslauriers <francis.deslauriers@efficios.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License, version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <string.h>
+#include <stdbool.h>
+
+#include "ust-field-utils.h"
+
+/*
+ * The ustctl_field is made of a combinaison of C basic types
+ * ustctl_basic_type and _ustctl_basic_type.
+ *
+ * ustctl_basic_type contains an enumeration describing the abstract type.
+ * _ustctl_basic_type does _NOT_ contain an enumeration describing the
+ * abstract type.
+ *
+ * A layer is needed to use the same code for both structures.
+ * When dealing with _ustctl_basic_type, we need to use the abstract type of
+ * the ustctl_type struct.
+ */
+
+/*
+ * Compare two ustctl_integer_type fields.
+ * Returns 1 if both are identical.
+ */
+static bool match_ustctl_field_integer(struct ustctl_integer_type *first,
+			struct ustctl_integer_type *second)
+{
+	bool match = true;
+	match &= first->size == second->size;
+	match &= first->alignment == second->alignment;
+	match &= first->signedness == second->signedness;
+	match &= first->encoding == second->encoding;
+	match &= first->base == second->base;
+	match &= first->reverse_byte_order == second->reverse_byte_order;
+
+	return match;
+}
+
+/*
+ * Compare two _ustctl_basic_type fields known to be of type integer.
+ * Returns 1 if both are identical.
+ */
+static bool match_ustctl_field_integer_from_raw_basic_type(
+			union _ustctl_basic_type *first, union _ustctl_basic_type *second)
+{
+	return match_ustctl_field_integer(&first->integer, &second->integer);
+}
+
+/*
+ * Compare two _ustctl_basic_type fields known to be of type enum.
+ * Returns 1 if both are identical.
+ */
+static bool match_ustctl_field_enum_from_raw_basic_type(
+			union _ustctl_basic_type *first, union _ustctl_basic_type *second)
+{
+	/*
+	 * Compare enumeration ID. Enumeration ID is provided to the application by
+	 * the session daemon before event registration.
+	 */
+	if (first->enumeration.id != second->enumeration.id) {
+		goto no_match;
+	}
+
+	/*
+	 * Sanity check of the name and container type. Those were already checked
+	 * during enum registration.
+	 */
+	if (strncmp(first->enumeration.name, second->enumeration.name,
+				LTTNG_UST_SYM_NAME_LEN)) {
+		goto no_match;
+	}
+	if (match_ustctl_field_integer(&first->enumeration.container_type,
+				&second->enumeration.container_type) == false) {
+		goto no_match;
+	}
+
+	return true;
+
+no_match:
+	return false;
+}
+
+/*
+ * Compare two _ustctl_basic_type fields known to be of type string.
+ * Returns 1 if both are identical.
+ */
+static bool match_ustctl_field_string_from_raw_basic_type(
+			union _ustctl_basic_type *first, union _ustctl_basic_type *second)
+{
+	return first->string.encoding == second->string.encoding;
+}
+
+/*
+ * Compare two _ustctl_basic_type fields known to be of type float.
+ * Returns 1 if both are identical.
+ */
+static bool match_ustctl_field_float_from_raw_basic_type(
+			union _ustctl_basic_type *first, union _ustctl_basic_type *second)
+{
+	bool match = true;
+	match &= first->_float.exp_dig == second->_float.exp_dig;
+	match &= first->_float.mant_dig == second->_float.mant_dig;
+	match &= first->_float.reverse_byte_order == second->_float.reverse_byte_order;
+	match &= first->_float.alignment == second->_float.alignment;
+
+	return match;
+}
+
+/*
+ * Compare two _ustctl_basic_type fields given their respective abstract types.
+ * Returns 1 if both are identical.
+ */
+static bool match_ustctl_field_raw_basic_type(
+			enum ustctl_abstract_types first_atype,
+			union _ustctl_basic_type *first,
+			enum ustctl_abstract_types second_atype,
+			union _ustctl_basic_type *second)
+{
+	if (first_atype != second_atype) {
+		goto no_match;
+	}
+
+	switch (first_atype) {
+	case ustctl_atype_integer:
+		if (match_ustctl_field_integer_from_raw_basic_type(first, second) == false) {
+			goto no_match;
+		}
+		break;
+	case ustctl_atype_enum:
+		if (match_ustctl_field_enum_from_raw_basic_type(first, second) == false) {
+			goto no_match;
+		}
+		break;
+	case ustctl_atype_string:
+		if (match_ustctl_field_string_from_raw_basic_type(first, second) == false) {
+			goto no_match;
+		}
+		break;
+	case ustctl_atype_float:
+		if (match_ustctl_field_float_from_raw_basic_type(first, second) == false) {
+			goto no_match;
+		}
+		break;
+	default:
+		goto no_match;
+	}
+
+	return true;
+
+no_match:
+	return false;
+}
+
+/*
+ * Compatibility layer between the ustctl_basic_type struct and
+ * _ustctl_basic_type union.
+ */
+static bool match_ustctl_field_basic_type(struct ustctl_basic_type *first,
+			struct ustctl_basic_type *second)
+{
+	return match_ustctl_field_raw_basic_type(first->atype, &first->u.basic,
+				second->atype, &second->u.basic);
+}
+
+int match_ustctl_field(struct ustctl_field *first, struct ustctl_field *second)
+{
+	/* Check the name of the field is identical. */
+	if (strncmp(first->name, second->name, LTTNG_UST_SYM_NAME_LEN)) {
+		goto no_match;
+	}
+
+	/* Check the field type is identical. */
+	if (first->type.atype != second->type.atype) {
+		goto no_match;
+	}
+
+	/* Check the field layout. */
+	switch (first->type.atype) {
+	case ustctl_atype_integer:
+	case ustctl_atype_enum:
+	case ustctl_atype_string:
+	case ustctl_atype_float:
+		if (match_ustctl_field_raw_basic_type(first->type.atype,
+					&first->type.u.basic, second->type.atype,
+					&second->type.u.basic) == false) {
+			goto no_match;
+		}
+		break;
+	case ustctl_atype_sequence:
+		/* Match element type of the sequence. */
+		if (match_ustctl_field_basic_type(&first->type.u.sequence.elem_type,
+					&second->type.u.sequence.elem_type) == false) {
+			goto no_match;
+		}
+
+		/* Match length type of the sequence. */
+		if (match_ustctl_field_basic_type(&first->type.u.sequence.length_type,
+					&second->type.u.sequence.length_type) == false) {
+			goto no_match;
+		}
+
+		break;
+	case ustctl_atype_array:
+		/* Match element type of the array. */
+		if (match_ustctl_field_basic_type(&first->type.u.array.elem_type,
+					&second->type.u.array.elem_type) == false) {
+			goto no_match;
+		}
+
+		/* Match length of the array. */
+		if (first->type.u.array.length != second->type.u.array.length) {
+			goto no_match;
+		}
+
+		break;
+	case ustctl_atype_variant:
+		/* Compare number of choice of the variants. */
+		if (first->type.u.variant.nr_choices !=
+					second->type.u.variant.nr_choices) {
+			goto no_match;
+		}
+
+		/* Compare tag name of the variants. */
+		if (strncmp(first->type.u.variant.tag_name,
+					second->type.u.variant.tag_name,
+					LTTNG_UST_SYM_NAME_LEN)) {
+			goto no_match;
+		}
+
+		break;
+	case ustctl_atype_struct:
+		/* Compare number of fields of the structs. */
+		if (first->type.u._struct.nr_fields != second->type.u._struct.nr_fields) {
+			goto no_match;
+		}
+
+		break;
+	default:
+		goto no_match;
+	}
+
+	return true;
+
+no_match:
+	return false;
+}
diff --git a/src/bin/lttng-sessiond/ust-field-utils.h b/src/bin/lttng-sessiond/ust-field-utils.h
new file mode 100644
index 0000000..13a1433
--- /dev/null
+++ b/src/bin/lttng-sessiond/ust-field-utils.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2018 - Francis Deslauriers francis.deslauriers@efficios.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License, version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef LTTNG_UST_FIELD_UTILS_H
+#define LTTNG_UST_FIELD_UTILS_H
+
+#include "ust-ctl.h"
+
+/*
+ * Compare two UST fields.
+ * Return 1 if both fields have identical definition, 0 otherwise.
+ */
+int match_ustctl_field(struct ustctl_field *first, struct ustctl_field *second);
+
+#endif /* LTTNG_UST_FIELD_UTILS_H */
diff --git a/src/bin/lttng-sessiond/ust-registry.c b/src/bin/lttng-sessiond/ust-registry.c
index d63c750..e336b9e 100644
--- a/src/bin/lttng-sessiond/ust-registry.c
+++ b/src/bin/lttng-sessiond/ust-registry.c
@@ -25,15 +25,18 @@
 
 #include "ust-registry.h"
 #include "ust-app.h"
+#include "ust-field-utils.h"
 #include "utils.h"
 #include "lttng-sessiond.h"
 #include "notification-thread-commands.h"
 
+
 /*
  * Hash table match function for event in the registry.
  */
 static int ht_match_event(struct cds_lfht_node *node, const void *_key)
 {
+	int i;
 	struct ust_registry_event *event;
 	const struct ust_registry_event *key;
 
@@ -44,15 +47,37 @@ static int ht_match_event(struct cds_lfht_node *node, const void *_key)
 	assert(event);
 	key = _key;
 
-	/* It has to be a perfect match. */
+	/* It has to be a perfect match. First, compare the event names. */
 	if (strncmp(event->name, key->name, sizeof(event->name))) {
 		goto no_match;
 	}
 
-	/* It has to be a perfect match. */
-	if (strncmp(event->signature, key->signature,
-			strlen(event->signature))) {
+	/* Compare log levels. */
+	if (event->loglevel_value != key->loglevel_value) {
+		goto no_match;
+	}
+
+	/* Compare the number of fields. */
+	if (event->nr_fields != key->nr_fields) {
+		goto no_match;
+	}
+
+	/* Compare each field individually. */
+	for (i = 0; i < event->nr_fields; i++) {
+		if (match_ustctl_field(&event->fields[i], &key->fields[i]) == 0) {
+			goto no_match;
+		}
+	}
+
+	/* Compare model URI. */
+	if (event->model_emf_uri != NULL && key->model_emf_uri == NULL) {
+		goto no_match;
+	} else if(event->model_emf_uri == NULL && key->model_emf_uri != NULL) {
 		goto no_match;
+	} else if (event->model_emf_uri != NULL && key->model_emf_uri != NULL) {
+		if (strcmp(event->model_emf_uri, key->model_emf_uri)) {
+			goto no_match;
+		}
 	}
 
 	/* Match */
@@ -64,15 +89,14 @@ no_match:
 
 static unsigned long ht_hash_event(void *_key, unsigned long seed)
 {
-	uint64_t xored_key;
+	uint64_t hashed_key;
 	struct ust_registry_event *key = _key;
 
 	assert(key);
 
-	xored_key = (uint64_t) (hash_key_str(key->name, seed) ^
-			hash_key_str(key->signature, seed));
+	hashed_key = (uint64_t) hash_key_str(key->name, seed);
 
-	return hash_key_u64(&xored_key, seed);
+	return hash_key_u64(&hashed_key, seed);
 }
 
 static int compare_enums(const struct ust_registry_enum *reg_enum_a,
diff --git a/tests/unit/Makefile.am b/tests/unit/Makefile.am
index 340dd93..2fb581b 100644
--- a/tests/unit/Makefile.am
+++ b/tests/unit/Makefile.am
@@ -63,6 +63,7 @@ UST_DATA_TRACE=$(top_builddir)/src/bin/lttng-sessiond/trace-ust.$(OBJEXT) \
 	       $(top_builddir)/src/bin/lttng-sessiond/utils.$(OBJEXT) \
 		   $(top_builddir)/src/bin/lttng-sessiond/buffer-registry.$(OBJEXT) \
 		   $(top_builddir)/src/bin/lttng-sessiond/ust-registry.$(OBJEXT) \
+		   $(top_builddir)/src/bin/lttng-sessiond/ust-field-utils.$(OBJEXT) \
 		   $(top_builddir)/src/bin/lttng-sessiond/ust-metadata.$(OBJEXT) \
 		   $(top_builddir)/src/bin/lttng-sessiond/ust-app.$(OBJEXT) \
 		   $(top_builddir)/src/bin/lttng-sessiond/ust-consumer.$(OBJEXT) \
-- 
2.7.4

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

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH lttng-tools 2/5] Fix: should pass the reg_enum_lookup pointer directly
       [not found] <1518032219-28072-1-git-send-email-francis.deslauriers@efficios.com>
  2018-02-07 19:36 ` [PATCH lttng-tools 1/5] Fix: probes should not be compared by their names and callsite signatures Francis Deslauriers
@ 2018-02-07 19:36 ` Francis Deslauriers
  2018-02-07 19:36 ` [PATCH lttng-tools 3/5] Tests: allow the use of regular expressions to match events Francis Deslauriers
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 16+ messages in thread
From: Francis Deslauriers @ 2018-02-07 19:36 UTC (permalink / raw)
  To: lttng-dev; +Cc: jgalar

As the ht_hash_enum and ht_match_enum functions are not changing the
pointer there is no need to pass the address of the pointer.

Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
---
 src/bin/lttng-sessiond/ust-registry.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/bin/lttng-sessiond/ust-registry.c b/src/bin/lttng-sessiond/ust-registry.c
index e336b9e..cd6fdac 100644
--- a/src/bin/lttng-sessiond/ust-registry.c
+++ b/src/bin/lttng-sessiond/ust-registry.c
@@ -558,8 +558,8 @@ struct ust_registry_enum *
 	struct lttng_ht_iter iter;
 
 	cds_lfht_lookup(session->enums->ht,
-			ht_hash_enum((void *) &reg_enum_lookup, lttng_ht_seed),
-			ht_match_enum, &reg_enum_lookup, &iter.iter);
+			ht_hash_enum((void *) reg_enum_lookup, lttng_ht_seed),
+			ht_match_enum, reg_enum_lookup, &iter.iter);
 	node = lttng_ht_iter_get_node_str(&iter);
 	if (!node) {
 	        goto end;
-- 
2.7.4

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

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH lttng-tools 3/5] Tests: allow the use of regular expressions to match events
       [not found] <1518032219-28072-1-git-send-email-francis.deslauriers@efficios.com>
  2018-02-07 19:36 ` [PATCH lttng-tools 1/5] Fix: probes should not be compared by their names and callsite signatures Francis Deslauriers
  2018-02-07 19:36 ` [PATCH lttng-tools 2/5] Fix: should pass the reg_enum_lookup pointer directly Francis Deslauriers
@ 2018-02-07 19:36 ` Francis Deslauriers
  2018-02-07 19:36 ` [PATCH lttng-tools 4/5] Tests: add function to validate the number of an event name in metadata Francis Deslauriers
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 16+ messages in thread
From: Francis Deslauriers @ 2018-02-07 19:36 UTC (permalink / raw)
  To: lttng-dev; +Cc: jgalar

Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
---
 tests/utils/utils.sh | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tests/utils/utils.sh b/tests/utils/utils.sh
index e8dfcda..9bf1fcc 100644
--- a/tests/utils/utils.sh
+++ b/tests/utils/utils.sh
@@ -1457,7 +1457,7 @@ function validate_trace_exp()
 	which $BABELTRACE_BIN >/dev/null
 	skip $? -ne 0 "Babeltrace binary not found. Skipping trace validation"
 
-	traced=$($BABELTRACE_BIN $trace_path 2>/dev/null | grep ${event_exp} | wc -l)
+	traced=$($BABELTRACE_BIN $trace_path 2>/dev/null | grep --extended-regexp ${event_exp} | wc -l)
 	if [ "$traced" -ne 0 ]; then
 		pass "Validate trace for expression '${event_exp}', $traced events"
 	else
@@ -1476,7 +1476,7 @@ function validate_trace_only_exp()
 	which $BABELTRACE_BIN >/dev/null
 	skip $? -ne 0 "Babeltrace binary not found. Skipping trace matches"
 
-	local count=$($BABELTRACE_BIN $trace_path | grep ${event_exp} | wc -l)
+	local count=$($BABELTRACE_BIN $trace_path | grep --extended-regexp ${event_exp} | wc -l)
 	local total=$($BABELTRACE_BIN $trace_path | wc -l)
 
 	if [ "$count" -ne 0 ] && [ "$total" -eq "$count" ]; then
-- 
2.7.4

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

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH lttng-tools 4/5] Tests: add function to validate the number of an event name in metadata
       [not found] <1518032219-28072-1-git-send-email-francis.deslauriers@efficios.com>
                   ` (2 preceding siblings ...)
  2018-02-07 19:36 ` [PATCH lttng-tools 3/5] Tests: allow the use of regular expressions to match events Francis Deslauriers
@ 2018-02-07 19:36 ` Francis Deslauriers
  2018-02-07 19:36 ` [PATCH lttng-tools 5/5] Tests: add duplicated providers tests Francis Deslauriers
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 16+ messages in thread
From: Francis Deslauriers @ 2018-02-07 19:36 UTC (permalink / raw)
  To: lttng-dev; +Cc: jgalar

Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
---
 tests/utils/utils.sh | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/tests/utils/utils.sh b/tests/utils/utils.sh
index 9bf1fcc..60df376 100644
--- a/tests/utils/utils.sh
+++ b/tests/utils/utils.sh
@@ -1343,6 +1343,29 @@ function add_context_kernel_fail()
 	add_context_lttng 1 -k "$@"
 }
 
+function validate_metadata_event ()
+{
+	local event_name=$1
+	local nr_event_id=$2
+	local trace_path=$3
+
+	local metadata_file=$(find $trace_path | grep metadata)
+	local metadata_path=$(dirname $metadata_file)
+
+	which $BABELTRACE_BIN >/dev/null
+	skip $? -ne 0 "Babeltrace binary not found. Skipping trace matches"
+
+	local count=$($BABELTRACE_BIN --output-format=ctf-metadata $metadata_path | grep $event_name | wc -l)
+
+	if [ "$count" -ne "$nr_event_id" ]; then
+		fail "Metadata match with the metadata of $count event(s) named $event_name"
+		diag "$count matching event id found in metadata"
+	else
+		pass "Metadata match with the metadata of $count event(s) named $event_name"
+	fi
+
+}
+
 function trace_matches ()
 {
 	local event_name=$1
-- 
2.7.4

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

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH lttng-tools 5/5] Tests: add duplicated providers tests
       [not found] <1518032219-28072-1-git-send-email-francis.deslauriers@efficios.com>
                   ` (3 preceding siblings ...)
  2018-02-07 19:36 ` [PATCH lttng-tools 4/5] Tests: add function to validate the number of an event name in metadata Francis Deslauriers
@ 2018-02-07 19:36 ` Francis Deslauriers
       [not found] ` <1518032219-28072-2-git-send-email-francis.deslauriers@efficios.com>
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 16+ messages in thread
From: Francis Deslauriers @ 2018-02-07 19:36 UTC (permalink / raw)
  To: lttng-dev; +Cc: jgalar

Signed-off-by: Francis Deslauriers <francis.deslauriers@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.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);
+}
+
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.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 */
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.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:
+	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.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"
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.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>
+
+#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.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=./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

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH lttng-tools 1/5] Fix: probes should not be compared by their names and callsite signatures
       [not found] ` <1518032219-28072-2-git-send-email-francis.deslauriers@efficios.com>
@ 2018-02-07 20:43   ` Mathieu Desnoyers
       [not found]   ` <744065283.17784.1518036233806.JavaMail.zimbra@efficios.com>
  1 sibling, 0 replies; 16+ messages in thread
From: Mathieu Desnoyers @ 2018-02-07 20:43 UTC (permalink / raw)
  To: Francis Deslauriers; +Cc: lttng-dev, Jeremie Galarneau

----- On Feb 7, 2018, at 2:36 PM, Francis Deslauriers francis.deslauriers@efficios.com wrote:

> Events with different payloads but identical name and signatures could
> lead to corrupted trace as the Session Daemon would consider them
> identical and give them the same event ID.
> 
> Events should be compared using the name, loglevel, fields and
> model_emf_uri to ensure that their serialized layout is the same.

model_emf_uri has no impact on the serialized layout, but does have an
impact on what ends up in the metadata description for the event. The
changelog should be adapated to clarify this.

> 
> Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
> ---
> src/bin/lttng-sessiond/Makefile.am       |   3 +-
> src/bin/lttng-sessiond/ust-field-utils.c | 261 +++++++++++++++++++++++++++++++
> src/bin/lttng-sessiond/ust-field-utils.h |  29 ++++
> src/bin/lttng-sessiond/ust-registry.c    |  40 ++++-
> tests/unit/Makefile.am                   |   1 +
> 5 files changed, 325 insertions(+), 9 deletions(-)
> create mode 100644 src/bin/lttng-sessiond/ust-field-utils.c
> create mode 100644 src/bin/lttng-sessiond/ust-field-utils.h
> 
> diff --git a/src/bin/lttng-sessiond/Makefile.am
> b/src/bin/lttng-sessiond/Makefile.am
> index 413fe75..6fc1809 100644
> --- a/src/bin/lttng-sessiond/Makefile.am
> +++ b/src/bin/lttng-sessiond/Makefile.am
> @@ -40,7 +40,8 @@ lttng_sessiond_SOURCES = utils.c utils.h \
> if HAVE_LIBLTTNG_UST_CTL
> lttng_sessiond_SOURCES += trace-ust.c ust-registry.c ust-app.c \
> 			ust-consumer.c ust-consumer.h ust-thread.c \
> -			ust-metadata.c ust-clock.h agent-thread.c agent-thread.h
> +			ust-metadata.c ust-clock.h agent-thread.c agent-thread.h \
> +			ust-field-utils.h ust-field-utils.c
> endif
> 
> # Add main.c at the end for compile order
> diff --git a/src/bin/lttng-sessiond/ust-field-utils.c
> b/src/bin/lttng-sessiond/ust-field-utils.c
> new file mode 100644
> index 0000000..3c2da14
> --- /dev/null
> +++ b/src/bin/lttng-sessiond/ust-field-utils.c
> @@ -0,0 +1,261 @@
> +/*
> + * Copyright (C) 2018 - Francis Deslauriers <francis.deslauriers@efficios.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License, version 2 only, as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
> + * more details.
> + *
> + * You should have received a copy of the GNU General Public License along with
> + * this program; if not, write to the Free Software Foundation, Inc., 51
> + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +#include <string.h>
> +#include <stdbool.h>
> +
> +#include "ust-field-utils.h"
> +
> +/*
> + * The ustctl_field is made of a combinaison of C basic types

combination

> + * ustctl_basic_type and _ustctl_basic_type.
> + *
> + * ustctl_basic_type contains an enumeration describing the abstract type.
> + * _ustctl_basic_type does _NOT_ contain an enumeration describing the
> + * abstract type.
> + *
> + * A layer is needed to use the same code for both structures.
> + * When dealing with _ustctl_basic_type, we need to use the abstract type of
> + * the ustctl_type struct.
> + */
> +
> +/*
> + * Compare two ustctl_integer_type fields.
> + * Returns 1 if both are identical.
> + */
> +static bool match_ustctl_field_integer(struct ustctl_integer_type *first,
> +			struct ustctl_integer_type *second)
> +{
> +	bool match = true;

I don't like bitwise operators on C bool type. Is there anything that
guarantees us that bool always uses the same bit to represent "true" ?

Also, missing whiteline after the variable declaration.


> +	match &= first->size == second->size;
> +	match &= first->alignment == second->alignment;
> +	match &= first->signedness == second->signedness;
> +	match &= first->encoding == second->encoding;
> +	match &= first->base == second->base;
> +	match &= first->reverse_byte_order == second->reverse_byte_order;
> +
> +	return match;


I'd prefer simply:

if (first->size != second->size)
   return false;
.....
return true;

> +}
> +
> +/*
> + * Compare two _ustctl_basic_type fields known to be of type integer.
> + * Returns 1 if both are identical.
> + */
> +static bool match_ustctl_field_integer_from_raw_basic_type(
> +			union _ustctl_basic_type *first, union _ustctl_basic_type *second)
> +{
> +	return match_ustctl_field_integer(&first->integer, &second->integer);
> +}
> +
> +/*
> + * Compare two _ustctl_basic_type fields known to be of type enum.
> + * Returns 1 if both are identical.
> + */
> +static bool match_ustctl_field_enum_from_raw_basic_type(
> +			union _ustctl_basic_type *first, union _ustctl_basic_type *second)
> +{
> +	/*
> +	 * Compare enumeration ID. Enumeration ID is provided to the application by
> +	 * the session daemon before event registration.
> +	 */
> +	if (first->enumeration.id != second->enumeration.id) {
> +		goto no_match;
> +	}
> +
> +	/*
> +	 * Sanity check of the name and container type. Those were already checked
> +	 * during enum registration.
> +	 */
> +	if (strncmp(first->enumeration.name, second->enumeration.name,
> +				LTTNG_UST_SYM_NAME_LEN)) {
> +		goto no_match;
> +	}
> +	if (match_ustctl_field_integer(&first->enumeration.container_type,
> +				&second->enumeration.container_type) == false) {

replace if (match_...() == false) {

by

if (!match...()) {

> +		goto no_match;
> +	}
> +
> +	return true;
> +
> +no_match:
> +	return false;
> +}
> +
> +/*
> + * Compare two _ustctl_basic_type fields known to be of type string.
> + * Returns 1 if both are identical.
> + */
> +static bool match_ustctl_field_string_from_raw_basic_type(
> +			union _ustctl_basic_type *first, union _ustctl_basic_type *second)
> +{
> +	return first->string.encoding == second->string.encoding;
> +}
> +
> +/*
> + * Compare two _ustctl_basic_type fields known to be of type float.
> + * Returns 1 if both are identical.
> + */
> +static bool match_ustctl_field_float_from_raw_basic_type(
> +			union _ustctl_basic_type *first, union _ustctl_basic_type *second)
> +{
> +	bool match = true;


same here about bitwise ops and whiteline.

> +	match &= first->_float.exp_dig == second->_float.exp_dig;
> +	match &= first->_float.mant_dig == second->_float.mant_dig;
> +	match &= first->_float.reverse_byte_order ==
> second->_float.reverse_byte_order;
> +	match &= first->_float.alignment == second->_float.alignment;
> +
> +	return match;
> +}
> +
> +/*
> + * Compare two _ustctl_basic_type fields given their respective abstract types.
> + * Returns 1 if both are identical.
> + */
> +static bool match_ustctl_field_raw_basic_type(
> +			enum ustctl_abstract_types first_atype,
> +			union _ustctl_basic_type *first,
> +			enum ustctl_abstract_types second_atype,
> +			union _ustctl_basic_type *second)
> +{
> +	if (first_atype != second_atype) {
> +		goto no_match;
> +	}
> +
> +	switch (first_atype) {
> +	case ustctl_atype_integer:
> +		if (match_ustctl_field_integer_from_raw_basic_type(first, second) == false) {
> +			goto no_match;
> +		}
> +		break;
> +	case ustctl_atype_enum:
> +		if (match_ustctl_field_enum_from_raw_basic_type(first, second) == false) {
> +			goto no_match;
> +		}
> +		break;
> +	case ustctl_atype_string:
> +		if (match_ustctl_field_string_from_raw_basic_type(first, second) == false) {
> +			goto no_match;
> +		}
> +		break;
> +	case ustctl_atype_float:
> +		if (match_ustctl_field_float_from_raw_basic_type(first, second) == false) {
> +			goto no_match;
> +		}
> +		break;
> +	default:
> +		goto no_match;
> +	}
> +
> +	return true;
> +
> +no_match:
> +	return false;
> +}
> +
> +/*
> + * Compatibility layer between the ustctl_basic_type struct and
> + * _ustctl_basic_type union.
> + */
> +static bool match_ustctl_field_basic_type(struct ustctl_basic_type *first,
> +			struct ustctl_basic_type *second)
> +{
> +	return match_ustctl_field_raw_basic_type(first->atype, &first->u.basic,
> +				second->atype, &second->u.basic);
> +}
> +
> +int match_ustctl_field(struct ustctl_field *first, struct ustctl_field *second)
> +{
> +	/* Check the name of the field is identical. */
> +	if (strncmp(first->name, second->name, LTTNG_UST_SYM_NAME_LEN)) {
> +		goto no_match;
> +	}
> +
> +	/* Check the field type is identical. */
> +	if (first->type.atype != second->type.atype) {
> +		goto no_match;
> +	}
> +
> +	/* Check the field layout. */
> +	switch (first->type.atype) {
> +	case ustctl_atype_integer:
> +	case ustctl_atype_enum:
> +	case ustctl_atype_string:
> +	case ustctl_atype_float:
> +		if (match_ustctl_field_raw_basic_type(first->type.atype,
> +					&first->type.u.basic, second->type.atype,
> +					&second->type.u.basic) == false) {


== false -> !match...()... for entire function.

> +			goto no_match;
> +		}
> +		break;
> +	case ustctl_atype_sequence:
> +		/* Match element type of the sequence. */
> +		if (match_ustctl_field_basic_type(&first->type.u.sequence.elem_type,
> +					&second->type.u.sequence.elem_type) == false) {
> +			goto no_match;
> +		}
> +
> +		/* Match length type of the sequence. */
> +		if (match_ustctl_field_basic_type(&first->type.u.sequence.length_type,
> +					&second->type.u.sequence.length_type) == false) {
> +			goto no_match;
> +		}
> +
> +		break;
> +	case ustctl_atype_array:
> +		/* Match element type of the array. */
> +		if (match_ustctl_field_basic_type(&first->type.u.array.elem_type,
> +					&second->type.u.array.elem_type) == false) {
> +			goto no_match;
> +		}
> +
> +		/* Match length of the array. */
> +		if (first->type.u.array.length != second->type.u.array.length) {
> +			goto no_match;
> +		}
> +
> +		break;
> +	case ustctl_atype_variant:
> +		/* Compare number of choice of the variants. */
> +		if (first->type.u.variant.nr_choices !=
> +					second->type.u.variant.nr_choices) {
> +			goto no_match;
> +		}
> +
> +		/* Compare tag name of the variants. */
> +		if (strncmp(first->type.u.variant.tag_name,
> +					second->type.u.variant.tag_name,
> +					LTTNG_UST_SYM_NAME_LEN)) {
> +			goto no_match;
> +		}
> +
> +		break;
> +	case ustctl_atype_struct:
> +		/* Compare number of fields of the structs. */
> +		if (first->type.u._struct.nr_fields != second->type.u._struct.nr_fields) {
> +			goto no_match;
> +		}
> +
> +		break;
> +	default:
> +		goto no_match;
> +	}
> +
> +	return true;
> +
> +no_match:
> +	return false;
> +}
> diff --git a/src/bin/lttng-sessiond/ust-field-utils.h
> b/src/bin/lttng-sessiond/ust-field-utils.h
> new file mode 100644
> index 0000000..13a1433
> --- /dev/null
> +++ b/src/bin/lttng-sessiond/ust-field-utils.h
> @@ -0,0 +1,29 @@
> +/*
> + * Copyright (C) 2018 - Francis Deslauriers francis.deslauriers@efficios.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License, version 2 only, as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
> + * more details.
> + *
> + * You should have received a copy of the GNU General Public License along with
> + * this program; if not, write to the Free Software Foundation, Inc., 51
> + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +#ifndef LTTNG_UST_FIELD_UTILS_H
> +#define LTTNG_UST_FIELD_UTILS_H
> +
> +#include "ust-ctl.h"
> +
> +/*
> + * Compare two UST fields.
> + * Return 1 if both fields have identical definition, 0 otherwise.
> + */
> +int match_ustctl_field(struct ustctl_field *first, struct ustctl_field
> *second);
> +
> +#endif /* LTTNG_UST_FIELD_UTILS_H */
> diff --git a/src/bin/lttng-sessiond/ust-registry.c
> b/src/bin/lttng-sessiond/ust-registry.c
> index d63c750..e336b9e 100644
> --- a/src/bin/lttng-sessiond/ust-registry.c
> +++ b/src/bin/lttng-sessiond/ust-registry.c
> @@ -25,15 +25,18 @@
> 
> #include "ust-registry.h"
> #include "ust-app.h"
> +#include "ust-field-utils.h"
> #include "utils.h"
> #include "lttng-sessiond.h"
> #include "notification-thread-commands.h"
> 
> +
> /*
>  * Hash table match function for event in the registry.
>  */
> static int ht_match_event(struct cds_lfht_node *node, const void *_key)
> {
> +	int i;
> 	struct ust_registry_event *event;
> 	const struct ust_registry_event *key;

please try to put shorter declarations at the bottom, such as:

const struct ust_registry_event *key;
struct ust_registry_event *event;
int i;

Thanks,

Mathieu

> 
> @@ -44,15 +47,37 @@ static int ht_match_event(struct cds_lfht_node *node, const
> void *_key)
> 	assert(event);
> 	key = _key;
> 
> -	/* It has to be a perfect match. */
> +	/* It has to be a perfect match. First, compare the event names. */
> 	if (strncmp(event->name, key->name, sizeof(event->name))) {
> 		goto no_match;
> 	}
> 
> -	/* It has to be a perfect match. */
> -	if (strncmp(event->signature, key->signature,
> -			strlen(event->signature))) {
> +	/* Compare log levels. */
> +	if (event->loglevel_value != key->loglevel_value) {
> +		goto no_match;
> +	}
> +
> +	/* Compare the number of fields. */
> +	if (event->nr_fields != key->nr_fields) {
> +		goto no_match;
> +	}
> +
> +	/* Compare each field individually. */
> +	for (i = 0; i < event->nr_fields; i++) {
> +		if (match_ustctl_field(&event->fields[i], &key->fields[i]) == 0) {
> +			goto no_match;
> +		}
> +	}
> +
> +	/* Compare model URI. */
> +	if (event->model_emf_uri != NULL && key->model_emf_uri == NULL) {
> +		goto no_match;
> +	} else if(event->model_emf_uri == NULL && key->model_emf_uri != NULL) {
> 		goto no_match;
> +	} else if (event->model_emf_uri != NULL && key->model_emf_uri != NULL) {
> +		if (strcmp(event->model_emf_uri, key->model_emf_uri)) {
> +			goto no_match;
> +		}
> 	}
> 
> 	/* Match */
> @@ -64,15 +89,14 @@ no_match:
> 
> static unsigned long ht_hash_event(void *_key, unsigned long seed)
> {
> -	uint64_t xored_key;
> +	uint64_t hashed_key;
> 	struct ust_registry_event *key = _key;
> 
> 	assert(key);
> 
> -	xored_key = (uint64_t) (hash_key_str(key->name, seed) ^
> -			hash_key_str(key->signature, seed));
> +	hashed_key = (uint64_t) hash_key_str(key->name, seed);
> 
> -	return hash_key_u64(&xored_key, seed);
> +	return hash_key_u64(&hashed_key, seed);
> }
> 
> static int compare_enums(const struct ust_registry_enum *reg_enum_a,
> diff --git a/tests/unit/Makefile.am b/tests/unit/Makefile.am
> index 340dd93..2fb581b 100644
> --- a/tests/unit/Makefile.am
> +++ b/tests/unit/Makefile.am
> @@ -63,6 +63,7 @@
> UST_DATA_TRACE=$(top_builddir)/src/bin/lttng-sessiond/trace-ust.$(OBJEXT) \
> 	       $(top_builddir)/src/bin/lttng-sessiond/utils.$(OBJEXT) \
> 		   $(top_builddir)/src/bin/lttng-sessiond/buffer-registry.$(OBJEXT) \
> 		   $(top_builddir)/src/bin/lttng-sessiond/ust-registry.$(OBJEXT) \
> +		   $(top_builddir)/src/bin/lttng-sessiond/ust-field-utils.$(OBJEXT) \
> 		   $(top_builddir)/src/bin/lttng-sessiond/ust-metadata.$(OBJEXT) \
> 		   $(top_builddir)/src/bin/lttng-sessiond/ust-app.$(OBJEXT) \
> 		   $(top_builddir)/src/bin/lttng-sessiond/ust-consumer.$(OBJEXT) \
> --
> 2.7.4
> 
> _______________________________________________
> lttng-dev mailing list
> lttng-dev@lists.lttng.org
> https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev

-- 
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com
_______________________________________________
lttng-dev mailing list
lttng-dev@lists.lttng.org
https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH lttng-tools 2/5] Fix: should pass the reg_enum_lookup pointer directly
       [not found] ` <1518032219-28072-3-git-send-email-francis.deslauriers@efficios.com>
@ 2018-02-07 20:48   ` Mathieu Desnoyers
       [not found]   ` <906102650.17794.1518036507633.JavaMail.zimbra@efficios.com>
  1 sibling, 0 replies; 16+ messages in thread
From: Mathieu Desnoyers @ 2018-02-07 20:48 UTC (permalink / raw)
  To: Francis Deslauriers; +Cc: lttng-dev, Jeremie Galarneau

----- On Feb 7, 2018, at 2:36 PM, Francis Deslauriers francis.deslauriers@efficios.com wrote:

> As the ht_hash_enum and ht_match_enum functions are not changing the
> pointer there is no need to pass the address of the pointer.

The changelog seems too nice. The current situation is that the arguments
passed to the cds_lfht_lookup() function do not match the args expected by ht_has_enum
and ht_match_enum, and by chance we probably always end up comparing with garbage ?

The changelog should better describe the current problem.

Thanks,

Mathieu

> 
> Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
> ---
> src/bin/lttng-sessiond/ust-registry.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/src/bin/lttng-sessiond/ust-registry.c
> b/src/bin/lttng-sessiond/ust-registry.c
> index e336b9e..cd6fdac 100644
> --- a/src/bin/lttng-sessiond/ust-registry.c
> +++ b/src/bin/lttng-sessiond/ust-registry.c
> @@ -558,8 +558,8 @@ struct ust_registry_enum *
> 	struct lttng_ht_iter iter;
> 
> 	cds_lfht_lookup(session->enums->ht,
> -			ht_hash_enum((void *) &reg_enum_lookup, lttng_ht_seed),
> -			ht_match_enum, &reg_enum_lookup, &iter.iter);
> +			ht_hash_enum((void *) reg_enum_lookup, lttng_ht_seed),
> +			ht_match_enum, reg_enum_lookup, &iter.iter);
> 	node = lttng_ht_iter_get_node_str(&iter);
> 	if (!node) {
> 	        goto end;
> --
> 2.7.4
> 
> _______________________________________________
> lttng-dev mailing list
> lttng-dev@lists.lttng.org
> https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev

-- 
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com
_______________________________________________
lttng-dev mailing list
lttng-dev@lists.lttng.org
https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH lttng-tools 1/5] Fix: probes should not be compared by their names and callsite signatures
       [not found]   ` <744065283.17784.1518036233806.JavaMail.zimbra@efficios.com>
@ 2018-02-08 16:16     ` Francis Deslauriers
  0 siblings, 0 replies; 16+ messages in thread
From: Francis Deslauriers @ 2018-02-08 16:16 UTC (permalink / raw)
  To: Mathieu Desnoyers; +Cc: lttng-dev, Jeremie Galarneau

2018-02-07 15:43 GMT-05:00 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>:
> ----- On Feb 7, 2018, at 2:36 PM, Francis Deslauriers francis.deslauriers@efficios.com wrote:
>
>> Events with different payloads but identical name and signatures could
>> lead to corrupted trace as the Session Daemon would consider them
>> identical and give them the same event ID.
>>
>> Events should be compared using the name, loglevel, fields and
>> model_emf_uri to ensure that their serialized layout is the same.
>
> model_emf_uri has no impact on the serialized layout, but does have an
> impact on what ends up in the metadata description for the event. The
> changelog should be adapated to clarify this.

I understand, how about this:
Fix: probes should be compared strictly by events metadata

Currently, events are compared using names and signatures. Events
with different payloads but identical name and signatures could
lead to corrupted trace as the Session Daemon would consider them
identical and give them the same event ID.

Events should be compared using the name, loglevel, fields and
model_emf_uri to ensure that their respective metadata is the same.

>
>>
>> Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
>> ---
>> src/bin/lttng-sessiond/Makefile.am       |   3 +-
>> src/bin/lttng-sessiond/ust-field-utils.c | 261 +++++++++++++++++++++++++++++++
>> src/bin/lttng-sessiond/ust-field-utils.h |  29 ++++
>> src/bin/lttng-sessiond/ust-registry.c    |  40 ++++-
>> tests/unit/Makefile.am                   |   1 +
>> 5 files changed, 325 insertions(+), 9 deletions(-)
>> create mode 100644 src/bin/lttng-sessiond/ust-field-utils.c
>> create mode 100644 src/bin/lttng-sessiond/ust-field-utils.h
>>
>> diff --git a/src/bin/lttng-sessiond/Makefile.am
>> b/src/bin/lttng-sessiond/Makefile.am
>> index 413fe75..6fc1809 100644
>> --- a/src/bin/lttng-sessiond/Makefile.am
>> +++ b/src/bin/lttng-sessiond/Makefile.am
>> @@ -40,7 +40,8 @@ lttng_sessiond_SOURCES = utils.c utils.h \
>> if HAVE_LIBLTTNG_UST_CTL
>> lttng_sessiond_SOURCES += trace-ust.c ust-registry.c ust-app.c \
>>                       ust-consumer.c ust-consumer.h ust-thread.c \
>> -                     ust-metadata.c ust-clock.h agent-thread.c agent-thread.h
>> +                     ust-metadata.c ust-clock.h agent-thread.c agent-thread.h \
>> +                     ust-field-utils.h ust-field-utils.c
>> endif
>>
>> # Add main.c at the end for compile order
>> diff --git a/src/bin/lttng-sessiond/ust-field-utils.c
>> b/src/bin/lttng-sessiond/ust-field-utils.c
>> new file mode 100644
>> index 0000000..3c2da14
>> --- /dev/null
>> +++ b/src/bin/lttng-sessiond/ust-field-utils.c
>> @@ -0,0 +1,261 @@
>> +/*
>> + * Copyright (C) 2018 - Francis Deslauriers <francis.deslauriers@efficios.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify it
>> + * under the terms of the GNU General Public License, version 2 only, as
>> + * published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope that it will be useful, but WITHOUT
>> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
>> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
>> + * more details.
>> + *
>> + * You should have received a copy of the GNU General Public License along with
>> + * this program; if not, write to the Free Software Foundation, Inc., 51
>> + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
>> + */
>> +
>> +#include <string.h>
>> +#include <stdbool.h>
>> +
>> +#include "ust-field-utils.h"
>> +
>> +/*
>> + * The ustctl_field is made of a combinaison of C basic types
>
> combination
Done.
>
>> + * ustctl_basic_type and _ustctl_basic_type.
>> + *
>> + * ustctl_basic_type contains an enumeration describing the abstract type.
>> + * _ustctl_basic_type does _NOT_ contain an enumeration describing the
>> + * abstract type.
>> + *
>> + * A layer is needed to use the same code for both structures.
>> + * When dealing with _ustctl_basic_type, we need to use the abstract type of
>> + * the ustctl_type struct.
>> + */
>> +
>> +/*
>> + * Compare two ustctl_integer_type fields.
>> + * Returns 1 if both are identical.
>> + */
>> +static bool match_ustctl_field_integer(struct ustctl_integer_type *first,
>> +                     struct ustctl_integer_type *second)
>> +{
>> +     bool match = true;
>
> I don't like bitwise operators on C bool type. Is there anything that
> guarantees us that bool always uses the same bit to represent "true" ?
>
> Also, missing whiteline after the variable declaration.
Changed for simpler ifs.
>
>
>> +     match &= first->size == second->size;
>> +     match &= first->alignment == second->alignment;
>> +     match &= first->signedness == second->signedness;
>> +     match &= first->encoding == second->encoding;
>> +     match &= first->base == second->base;
>> +     match &= first->reverse_byte_order == second->reverse_byte_order;
>> +
>> +     return match;
>
>
> I'd prefer simply:
>
> if (first->size != second->size)
>    return false;
> .....
> return true;
>

Done.

>> +}
>> +
>> +/*
>> + * Compare two _ustctl_basic_type fields known to be of type integer.
>> + * Returns 1 if both are identical.
>> + */
>> +static bool match_ustctl_field_integer_from_raw_basic_type(
>> +                     union _ustctl_basic_type *first, union _ustctl_basic_type *second)
>> +{
>> +     return match_ustctl_field_integer(&first->integer, &second->integer);
>> +}
>> +
>> +/*
>> + * Compare two _ustctl_basic_type fields known to be of type enum.
>> + * Returns 1 if both are identical.
>> + */
>> +static bool match_ustctl_field_enum_from_raw_basic_type(
>> +                     union _ustctl_basic_type *first, union _ustctl_basic_type *second)
>> +{
>> +     /*
>> +      * Compare enumeration ID. Enumeration ID is provided to the application by
>> +      * the session daemon before event registration.
>> +      */
>> +     if (first->enumeration.id != second->enumeration.id) {
>> +             goto no_match;
>> +     }
>> +
>> +     /*
>> +      * Sanity check of the name and container type. Those were already checked
>> +      * during enum registration.
>> +      */
>> +     if (strncmp(first->enumeration.name, second->enumeration.name,
>> +                             LTTNG_UST_SYM_NAME_LEN)) {
>> +             goto no_match;
>> +     }
>> +     if (match_ustctl_field_integer(&first->enumeration.container_type,
>> +                             &second->enumeration.container_type) == false) {
>
> replace if (match_...() == false) {
>
> by
>
> if (!match...()) {
>

Done.

>> +             goto no_match;
>> +     }
>> +
>> +     return true;
>> +
>> +no_match:
>> +     return false;
>> +}
>> +
>> +/*
>> + * Compare two _ustctl_basic_type fields known to be of type string.
>> + * Returns 1 if both are identical.
>> + */
>> +static bool match_ustctl_field_string_from_raw_basic_type(
>> +                     union _ustctl_basic_type *first, union _ustctl_basic_type *second)
>> +{
>> +     return first->string.encoding == second->string.encoding;
>> +}
>> +
>> +/*
>> + * Compare two _ustctl_basic_type fields known to be of type float.
>> + * Returns 1 if both are identical.
>> + */
>> +static bool match_ustctl_field_float_from_raw_basic_type(
>> +                     union _ustctl_basic_type *first, union _ustctl_basic_type *second)
>> +{
>> +     bool match = true;
>
>
> same here about bitwise ops and whiteline.
Done.
>
>> +     match &= first->_float.exp_dig == second->_float.exp_dig;
>> +     match &= first->_float.mant_dig == second->_float.mant_dig;
>> +     match &= first->_float.reverse_byte_order ==
>> second->_float.reverse_byte_order;
>> +     match &= first->_float.alignment == second->_float.alignment;
>> +
>> +     return match;
>> +}
>> +
>> +/*
>> + * Compare two _ustctl_basic_type fields given their respective abstract types.
>> + * Returns 1 if both are identical.
>> + */
>> +static bool match_ustctl_field_raw_basic_type(
>> +                     enum ustctl_abstract_types first_atype,
>> +                     union _ustctl_basic_type *first,
>> +                     enum ustctl_abstract_types second_atype,
>> +                     union _ustctl_basic_type *second)
>> +{
>> +     if (first_atype != second_atype) {
>> +             goto no_match;
>> +     }
>> +
>> +     switch (first_atype) {
>> +     case ustctl_atype_integer:
>> +             if (match_ustctl_field_integer_from_raw_basic_type(first, second) == false) {
>> +                     goto no_match;
>> +             }
>> +             break;
>> +     case ustctl_atype_enum:
>> +             if (match_ustctl_field_enum_from_raw_basic_type(first, second) == false) {
>> +                     goto no_match;
>> +             }
>> +             break;
>> +     case ustctl_atype_string:
>> +             if (match_ustctl_field_string_from_raw_basic_type(first, second) == false) {
>> +                     goto no_match;
>> +             }
>> +             break;
>> +     case ustctl_atype_float:
>> +             if (match_ustctl_field_float_from_raw_basic_type(first, second) == false) {
>> +                     goto no_match;
>> +             }
>> +             break;
>> +     default:
>> +             goto no_match;
>> +     }
>> +
>> +     return true;
>> +
>> +no_match:
>> +     return false;
>> +}
>> +
>> +/*
>> + * Compatibility layer between the ustctl_basic_type struct and
>> + * _ustctl_basic_type union.
>> + */
>> +static bool match_ustctl_field_basic_type(struct ustctl_basic_type *first,
>> +                     struct ustctl_basic_type *second)
>> +{
>> +     return match_ustctl_field_raw_basic_type(first->atype, &first->u.basic,
>> +                             second->atype, &second->u.basic);
>> +}
>> +
>> +int match_ustctl_field(struct ustctl_field *first, struct ustctl_field *second)
>> +{
>> +     /* Check the name of the field is identical. */
>> +     if (strncmp(first->name, second->name, LTTNG_UST_SYM_NAME_LEN)) {
>> +             goto no_match;
>> +     }
>> +
>> +     /* Check the field type is identical. */
>> +     if (first->type.atype != second->type.atype) {
>> +             goto no_match;
>> +     }
>> +
>> +     /* Check the field layout. */
>> +     switch (first->type.atype) {
>> +     case ustctl_atype_integer:
>> +     case ustctl_atype_enum:
>> +     case ustctl_atype_string:
>> +     case ustctl_atype_float:
>> +             if (match_ustctl_field_raw_basic_type(first->type.atype,
>> +                                     &first->type.u.basic, second->type.atype,
>> +                                     &second->type.u.basic) == false) {
>
>
> == false -> !match...()... for entire function.
Done
>
>> +                     goto no_match;
>> +             }
>> +             break;
>> +     case ustctl_atype_sequence:
>> +             /* Match element type of the sequence. */
>> +             if (match_ustctl_field_basic_type(&first->type.u.sequence.elem_type,
>> +                                     &second->type.u.sequence.elem_type) == false) {
>> +                     goto no_match;
>> +             }
>> +
>> +             /* Match length type of the sequence. */
>> +             if (match_ustctl_field_basic_type(&first->type.u.sequence.length_type,
>> +                                     &second->type.u.sequence.length_type) == false) {
>> +                     goto no_match;
>> +             }
>> +
>> +             break;
>> +     case ustctl_atype_array:
>> +             /* Match element type of the array. */
>> +             if (match_ustctl_field_basic_type(&first->type.u.array.elem_type,
>> +                                     &second->type.u.array.elem_type) == false) {
>> +                     goto no_match;
>> +             }
>> +
>> +             /* Match length of the array. */
>> +             if (first->type.u.array.length != second->type.u.array.length) {
>> +                     goto no_match;
>> +             }
>> +
>> +             break;
>> +     case ustctl_atype_variant:
>> +             /* Compare number of choice of the variants. */
>> +             if (first->type.u.variant.nr_choices !=
>> +                                     second->type.u.variant.nr_choices) {
>> +                     goto no_match;
>> +             }
>> +
>> +             /* Compare tag name of the variants. */
>> +             if (strncmp(first->type.u.variant.tag_name,
>> +                                     second->type.u.variant.tag_name,
>> +                                     LTTNG_UST_SYM_NAME_LEN)) {
>> +                     goto no_match;
>> +             }
>> +
>> +             break;
>> +     case ustctl_atype_struct:
>> +             /* Compare number of fields of the structs. */
>> +             if (first->type.u._struct.nr_fields != second->type.u._struct.nr_fields) {
>> +                     goto no_match;
>> +             }
>> +
>> +             break;
>> +     default:
>> +             goto no_match;
>> +     }
>> +
>> +     return true;
>> +
>> +no_match:
>> +     return false;
>> +}
>> diff --git a/src/bin/lttng-sessiond/ust-field-utils.h
>> b/src/bin/lttng-sessiond/ust-field-utils.h
>> new file mode 100644
>> index 0000000..13a1433
>> --- /dev/null
>> +++ b/src/bin/lttng-sessiond/ust-field-utils.h
>> @@ -0,0 +1,29 @@
>> +/*
>> + * Copyright (C) 2018 - Francis Deslauriers francis.deslauriers@efficios.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify it
>> + * under the terms of the GNU General Public License, version 2 only, as
>> + * published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope that it will be useful, but WITHOUT
>> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
>> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
>> + * more details.
>> + *
>> + * You should have received a copy of the GNU General Public License along with
>> + * this program; if not, write to the Free Software Foundation, Inc., 51
>> + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
>> + */
>> +
>> +#ifndef LTTNG_UST_FIELD_UTILS_H
>> +#define LTTNG_UST_FIELD_UTILS_H
>> +
>> +#include "ust-ctl.h"
>> +
>> +/*
>> + * Compare two UST fields.
>> + * Return 1 if both fields have identical definition, 0 otherwise.
>> + */
>> +int match_ustctl_field(struct ustctl_field *first, struct ustctl_field
>> *second);
>> +
>> +#endif /* LTTNG_UST_FIELD_UTILS_H */
>> diff --git a/src/bin/lttng-sessiond/ust-registry.c
>> b/src/bin/lttng-sessiond/ust-registry.c
>> index d63c750..e336b9e 100644
>> --- a/src/bin/lttng-sessiond/ust-registry.c
>> +++ b/src/bin/lttng-sessiond/ust-registry.c
>> @@ -25,15 +25,18 @@
>>
>> #include "ust-registry.h"
>> #include "ust-app.h"
>> +#include "ust-field-utils.h"
>> #include "utils.h"
>> #include "lttng-sessiond.h"
>> #include "notification-thread-commands.h"
>>
>> +
>> /*
>>  * Hash table match function for event in the registry.
>>  */
>> static int ht_match_event(struct cds_lfht_node *node, const void *_key)
>> {
>> +     int i;
>>       struct ust_registry_event *event;
>>       const struct ust_registry_event *key;
>
> please try to put shorter declarations at the bottom, such as:
>
> const struct ust_registry_event *key;
> struct ust_registry_event *event;
> int i;
Done.
>
> Thanks,
>
> Mathieu
>
>>
>> @@ -44,15 +47,37 @@ static int ht_match_event(struct cds_lfht_node *node, const
>> void *_key)
>>       assert(event);
>>       key = _key;
>>
>> -     /* It has to be a perfect match. */
>> +     /* It has to be a perfect match. First, compare the event names. */
>>       if (strncmp(event->name, key->name, sizeof(event->name))) {
>>               goto no_match;
>>       }
>>
>> -     /* It has to be a perfect match. */
>> -     if (strncmp(event->signature, key->signature,
>> -                     strlen(event->signature))) {
>> +     /* Compare log levels. */
>> +     if (event->loglevel_value != key->loglevel_value) {
>> +             goto no_match;
>> +     }
>> +
>> +     /* Compare the number of fields. */
>> +     if (event->nr_fields != key->nr_fields) {
>> +             goto no_match;
>> +     }
>> +
>> +     /* Compare each field individually. */
>> +     for (i = 0; i < event->nr_fields; i++) {
>> +             if (match_ustctl_field(&event->fields[i], &key->fields[i]) == 0) {
>> +                     goto no_match;
>> +             }
>> +     }
>> +
>> +     /* Compare model URI. */
>> +     if (event->model_emf_uri != NULL && key->model_emf_uri == NULL) {
>> +             goto no_match;
>> +     } else if(event->model_emf_uri == NULL && key->model_emf_uri != NULL) {
>>               goto no_match;
>> +     } else if (event->model_emf_uri != NULL && key->model_emf_uri != NULL) {
>> +             if (strcmp(event->model_emf_uri, key->model_emf_uri)) {
>> +                     goto no_match;
>> +             }
>>       }
>>
>>       /* Match */
>> @@ -64,15 +89,14 @@ no_match:
>>
>> static unsigned long ht_hash_event(void *_key, unsigned long seed)
>> {
>> -     uint64_t xored_key;
>> +     uint64_t hashed_key;
>>       struct ust_registry_event *key = _key;
>>
>>       assert(key);
>>
>> -     xored_key = (uint64_t) (hash_key_str(key->name, seed) ^
>> -                     hash_key_str(key->signature, seed));
>> +     hashed_key = (uint64_t) hash_key_str(key->name, seed);
>>
>> -     return hash_key_u64(&xored_key, seed);
>> +     return hash_key_u64(&hashed_key, seed);
>> }
>>
>> static int compare_enums(const struct ust_registry_enum *reg_enum_a,
>> diff --git a/tests/unit/Makefile.am b/tests/unit/Makefile.am
>> index 340dd93..2fb581b 100644
>> --- a/tests/unit/Makefile.am
>> +++ b/tests/unit/Makefile.am
>> @@ -63,6 +63,7 @@
>> UST_DATA_TRACE=$(top_builddir)/src/bin/lttng-sessiond/trace-ust.$(OBJEXT) \
>>              $(top_builddir)/src/bin/lttng-sessiond/utils.$(OBJEXT) \
>>                  $(top_builddir)/src/bin/lttng-sessiond/buffer-registry.$(OBJEXT) \
>>                  $(top_builddir)/src/bin/lttng-sessiond/ust-registry.$(OBJEXT) \
>> +                $(top_builddir)/src/bin/lttng-sessiond/ust-field-utils.$(OBJEXT) \
>>                  $(top_builddir)/src/bin/lttng-sessiond/ust-metadata.$(OBJEXT) \
>>                  $(top_builddir)/src/bin/lttng-sessiond/ust-app.$(OBJEXT) \
>>                  $(top_builddir)/src/bin/lttng-sessiond/ust-consumer.$(OBJEXT) \
>> --
>> 2.7.4
>>
>> _______________________________________________
>> lttng-dev mailing list
>> lttng-dev@lists.lttng.org
>> https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
>
> --
> Mathieu Desnoyers
> EfficiOS Inc.
> http://www.efficios.com



-- 
Francis Deslauriers
Software developer
EfficiOS inc.
_______________________________________________
lttng-dev mailing list
lttng-dev@lists.lttng.org
https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH lttng-tools 2/5] Fix: should pass the reg_enum_lookup pointer directly
       [not found]   ` <906102650.17794.1518036507633.JavaMail.zimbra@efficios.com>
@ 2018-02-08 16:42     ` Francis Deslauriers
  0 siblings, 0 replies; 16+ messages in thread
From: Francis Deslauriers @ 2018-02-08 16:42 UTC (permalink / raw)
  To: Mathieu Desnoyers; +Cc: lttng-dev, Jeremie Galarneau

2018-02-07 15:48 GMT-05:00 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>:
> ----- On Feb 7, 2018, at 2:36 PM, Francis Deslauriers francis.deslauriers@efficios.com wrote:
>
>> As the ht_hash_enum and ht_match_enum functions are not changing the
>> pointer there is no need to pass the address of the pointer.
>
> The changelog seems too nice. The current situation is that the arguments
> passed to the cds_lfht_lookup() function do not match the args expected by ht_has_enum
> and ht_match_enum, and by chance we probably always end up comparing with garbage ?
>
> The changelog should better describe the current problem.

Here is a revised version:

Fix: calling ht_{hash, match}_enum with wrong argument

ht_hash_enum and ht_match_enum are currently called with the address of the
pointer to a ust_registry_enum rather than the expected pointer to a
ust_registry_enum. This means that those function calls would end up
using garbage for hashing and comparing.


Thank you,
Francis

>
> Thanks,
>
> Mathieu
>
>>
>> Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
>> ---
>> src/bin/lttng-sessiond/ust-registry.c | 4 ++--
>> 1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/src/bin/lttng-sessiond/ust-registry.c
>> b/src/bin/lttng-sessiond/ust-registry.c
>> index e336b9e..cd6fdac 100644
>> --- a/src/bin/lttng-sessiond/ust-registry.c
>> +++ b/src/bin/lttng-sessiond/ust-registry.c
>> @@ -558,8 +558,8 @@ struct ust_registry_enum *
>>       struct lttng_ht_iter iter;
>>
>>       cds_lfht_lookup(session->enums->ht,
>> -                     ht_hash_enum((void *) &reg_enum_lookup, lttng_ht_seed),
>> -                     ht_match_enum, &reg_enum_lookup, &iter.iter);
>> +                     ht_hash_enum((void *) reg_enum_lookup, lttng_ht_seed),
>> +                     ht_match_enum, reg_enum_lookup, &iter.iter);
>>       node = lttng_ht_iter_get_node_str(&iter);
>>       if (!node) {
>>               goto end;
>> --
>> 2.7.4
>>
>> _______________________________________________
>> lttng-dev mailing list
>> lttng-dev@lists.lttng.org
>> https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
>
> --
> Mathieu Desnoyers
> EfficiOS Inc.
> http://www.efficios.com



-- 
Francis Deslauriers
Software developer
EfficiOS inc.
_______________________________________________
lttng-dev mailing list
lttng-dev@lists.lttng.org
https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH lttng-tools v2 0/5] Support probes with the same name but different event payload
       [not found] <1518032219-28072-1-git-send-email-francis.deslauriers@efficios.com>
                   ` (6 preceding siblings ...)
       [not found] ` <1518032219-28072-3-git-send-email-francis.deslauriers@efficios.com>
@ 2018-02-09 21:56 ` Francis Deslauriers
       [not found] ` <1518213412-16593-1-git-send-email-francis.deslauriers@efficios.com>
  8 siblings, 0 replies; 16+ messages in thread
From: Francis Deslauriers @ 2018-02-09 21:56 UTC (permalink / raw)
  To: lttng-dev; +Cc: jgalar

This patch set allows for multiple probes with the same name to be
hooked on the same callsite. Right now, the Session Daemon only
considers the name and signature of the events to determine if two
events are identical. This could lead to trace corruptions when two
probes would have the same name and signature but really different
binary trace layouts.

We now compare probes by doing a deep compare of every field. If two
events are _exactly_ the same and have the same metadata then the same
event ID will be used, if they are different a new event ID is created.

When used with its corresponding UST patch set[1], it allows for dynamic
library upgrade scenarios during tracing. The user can now dlopen a new
version of a provider library and dlclose an old version without
restarting the process.

This patch set also includes regression tests for both the deep
comparaison and the newly added dlclose capability.

[1]: https://github.com/frdeso/lttng-ust/tree/dlclose-support

Francis Deslauriers (5):
  Fix: probes should be compared strictly by events metadata
  Fix: calling ht_{hash, match}_enum with wrong argument
  Tests: allow the use of regular expressions to match events
  Tests: add function to validate the number of an event name in
    metadata
  Tests: add duplicated providers tests

 configure.ac                                    |   1 +
 src/bin/lttng-sessiond/Makefile.am              |   3 +-
 src/bin/lttng-sessiond/ust-field-utils.c        | 289 ++++++++++++++++++++++++
 src/bin/lttng-sessiond/ust-field-utils.h        |  29 +++
 src/bin/lttng-sessiond/ust-registry.c           |  46 +++-
 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 +++++++++++++++++++++
 tests/unit/Makefile.am                          |   1 +
 tests/utils/utils.sh                            |  27 ++-
 16 files changed, 1299 insertions(+), 14 deletions(-)
 create mode 100644 src/bin/lttng-sessiond/ust-field-utils.c
 create mode 100644 src/bin/lttng-sessiond/ust-field-utils.h
 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

-- 
2.7.4

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

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH lttng-tools v2 1/5] Fix: probes should be compared strictly by events metadata
       [not found] ` <1518213412-16593-1-git-send-email-francis.deslauriers@efficios.com>
@ 2018-02-09 21:56   ` Francis Deslauriers
  2018-02-09 21:56   ` [PATCH lttng-tools v2 2/5] Fix: calling ht_{hash, match}_enum with wrong argument Francis Deslauriers
                     ` (4 subsequent siblings)
  5 siblings, 0 replies; 16+ messages in thread
From: Francis Deslauriers @ 2018-02-09 21:56 UTC (permalink / raw)
  To: lttng-dev; +Cc: jgalar

Currently, events are compared using names and signatures. Events
with different payloads but identical name and signatures could
lead to corrupted trace because the Session Daemon would consider them
identical and give them the same event ID.

Events should be compared using the name, loglevel, fields and
model_emf_uri to ensure that their respective metadata is the same.

Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
---
 src/bin/lttng-sessiond/Makefile.am       |   3 +-
 src/bin/lttng-sessiond/ust-field-utils.c | 289 +++++++++++++++++++++++++++++++
 src/bin/lttng-sessiond/ust-field-utils.h |  29 ++++
 src/bin/lttng-sessiond/ust-registry.c    |  42 ++++-
 tests/unit/Makefile.am                   |   1 +
 5 files changed, 354 insertions(+), 10 deletions(-)
 create mode 100644 src/bin/lttng-sessiond/ust-field-utils.c
 create mode 100644 src/bin/lttng-sessiond/ust-field-utils.h

diff --git a/src/bin/lttng-sessiond/Makefile.am b/src/bin/lttng-sessiond/Makefile.am
index 413fe75..6fc1809 100644
--- a/src/bin/lttng-sessiond/Makefile.am
+++ b/src/bin/lttng-sessiond/Makefile.am
@@ -40,7 +40,8 @@ lttng_sessiond_SOURCES = utils.c utils.h \
 if HAVE_LIBLTTNG_UST_CTL
 lttng_sessiond_SOURCES += trace-ust.c ust-registry.c ust-app.c \
 			ust-consumer.c ust-consumer.h ust-thread.c \
-			ust-metadata.c ust-clock.h agent-thread.c agent-thread.h
+			ust-metadata.c ust-clock.h agent-thread.c agent-thread.h \
+			ust-field-utils.h ust-field-utils.c
 endif
 
 # Add main.c at the end for compile order
diff --git a/src/bin/lttng-sessiond/ust-field-utils.c b/src/bin/lttng-sessiond/ust-field-utils.c
new file mode 100644
index 0000000..8388052
--- /dev/null
+++ b/src/bin/lttng-sessiond/ust-field-utils.c
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 2018 - Francis Deslauriers <francis.deslauriers@efficios.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License, version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdbool.h>
+#include <string.h>
+
+#include "ust-field-utils.h"
+
+/*
+ * The ustctl_field is made of a combination of C basic types
+ * ustctl_basic_type and _ustctl_basic_type.
+ *
+ * ustctl_basic_type contains an enumeration describing the abstract type.
+ * _ustctl_basic_type does _NOT_ contain an enumeration describing the
+ * abstract type.
+ *
+ * A layer is needed to use the same code for both structures.
+ * When dealing with _ustctl_basic_type, we need to use the abstract type of
+ * the ustctl_type struct.
+ */
+
+/*
+ * Compare two ustctl_integer_type fields.
+ * Returns 1 if both are identical.
+ */
+static bool match_ustctl_field_integer(struct ustctl_integer_type *first,
+			struct ustctl_integer_type *second)
+{
+	if (first->size != second->size) {
+		goto no_match;
+	}
+	if (first->alignment != second->alignment) {
+		goto no_match;
+	}
+	if (first->signedness != second->signedness) {
+		goto no_match;
+	}
+	if (first->encoding != second->encoding) {
+		goto no_match;
+	}
+	if (first->base != second->base) {
+		goto no_match;
+	}
+	if (first->reverse_byte_order != second->reverse_byte_order) {
+		goto no_match;
+	}
+
+	return true;
+
+no_match:
+	return false;
+}
+
+/*
+ * Compare two _ustctl_basic_type fields known to be of type integer.
+ * Returns 1 if both are identical.
+ */
+static bool match_ustctl_field_integer_from_raw_basic_type(
+			union _ustctl_basic_type *first, union _ustctl_basic_type *second)
+{
+	return match_ustctl_field_integer(&first->integer, &second->integer);
+}
+
+/*
+ * Compare two _ustctl_basic_type fields known to be of type enum.
+ * Returns 1 if both are identical.
+ */
+static bool match_ustctl_field_enum_from_raw_basic_type(
+			union _ustctl_basic_type *first, union _ustctl_basic_type *second)
+{
+	/*
+	 * Compare enumeration ID. Enumeration ID is provided to the application by
+	 * the session daemon before event registration.
+	 */
+	if (first->enumeration.id != second->enumeration.id) {
+		goto no_match;
+	}
+
+	/*
+	 * Sanity check of the name and container type. Those were already checked
+	 * during enum registration.
+	 */
+	if (strncmp(first->enumeration.name, second->enumeration.name,
+				LTTNG_UST_SYM_NAME_LEN)) {
+		goto no_match;
+	}
+	if (!match_ustctl_field_integer(&first->enumeration.container_type,
+				&second->enumeration.container_type)) {
+		goto no_match;
+	}
+
+	return true;
+
+no_match:
+	return false;
+}
+
+/*
+ * Compare two _ustctl_basic_type fields known to be of type string.
+ * Returns 1 if both are identical.
+ */
+static bool match_ustctl_field_string_from_raw_basic_type(
+			union _ustctl_basic_type *first, union _ustctl_basic_type *second)
+{
+	return first->string.encoding == second->string.encoding;
+}
+
+/*
+ * Compare two _ustctl_basic_type fields known to be of type float.
+ * Returns 1 if both are identical.
+ */
+static bool match_ustctl_field_float_from_raw_basic_type(
+			union _ustctl_basic_type *first, union _ustctl_basic_type *second)
+{
+	if (first->_float.exp_dig != second->_float.exp_dig) {
+		goto no_match;
+	}
+
+	if (first->_float.mant_dig != second->_float.mant_dig) {
+		goto no_match;
+	}
+
+	if (first->_float.reverse_byte_order !=
+			second->_float.reverse_byte_order) {
+		goto no_match;
+	}
+
+	if (first->_float.alignment != second->_float.alignment) {
+		goto no_match;
+	}
+
+	return true;
+
+no_match:
+	return false;
+}
+
+/*
+ * Compare two _ustctl_basic_type fields given their respective abstract types.
+ * Returns 1 if both are identical.
+ */
+static bool match_ustctl_field_raw_basic_type(
+			enum ustctl_abstract_types first_atype,
+			union _ustctl_basic_type *first,
+			enum ustctl_abstract_types second_atype,
+			union _ustctl_basic_type *second)
+{
+	if (first_atype != second_atype) {
+		goto no_match;
+	}
+
+	switch (first_atype) {
+	case ustctl_atype_integer:
+		if (!match_ustctl_field_integer_from_raw_basic_type(first, second)) {
+			goto no_match;
+		}
+		break;
+	case ustctl_atype_enum:
+		if (!match_ustctl_field_enum_from_raw_basic_type(first, second)) {
+			goto no_match;
+		}
+		break;
+	case ustctl_atype_string:
+		if (!match_ustctl_field_string_from_raw_basic_type(first, second)) {
+			goto no_match;
+		}
+		break;
+	case ustctl_atype_float:
+		if (!match_ustctl_field_float_from_raw_basic_type(first, second)) {
+			goto no_match;
+		}
+		break;
+	default:
+		goto no_match;
+	}
+
+	return true;
+
+no_match:
+	return false;
+}
+
+/*
+ * Compatibility layer between the ustctl_basic_type struct and
+ * _ustctl_basic_type union.
+ */
+static bool match_ustctl_field_basic_type(struct ustctl_basic_type *first,
+			struct ustctl_basic_type *second)
+{
+	return match_ustctl_field_raw_basic_type(first->atype, &first->u.basic,
+				second->atype, &second->u.basic);
+}
+
+int match_ustctl_field(struct ustctl_field *first, struct ustctl_field *second)
+{
+	/* Check the name of the field is identical. */
+	if (strncmp(first->name, second->name, LTTNG_UST_SYM_NAME_LEN)) {
+		goto no_match;
+	}
+
+	/* Check the field type is identical. */
+	if (first->type.atype != second->type.atype) {
+		goto no_match;
+	}
+
+	/* Check the field layout. */
+	switch (first->type.atype) {
+	case ustctl_atype_integer:
+	case ustctl_atype_enum:
+	case ustctl_atype_string:
+	case ustctl_atype_float:
+		if (!match_ustctl_field_raw_basic_type(first->type.atype,
+					&first->type.u.basic, second->type.atype,
+					&second->type.u.basic)) {
+			goto no_match;
+		}
+		break;
+	case ustctl_atype_sequence:
+		/* Match element type of the sequence. */
+		if (!match_ustctl_field_basic_type(&first->type.u.sequence.elem_type,
+					&second->type.u.sequence.elem_type)) {
+			goto no_match;
+		}
+
+		/* Match length type of the sequence. */
+		if (!match_ustctl_field_basic_type(&first->type.u.sequence.length_type,
+					&second->type.u.sequence.length_type)) {
+			goto no_match;
+		}
+
+		break;
+	case ustctl_atype_array:
+		/* Match element type of the array. */
+		if (!match_ustctl_field_basic_type(&first->type.u.array.elem_type,
+					&second->type.u.array.elem_type)) {
+			goto no_match;
+		}
+
+		/* Match length of the array. */
+		if (first->type.u.array.length != second->type.u.array.length) {
+			goto no_match;
+		}
+
+		break;
+	case ustctl_atype_variant:
+		/* Compare number of choice of the variants. */
+		if (first->type.u.variant.nr_choices !=
+					second->type.u.variant.nr_choices) {
+			goto no_match;
+		}
+
+		/* Compare tag name of the variants. */
+		if (strncmp(first->type.u.variant.tag_name,
+					second->type.u.variant.tag_name,
+					LTTNG_UST_SYM_NAME_LEN)) {
+			goto no_match;
+		}
+
+		break;
+	case ustctl_atype_struct:
+		/* Compare number of fields of the structs. */
+		if (first->type.u._struct.nr_fields != second->type.u._struct.nr_fields) {
+			goto no_match;
+		}
+
+		break;
+	default:
+		goto no_match;
+	}
+
+	return true;
+
+no_match:
+	return false;
+}
diff --git a/src/bin/lttng-sessiond/ust-field-utils.h b/src/bin/lttng-sessiond/ust-field-utils.h
new file mode 100644
index 0000000..13a1433
--- /dev/null
+++ b/src/bin/lttng-sessiond/ust-field-utils.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2018 - Francis Deslauriers francis.deslauriers@efficios.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License, version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef LTTNG_UST_FIELD_UTILS_H
+#define LTTNG_UST_FIELD_UTILS_H
+
+#include "ust-ctl.h"
+
+/*
+ * Compare two UST fields.
+ * Return 1 if both fields have identical definition, 0 otherwise.
+ */
+int match_ustctl_field(struct ustctl_field *first, struct ustctl_field *second);
+
+#endif /* LTTNG_UST_FIELD_UTILS_H */
diff --git a/src/bin/lttng-sessiond/ust-registry.c b/src/bin/lttng-sessiond/ust-registry.c
index d63c750..a875515 100644
--- a/src/bin/lttng-sessiond/ust-registry.c
+++ b/src/bin/lttng-sessiond/ust-registry.c
@@ -25,17 +25,20 @@
 
 #include "ust-registry.h"
 #include "ust-app.h"
+#include "ust-field-utils.h"
 #include "utils.h"
 #include "lttng-sessiond.h"
 #include "notification-thread-commands.h"
 
+
 /*
  * Hash table match function for event in the registry.
  */
 static int ht_match_event(struct cds_lfht_node *node, const void *_key)
 {
-	struct ust_registry_event *event;
 	const struct ust_registry_event *key;
+	struct ust_registry_event *event;
+	int i;
 
 	assert(node);
 	assert(_key);
@@ -44,15 +47,37 @@ static int ht_match_event(struct cds_lfht_node *node, const void *_key)
 	assert(event);
 	key = _key;
 
-	/* It has to be a perfect match. */
+	/* It has to be a perfect match. First, compare the event names. */
 	if (strncmp(event->name, key->name, sizeof(event->name))) {
 		goto no_match;
 	}
 
-	/* It has to be a perfect match. */
-	if (strncmp(event->signature, key->signature,
-			strlen(event->signature))) {
+	/* Compare log levels. */
+	if (event->loglevel_value != key->loglevel_value) {
+		goto no_match;
+	}
+
+	/* Compare the number of fields. */
+	if (event->nr_fields != key->nr_fields) {
+		goto no_match;
+	}
+
+	/* Compare each field individually. */
+	for (i = 0; i < event->nr_fields; i++) {
+		if (match_ustctl_field(&event->fields[i], &key->fields[i]) == 0) {
+			goto no_match;
+		}
+	}
+
+	/* Compare model URI. */
+	if (event->model_emf_uri != NULL && key->model_emf_uri == NULL) {
+		goto no_match;
+	} else if(event->model_emf_uri == NULL && key->model_emf_uri != NULL) {
 		goto no_match;
+	} else if (event->model_emf_uri != NULL && key->model_emf_uri != NULL) {
+		if (strcmp(event->model_emf_uri, key->model_emf_uri)) {
+			goto no_match;
+		}
 	}
 
 	/* Match */
@@ -64,15 +89,14 @@ no_match:
 
 static unsigned long ht_hash_event(void *_key, unsigned long seed)
 {
-	uint64_t xored_key;
+	uint64_t hashed_key;
 	struct ust_registry_event *key = _key;
 
 	assert(key);
 
-	xored_key = (uint64_t) (hash_key_str(key->name, seed) ^
-			hash_key_str(key->signature, seed));
+	hashed_key = (uint64_t) hash_key_str(key->name, seed);
 
-	return hash_key_u64(&xored_key, seed);
+	return hash_key_u64(&hashed_key, seed);
 }
 
 static int compare_enums(const struct ust_registry_enum *reg_enum_a,
diff --git a/tests/unit/Makefile.am b/tests/unit/Makefile.am
index 340dd93..2fb581b 100644
--- a/tests/unit/Makefile.am
+++ b/tests/unit/Makefile.am
@@ -63,6 +63,7 @@ UST_DATA_TRACE=$(top_builddir)/src/bin/lttng-sessiond/trace-ust.$(OBJEXT) \
 	       $(top_builddir)/src/bin/lttng-sessiond/utils.$(OBJEXT) \
 		   $(top_builddir)/src/bin/lttng-sessiond/buffer-registry.$(OBJEXT) \
 		   $(top_builddir)/src/bin/lttng-sessiond/ust-registry.$(OBJEXT) \
+		   $(top_builddir)/src/bin/lttng-sessiond/ust-field-utils.$(OBJEXT) \
 		   $(top_builddir)/src/bin/lttng-sessiond/ust-metadata.$(OBJEXT) \
 		   $(top_builddir)/src/bin/lttng-sessiond/ust-app.$(OBJEXT) \
 		   $(top_builddir)/src/bin/lttng-sessiond/ust-consumer.$(OBJEXT) \
-- 
2.7.4

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

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH lttng-tools v2 2/5] Fix: calling ht_{hash, match}_enum with wrong argument
       [not found] ` <1518213412-16593-1-git-send-email-francis.deslauriers@efficios.com>
  2018-02-09 21:56   ` [PATCH lttng-tools v2 1/5] Fix: probes should be compared strictly by events metadata Francis Deslauriers
@ 2018-02-09 21:56   ` Francis Deslauriers
  2018-02-09 21:56   ` [PATCH lttng-tools v2 3/5] Tests: allow the use of regular expressions to match events Francis Deslauriers
                     ` (3 subsequent siblings)
  5 siblings, 0 replies; 16+ messages in thread
From: Francis Deslauriers @ 2018-02-09 21:56 UTC (permalink / raw)
  To: lttng-dev; +Cc: jgalar

ht_hash_enum and ht_match_enum are currently called with the address of the
pointer to a ust_registry_enum rather than the expected pointer to a
ust_registry_enum. This means that those function calls would end up
using garbage for hashing and comparing.

Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
---
 src/bin/lttng-sessiond/ust-registry.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/bin/lttng-sessiond/ust-registry.c b/src/bin/lttng-sessiond/ust-registry.c
index a875515..19bd30f 100644
--- a/src/bin/lttng-sessiond/ust-registry.c
+++ b/src/bin/lttng-sessiond/ust-registry.c
@@ -558,8 +558,8 @@ struct ust_registry_enum *
 	struct lttng_ht_iter iter;
 
 	cds_lfht_lookup(session->enums->ht,
-			ht_hash_enum((void *) &reg_enum_lookup, lttng_ht_seed),
-			ht_match_enum, &reg_enum_lookup, &iter.iter);
+			ht_hash_enum((void *) reg_enum_lookup, lttng_ht_seed),
+			ht_match_enum, reg_enum_lookup, &iter.iter);
 	node = lttng_ht_iter_get_node_str(&iter);
 	if (!node) {
 	        goto end;
-- 
2.7.4

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

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH lttng-tools v2 3/5] Tests: allow the use of regular expressions to match events
       [not found] ` <1518213412-16593-1-git-send-email-francis.deslauriers@efficios.com>
  2018-02-09 21:56   ` [PATCH lttng-tools v2 1/5] Fix: probes should be compared strictly by events metadata Francis Deslauriers
  2018-02-09 21:56   ` [PATCH lttng-tools v2 2/5] Fix: calling ht_{hash, match}_enum with wrong argument Francis Deslauriers
@ 2018-02-09 21:56   ` Francis Deslauriers
  2018-02-09 21:56   ` [PATCH lttng-tools v2 4/5] Tests: add function to validate the number of an event name in metadata Francis Deslauriers
                     ` (2 subsequent siblings)
  5 siblings, 0 replies; 16+ messages in thread
From: Francis Deslauriers @ 2018-02-09 21:56 UTC (permalink / raw)
  To: lttng-dev; +Cc: jgalar

Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
---
 tests/utils/utils.sh | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tests/utils/utils.sh b/tests/utils/utils.sh
index e8dfcda..9bf1fcc 100644
--- a/tests/utils/utils.sh
+++ b/tests/utils/utils.sh
@@ -1457,7 +1457,7 @@ function validate_trace_exp()
 	which $BABELTRACE_BIN >/dev/null
 	skip $? -ne 0 "Babeltrace binary not found. Skipping trace validation"
 
-	traced=$($BABELTRACE_BIN $trace_path 2>/dev/null | grep ${event_exp} | wc -l)
+	traced=$($BABELTRACE_BIN $trace_path 2>/dev/null | grep --extended-regexp ${event_exp} | wc -l)
 	if [ "$traced" -ne 0 ]; then
 		pass "Validate trace for expression '${event_exp}', $traced events"
 	else
@@ -1476,7 +1476,7 @@ function validate_trace_only_exp()
 	which $BABELTRACE_BIN >/dev/null
 	skip $? -ne 0 "Babeltrace binary not found. Skipping trace matches"
 
-	local count=$($BABELTRACE_BIN $trace_path | grep ${event_exp} | wc -l)
+	local count=$($BABELTRACE_BIN $trace_path | grep --extended-regexp ${event_exp} | wc -l)
 	local total=$($BABELTRACE_BIN $trace_path | wc -l)
 
 	if [ "$count" -ne 0 ] && [ "$total" -eq "$count" ]; then
-- 
2.7.4

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

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH lttng-tools v2 4/5] Tests: add function to validate the number of an event name in metadata
       [not found] ` <1518213412-16593-1-git-send-email-francis.deslauriers@efficios.com>
                     ` (2 preceding siblings ...)
  2018-02-09 21:56   ` [PATCH lttng-tools v2 3/5] Tests: allow the use of regular expressions to match events Francis Deslauriers
@ 2018-02-09 21:56   ` Francis Deslauriers
  2018-02-09 21:56   ` [PATCH lttng-tools v2 5/5] Tests: add duplicated providers tests Francis Deslauriers
  2018-05-30 18:44   ` [PATCH lttng-tools v2 0/5] Support probes with the same name but different event payload Jérémie Galarneau
  5 siblings, 0 replies; 16+ messages in thread
From: Francis Deslauriers @ 2018-02-09 21:56 UTC (permalink / raw)
  To: lttng-dev; +Cc: jgalar

Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
---
 tests/utils/utils.sh | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/tests/utils/utils.sh b/tests/utils/utils.sh
index 9bf1fcc..60df376 100644
--- a/tests/utils/utils.sh
+++ b/tests/utils/utils.sh
@@ -1343,6 +1343,29 @@ function add_context_kernel_fail()
 	add_context_lttng 1 -k "$@"
 }
 
+function validate_metadata_event ()
+{
+	local event_name=$1
+	local nr_event_id=$2
+	local trace_path=$3
+
+	local metadata_file=$(find $trace_path | grep metadata)
+	local metadata_path=$(dirname $metadata_file)
+
+	which $BABELTRACE_BIN >/dev/null
+	skip $? -ne 0 "Babeltrace binary not found. Skipping trace matches"
+
+	local count=$($BABELTRACE_BIN --output-format=ctf-metadata $metadata_path | grep $event_name | wc -l)
+
+	if [ "$count" -ne "$nr_event_id" ]; then
+		fail "Metadata match with the metadata of $count event(s) named $event_name"
+		diag "$count matching event id found in metadata"
+	else
+		pass "Metadata match with the metadata of $count event(s) named $event_name"
+	fi
+
+}
+
 function trace_matches ()
 {
 	local event_name=$1
-- 
2.7.4

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

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH lttng-tools v2 5/5] Tests: add duplicated providers tests
       [not found] ` <1518213412-16593-1-git-send-email-francis.deslauriers@efficios.com>
                     ` (3 preceding siblings ...)
  2018-02-09 21:56   ` [PATCH lttng-tools v2 4/5] Tests: add function to validate the number of an event name in metadata Francis Deslauriers
@ 2018-02-09 21:56   ` Francis Deslauriers
  2018-05-30 18:44   ` [PATCH lttng-tools v2 0/5] Support probes with the same name but different event payload Jérémie Galarneau
  5 siblings, 0 replies; 16+ messages in thread
From: Francis Deslauriers @ 2018-02-09 21:56 UTC (permalink / raw)
  To: lttng-dev; +Cc: jgalar

Signed-off-by: Francis Deslauriers <francis.deslauriers@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.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);
+}
+
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.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 */
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.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:
+	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.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"
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.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>
+
+#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.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=./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

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH lttng-tools v2 0/5] Support probes with the same name but different event payload
       [not found] ` <1518213412-16593-1-git-send-email-francis.deslauriers@efficios.com>
                     ` (4 preceding siblings ...)
  2018-02-09 21:56   ` [PATCH lttng-tools v2 5/5] Tests: add duplicated providers tests Francis Deslauriers
@ 2018-05-30 18:44   ` Jérémie Galarneau
  5 siblings, 0 replies; 16+ messages in thread
From: Jérémie Galarneau @ 2018-05-30 18:44 UTC (permalink / raw)
  To: Francis Deslauriers; +Cc: lttng-dev, Jeremie Galarneau


[-- Attachment #1.1: Type: text/plain, Size: 3802 bytes --]

Merged with a number of fixes to the test patch. Thanks!

The CFLAGS have to be propagated to the probes target, and I added a target
to ensure the EXTRA_DIST files are copied to the build directory.

Also, the "comparison" test did not work on 32-bit x86 since "long" and
"int" have the same size on that architecture. The test expected the events
to be different, but they will be merged (as both are 32-bit integers).

Jérémie

On 9 February 2018 at 16:56, Francis Deslauriers <
francis.deslauriers@efficios.com> wrote:

> This patch set allows for multiple probes with the same name to be
> hooked on the same callsite. Right now, the Session Daemon only
> considers the name and signature of the events to determine if two
> events are identical. This could lead to trace corruptions when two
> probes would have the same name and signature but really different
> binary trace layouts.
>
> We now compare probes by doing a deep compare of every field. If two
> events are _exactly_ the same and have the same metadata then the same
> event ID will be used, if they are different a new event ID is created.
>
> When used with its corresponding UST patch set[1], it allows for dynamic
> library upgrade scenarios during tracing. The user can now dlopen a new
> version of a provider library and dlclose an old version without
> restarting the process.
>
> This patch set also includes regression tests for both the deep
> comparaison and the newly added dlclose capability.
>
> [1]: https://github.com/frdeso/lttng-ust/tree/dlclose-support
>
> Francis Deslauriers (5):
>   Fix: probes should be compared strictly by events metadata
>   Fix: calling ht_{hash, match}_enum with wrong argument
>   Tests: allow the use of regular expressions to match events
>   Tests: add function to validate the number of an event name in
>     metadata
>   Tests: add duplicated providers tests
>
>  configure.ac                                    |   1 +
>  src/bin/lttng-sessiond/Makefile.am              |   3 +-
>  src/bin/lttng-sessiond/ust-field-utils.c        | 289
> ++++++++++++++++++++++++
>  src/bin/lttng-sessiond/ust-field-utils.h        |  29 +++
>  src/bin/lttng-sessiond/ust-registry.c           |  46 +++-
>  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
> +++++++++++++++++++++
>  tests/unit/Makefile.am                          |   1 +
>  tests/utils/utils.sh                            |  27 ++-
>  16 files changed, 1299 insertions(+), 14 deletions(-)
>  create mode 100644 src/bin/lttng-sessiond/ust-field-utils.c
>  create mode 100644 src/bin/lttng-sessiond/ust-field-utils.h
>  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
>
> --
> 2.7.4
>
>


-- 
Jérémie Galarneau
EfficiOS Inc.
http://www.efficios.com

[-- Attachment #1.2: Type: text/html, Size: 5146 bytes --]

[-- Attachment #2: Type: text/plain, Size: 156 bytes --]

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

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2018-05-30 18:45 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <1518032219-28072-1-git-send-email-francis.deslauriers@efficios.com>
2018-02-07 19:36 ` [PATCH lttng-tools 1/5] Fix: probes should not be compared by their names and callsite signatures Francis Deslauriers
2018-02-07 19:36 ` [PATCH lttng-tools 2/5] Fix: should pass the reg_enum_lookup pointer directly Francis Deslauriers
2018-02-07 19:36 ` [PATCH lttng-tools 3/5] Tests: allow the use of regular expressions to match events Francis Deslauriers
2018-02-07 19:36 ` [PATCH lttng-tools 4/5] Tests: add function to validate the number of an event name in metadata Francis Deslauriers
2018-02-07 19:36 ` [PATCH lttng-tools 5/5] Tests: add duplicated providers tests Francis Deslauriers
     [not found] ` <1518032219-28072-2-git-send-email-francis.deslauriers@efficios.com>
2018-02-07 20:43   ` [PATCH lttng-tools 1/5] Fix: probes should not be compared by their names and callsite signatures Mathieu Desnoyers
     [not found]   ` <744065283.17784.1518036233806.JavaMail.zimbra@efficios.com>
2018-02-08 16:16     ` Francis Deslauriers
     [not found] ` <1518032219-28072-3-git-send-email-francis.deslauriers@efficios.com>
2018-02-07 20:48   ` [PATCH lttng-tools 2/5] Fix: should pass the reg_enum_lookup pointer directly Mathieu Desnoyers
     [not found]   ` <906102650.17794.1518036507633.JavaMail.zimbra@efficios.com>
2018-02-08 16:42     ` Francis Deslauriers
2018-02-09 21:56 ` [PATCH lttng-tools v2 0/5] Support probes with the same name but different event payload Francis Deslauriers
     [not found] ` <1518213412-16593-1-git-send-email-francis.deslauriers@efficios.com>
2018-02-09 21:56   ` [PATCH lttng-tools v2 1/5] Fix: probes should be compared strictly by events metadata Francis Deslauriers
2018-02-09 21:56   ` [PATCH lttng-tools v2 2/5] Fix: calling ht_{hash, match}_enum with wrong argument Francis Deslauriers
2018-02-09 21:56   ` [PATCH lttng-tools v2 3/5] Tests: allow the use of regular expressions to match events Francis Deslauriers
2018-02-09 21:56   ` [PATCH lttng-tools v2 4/5] Tests: add function to validate the number of an event name in metadata Francis Deslauriers
2018-02-09 21:56   ` [PATCH lttng-tools v2 5/5] Tests: add duplicated providers tests Francis Deslauriers
2018-05-30 18:44   ` [PATCH lttng-tools v2 0/5] Support probes with the same name but different event payload Jérémie Galarneau

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.