)
#define LTTNG_UST_TP_TRACELOG_TEMPLATE(_level_enum) \
- LTTNG_UST_TRACEPOINT_EVENT_INSTANCE(lttng_ust_tracelog, tlclass, _level_enum, \
+ LTTNG_UST_TRACEPOINT_EVENT_INSTANCE(lttng_ust_tracelog, tlclass, \
+ lttng_ust_tracelog, _level_enum, \
LTTNG_UST_TP_ARGS(const char *, file, int, line, const char *, func, \
const char *, msg, unsigned int, len, void *, ip) \
) \
#define lttng_ust__tp_stringify(x) lttng_ust__tp_stringify1(x)
#undef LTTNG_UST_TRACEPOINT_EVENT_INSTANCE
-#define LTTNG_UST_TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, _args)
+#define LTTNG_UST_TRACEPOINT_EVENT_INSTANCE(_template_provider, _template_name, \
+ _provider, _name, _args)
#undef LTTNG_UST_TRACEPOINT_EVENT
#define LTTNG_UST_TRACEPOINT_EVENT(_provider, _name, _args, _fields) \
LTTNG_UST_TRACEPOINT_EVENT_CLASS(_provider, _name, LTTNG_UST__TP_PARAMS(_args), \
LTTNG_UST__TP_PARAMS(_fields)) \
- LTTNG_UST_TRACEPOINT_EVENT_INSTANCE(_provider, _name, _name, \
+ LTTNG_UST_TRACEPOINT_EVENT_INSTANCE(_provider, _name, _provider, _name, \
LTTNG_UST__TP_PARAMS(_args))
#define LTTNG_UST_TRACEPOINT_EVENT_CLASS(provider, name, args, fields)
#undef LTTNG_UST_TRACEPOINT_EVENT_INSTANCE
-#define LTTNG_UST_TRACEPOINT_EVENT_INSTANCE(provider, _template, name, args) \
+#define LTTNG_UST_TRACEPOINT_EVENT_INSTANCE(template_provider, template_name, provider, name, args) \
LTTNG_UST__DECLARE_TRACEPOINT(provider, name, LTTNG_UST__TP_PARAMS(args)) \
LTTNG_UST__DEFINE_TRACEPOINT(provider, name, LTTNG_UST__TP_PARAMS(args))
#define LTTNG_UST_TRACEPOINT_EVENT_CLASS(provider, name, args, fields)
-#define LTTNG_UST_TRACEPOINT_EVENT_INSTANCE(provider, _template, name, args) \
+#define LTTNG_UST_TRACEPOINT_EVENT_INSTANCE(template_provider, template_name, provider, name, args) \
LTTNG_UST__DECLARE_TRACEPOINT(provider, name, LTTNG_UST__TP_PARAMS(args)) \
LTTNG_UST__DEFINE_TRACEPOINT(provider, name, LTTNG_UST__TP_PARAMS(args))
#if LTTNG_UST_COMPAT_API(0)
#define TRACEPOINT_EVENT LTTNG_UST_TRACEPOINT_EVENT
#define TRACEPOINT_EVENT_CLASS LTTNG_UST_TRACEPOINT_EVENT_CLASS
-#define TRACEPOINT_EVENT_INSTANCE LTTNG_UST_TRACEPOINT_EVENT_INSTANCE
+#define TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, args) \
+ LTTNG_UST_TRACEPOINT_EVENT_INSTANCE(_provider, _template, \
+ _provider, _name, LTTNG_UST__TP_PARAMS(args))
+
#endif /* #if LTTNG_UST_COMPAT_API(0) */
#endif /* #ifndef LTTNG_UST_TRACEPOINT_EVENT */
* Older tracepoint providers can always register to newer lttng-ust
* library, but the opposite is rejected: a newer tracepoint provider is
* rejected by an older lttng-ust library.
+ *
+ * LTTNG_UST_PROVIDER_MAJOR_OLDEST_COMPATIBLE is the floor value of
+ * oldest provider major version currently allowed, typically increased
+ * when LTTng-UST has an ABI-breaking soname bump.
*/
-#define LTTNG_UST_PROVIDER_MAJOR 2
+#define LTTNG_UST_PROVIDER_MAJOR 3
+#define LTTNG_UST_PROVIDER_MAJOR_OLDEST_COMPATIBLE 3
#define LTTNG_UST_PROVIDER_MINOR 0
struct lttng_ust_channel_buffer;
/* End of base ABI. Fields below should be used after checking struct_size. */
};
+/*
+ * Tracepoint class description
+ *
+ * IMPORTANT: this structure is part of the ABI between the probe and
+ * UST. Fields need to be only added at the end, never reordered, never
+ * removed.
+ *
+ * The field @struct_size should be used to determine the size of the
+ * structure. It should be queried before using additional fields added
+ * at the end of the structure.
+ */
+
+struct lttng_ust_tracepoint_class {
+ uint32_t struct_size;
+
+ const struct lttng_ust_event_field * const *fields;
+ size_t nr_fields;
+ void (*probe_callback)(void);
+ const char *signature; /* Argument types/names received */
+
+ /* End of base ABI. Fields below should be used after checking struct_size. */
+};
/*
* IMPORTANT: this structure is part of the ABI between the probe and
const char *event_name;
const struct lttng_ust_probe_desc *probe_desc;
- void (*probe_callback)(void);
- const struct lttng_ust_event_field * const *fields; /* event payload */
- unsigned int nr_fields;
+ const struct lttng_ust_tracepoint_class *tp_class;
const int **loglevel;
- const char *signature; /* Argument types/names received */
const char **model_emf_uri;
/* End of base ABI. Fields below should be used after checking struct_size. */
#define LTTNG_UST__TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields)
#undef LTTNG_UST__TRACEPOINT_EVENT_INSTANCE
-#define LTTNG_UST__TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, _args)
+#define LTTNG_UST__TRACEPOINT_EVENT_INSTANCE(_template_provider, _template_name, _provider, _name, _args)
#undef LTTNG_UST_TRACEPOINT_ENUM
#define LTTNG_UST_TRACEPOINT_ENUM(_provider, _name, _values)
LTTNG_UST__TRACEPOINT_EVENT_CLASS(_provider, _name, \
LTTNG_UST__TP_PARAMS(_args), \
LTTNG_UST__TP_PARAMS(_fields)) \
- LTTNG_UST__TRACEPOINT_EVENT_INSTANCE(_provider, _name, _name, \
+ LTTNG_UST__TRACEPOINT_EVENT_INSTANCE(_provider, _name, _provider, _name, \
LTTNG_UST__TP_PARAMS(_args))
#undef LTTNG_UST_TRACEPOINT_EVENT_CLASS
LTTNG_UST__TRACEPOINT_EVENT_CLASS(_provider, _name, LTTNG_UST__TP_PARAMS(_args), LTTNG_UST__TP_PARAMS(_fields))
#undef LTTNG_UST_TRACEPOINT_EVENT_INSTANCE
-#define LTTNG_UST_TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, _args) \
- LTTNG_UST__TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, LTTNG_UST__TP_PARAMS(_args))
+#define LTTNG_UST_TRACEPOINT_EVENT_INSTANCE(_template_provider, _template_name, _provider, _name, _args) \
+ LTTNG_UST__TRACEPOINT_EVENT_INSTANCE(_template_provider, _template_name, _provider, _name, LTTNG_UST__TP_PARAMS(_args))
/* Helpers */
#define LTTNG_UST__TP_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
lttng_ust_tracepoint_provider_mismatch_##_provider();
#undef LTTNG_UST__TRACEPOINT_EVENT_INSTANCE
-#define LTTNG_UST__TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, _args) \
+#define LTTNG_UST__TRACEPOINT_EVENT_INSTANCE(_template_provider, _template_name, _provider, _name, _args) \
lttng_ust_tracepoint_provider_mismatch_##_provider();
static inline
#include <lttng/ust-tracepoint-event-reset.h>
#undef LTTNG_UST__TRACEPOINT_EVENT_INSTANCE
-#define LTTNG_UST__TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, _args) \
+#define LTTNG_UST__TRACEPOINT_EVENT_INSTANCE(_template_provider, _template_name, _provider, _name, _args) \
lttng_ust_tracepoint_validate_name_len(_provider, _name);
#include LTTNG_UST_TRACEPOINT_INCLUDE
#define LTTNG_UST_TP_ARGS(...) __VA_ARGS__
#undef LTTNG_UST__TRACEPOINT_EVENT_INSTANCE
-#define LTTNG_UST__TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, _args) \
-void lttng_ust__event_template_proto___##_provider##___##_template(LTTNG_UST__TP_ARGS_DATA_PROTO(_args));
+#define LTTNG_UST__TRACEPOINT_EVENT_INSTANCE(_template_provider, _template_name, _provider, _name, _args) \
+void lttng_ust__event_template_proto___##_template_provider##___##_template_name(LTTNG_UST__TP_ARGS_DATA_PROTO(_args));
#undef LTTNG_UST__TRACEPOINT_EVENT_CLASS
#define LTTNG_UST__TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \
#include LTTNG_UST_TRACEPOINT_INCLUDE
+/*
+ * Stage 0.9.2 of tracepoint event generation.
+ *
+ * Create probe signature
+ */
+
+/* Reset all macros within LTTNG_UST_TRACEPOINT_EVENT */
+#include <lttng/ust-tracepoint-event-reset.h>
+
+#undef LTTNG_UST_TP_ARGS
+#define LTTNG_UST_TP_ARGS(...) __VA_ARGS__
+
+#define LTTNG_UST__TP_EXTRACT_STRING2(...) #__VA_ARGS__
+
+#undef LTTNG_UST__TRACEPOINT_EVENT_CLASS
+#define LTTNG_UST__TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \
+static const char __tp_event_signature___##_provider##___##_name[] = \
+ LTTNG_UST__TP_EXTRACT_STRING2(_args);
+
+#include LTTNG_UST_TRACEPOINT_INCLUDE
+
+#undef LTTNG_UST__TP_EXTRACT_STRING2
+
/*
* Stage 1 of tracepoint event generation.
*
+ * Create probe callback prototypes.
+ */
+
+/* Reset all macros within LTTNG_UST_TRACEPOINT_EVENT */
+#include <lttng/ust-tracepoint-event-reset.h>
+
+#undef LTTNG_UST_TP_ARGS
+#define LTTNG_UST_TP_ARGS(...) __VA_ARGS__
+
+#undef LTTNG_UST__TRACEPOINT_EVENT_CLASS
+#define LTTNG_UST__TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \
+static void lttng_ust__event_probe__##_provider##___##_name(LTTNG_UST__TP_ARGS_DATA_PROTO(_args));
+
+#include LTTNG_UST_TRACEPOINT_INCLUDE
+
+/*
+ * Stage 2 of tracepoint event generation.
+ *
* Create event field type metadata section.
* Each event produce an array of fields.
*/
static const struct lttng_ust_event_field * const lttng_ust__event_fields___##_provider##___##_name[] = { \
_fields \
lttng_ust_field_integer(int, dummy, 0) /* Dummy, C99 forbids 0-len array. */ \
+ }; \
+ static const struct lttng_ust_tracepoint_class lttng_ust__event_class___##_provider##___##_name = { \
+ .struct_size = sizeof(struct lttng_ust_tracepoint_class), \
+ .fields = lttng_ust__event_fields___##_provider##___##_name, \
+ .nr_fields = LTTNG_UST__TP_ARRAY_SIZE(lttng_ust__event_fields___##_provider##___##_name) - 1, \
+ .probe_callback = (void (*)(void)) <tng_ust__event_probe__##_provider##___##_name, \
+ .signature = __tp_event_signature___##_provider##___##_name, \
};
#undef LTTNG_UST_TRACEPOINT_ENUM
#include LTTNG_UST_TRACEPOINT_INCLUDE
-/*
- * Stage 2 of tracepoint event generation.
- *
- * Create probe callback prototypes.
- */
-
-/* Reset all macros within LTTNG_UST_TRACEPOINT_EVENT */
-#include <lttng/ust-tracepoint-event-reset.h>
-
-#undef LTTNG_UST_TP_ARGS
-#define LTTNG_UST_TP_ARGS(...) __VA_ARGS__
-
-#undef LTTNG_UST__TRACEPOINT_EVENT_CLASS
-#define LTTNG_UST__TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \
-static void lttng_ust__event_probe__##_provider##___##_name(LTTNG_UST__TP_ARGS_DATA_PROTO(_args));
-
-#include LTTNG_UST_TRACEPOINT_INCLUDE
-
/*
* Stage 3.0 of tracepoint event generation.
*
#undef lttng_ust__get_dynamic_len
-/*
- * Stage 5.1 of tracepoint event generation.
- *
- * Create probe signature
- */
-
-/* Reset all macros within LTTNG_UST_TRACEPOINT_EVENT */
-#include <lttng/ust-tracepoint-event-reset.h>
-
-#undef LTTNG_UST_TP_ARGS
-#define LTTNG_UST_TP_ARGS(...) __VA_ARGS__
-
-#define LTTNG_UST__TP_EXTRACT_STRING2(...) #__VA_ARGS__
-
-#undef LTTNG_UST__TRACEPOINT_EVENT_CLASS
-#define LTTNG_UST__TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \
-static const char __tp_event_signature___##_provider##___##_name[] = \
- LTTNG_UST__TP_EXTRACT_STRING2(_args);
-
-#include LTTNG_UST_TRACEPOINT_INCLUDE
-
-#undef LTTNG_UST__TP_EXTRACT_STRING2
-
/*
* Stage 6 of tracepoint event generation.
*
#include <lttng/ust-tracepoint-event-reset.h>
#undef LTTNG_UST__TRACEPOINT_EVENT_INSTANCE
-#define LTTNG_UST__TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, _args) \
+#define LTTNG_UST__TRACEPOINT_EVENT_INSTANCE(_template_provider, _template_name, _provider, _name, _args) \
static const int * \
__ref_loglevel___##_provider##___##_name \
__attribute__((weakref ("_loglevel___" #_provider "___" #_name))); \
.struct_size = sizeof(struct lttng_ust_event_desc), \
.event_name = #_name, \
.probe_desc = <tng_ust__probe_desc___##_provider, \
- .probe_callback = (void (*)(void)) <tng_ust__event_probe__##_provider##___##_template, \
- .fields = lttng_ust__event_fields___##_provider##___##_template, \
- .nr_fields = LTTNG_UST__TP_ARRAY_SIZE(lttng_ust__event_fields___##_provider##___##_template) - 1, \
+ .tp_class = <tng_ust__event_class___##_template_provider##___##_template_name, \
.loglevel = &__ref_loglevel___##_provider##___##_name, \
- .signature = __tp_event_signature___##_provider##___##_template, \
.model_emf_uri = &__ref_model_emf_uri___##_provider##___##_name, \
};
#include <lttng/ust-tracepoint-event-reset.h>
#undef LTTNG_UST__TRACEPOINT_EVENT_INSTANCE
-#define LTTNG_UST__TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, _args) \
+#define LTTNG_UST__TRACEPOINT_EVENT_INSTANCE(_template_provider, _template_name, _provider, _name, _args) \
<tng_ust__event_desc___##_provider##_##_name,
static const struct lttng_ust_event_desc * const LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust__event_desc___, LTTNG_UST_TRACEPOINT_PROVIDER)[] = {
)
LTTNG_UST_TRACEPOINT_EVENT_INSTANCE(lttng_ust_cyg_profile, func_class,
- func_entry,
+ lttng_ust_cyg_profile, func_entry,
LTTNG_UST_TP_ARGS(void *, func_addr, void *, call_site)
)
LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG_FUNCTION)
LTTNG_UST_TRACEPOINT_EVENT_INSTANCE(lttng_ust_cyg_profile, func_class,
- func_exit,
+ lttng_ust_cyg_profile, func_exit,
LTTNG_UST_TP_ARGS(void *, func_addr, void *, call_site)
)
struct bytecode_get_index_data gid;
ssize_t data_offset;
- nr_fields = event_desc->nr_fields;
+ nr_fields = event_desc->tp_class->nr_fields;
offset = ((struct get_symbol *) insn->data)->offset;
name = runtime->p.bc->bc.data + runtime->p.bc->bc.reloc_offset + offset;
for (i = 0; i < nr_fields; i++) {
- field = event_desc->fields[i];
+ field = event_desc->tp_class->fields[i];
if (field->nofilter) {
continue;
}
/* Lookup event by name */
if (!event_desc)
return -EINVAL;
- fields = event_desc->fields;
+ fields = event_desc->tp_class->fields;
if (!fields)
return -EINVAL;
- nr_fields = event_desc->nr_fields;
+ nr_fields = event_desc->tp_class->nr_fields;
for (i = 0; i < nr_fields; i++) {
if (fields[i]->nofilter) {
continue;
desc = event->priv->desc;
ret = lttng_ust_tp_probe_register_queue_release(desc->probe_desc->provider_name,
desc->event_name,
- desc->probe_callback,
- event, desc->signature);
+ desc->tp_class->probe_callback,
+ event, desc->tp_class->signature);
WARN_ON_ONCE(ret);
if (!ret)
event->priv->registered = 1;
desc = event->priv->desc;
ret = lttng_ust_tp_probe_unregister_queue_release(desc->probe_desc->provider_name,
desc->event_name,
- desc->probe_callback,
+ desc->tp_class->probe_callback,
event);
WARN_ON_ONCE(ret);
if (!ret)
goto socket_error;
}
- ret = lttng_create_all_event_enums(desc->nr_fields, desc->fields,
+ ret = lttng_create_all_event_enums(desc->tp_class->nr_fields, desc->tp_class->fields,
session);
if (ret < 0) {
DBG("Error (%d) adding enum to session", ret);
chan->priv->parent.objd,
name,
loglevel,
- desc->signature,
- desc->nr_fields,
- desc->fields,
+ desc->tp_class->signature,
+ desc->tp_class->nr_fields,
+ desc->tp_class->fields,
uri,
&event_recorder->priv->id);
if (ret < 0) {
unsigned int i;
/* Destroy enums of the current event. */
- for (i = 0; i < event_recorder->parent->priv->desc->nr_fields; i++) {
+ for (i = 0; i < event_recorder->parent->priv->desc->tp_class->nr_fields; i++) {
const struct lttng_ust_enum_desc *enum_desc;
const struct lttng_ust_event_field *field;
struct lttng_enum *curr_enum;
- field = event_recorder->parent->priv->desc->fields[i];
+ field = event_recorder->parent->priv->desc->tp_class->fields[i];
switch (field->type->type) {
case lttng_ust_type_enum:
enum_desc = lttng_ust_get_type_enum(field->type)->desc;
/*
* Check tracepoint provider version compatibility.
*/
- if (desc->major <= LTTNG_UST_PROVIDER_MAJOR) {
+ if (desc->major <= LTTNG_UST_PROVIDER_MAJOR &&
+ desc->major >= LTTNG_UST_PROVIDER_MAJOR_OLDEST_COMPATIBLE) {
DBG("Provider \"%s\" accepted, version %u.%u is compatible "
"with LTTng UST provider version %u.%u.",
desc->provider_name, desc->major, desc->minor,
probe_desc->event_desc[i];
int j;
- if (event_desc->nr_fields == 0) {
+ if (event_desc->tp_class->nr_fields == 0) {
/* Events without fields. */
struct tp_field_list_entry *list_entry;
list_entry->field.nowrite = 1;
}
- for (j = 0; j < event_desc->nr_fields; j++) {
+ for (j = 0; j < event_desc->tp_class->nr_fields; j++) {
const struct lttng_ust_event_field *event_field =
- event_desc->fields[j];
+ event_desc->tp_class->fields[j];
struct tp_field_list_entry *list_entry;
/* Skip event if name is too long. */