#include <lttng/ust-config.h> /* for sdt */
#include <lttng/ust-compiler.h>
#include <lttng/ust-tracer.h>
+#include <lttng/ust-api-compat.h>
+
+#define LTTNG_UST_TRACEPOINT_NAME_LEN_MAX 256
#ifdef LTTNG_UST_HAVE_SDT_INTEGRATION
/*
*/
#include <sys/sdt.h>
-#define _LTTNG_SDT_NARG(...) \
- __LTTNG_SDT_NARG(__VA_ARGS__, 12,11,10,9,8,7,6,5,4,3,2,1,0)
+#define _LTTNG_UST_SDT_NARG(...) \
+ __LTTNG_UST_SDT_NARG(__VA_ARGS__, 12,11,10,9,8,7,6,5,4,3,2,1,0)
-#define __LTTNG_SDT_NARG(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12, N, ...) N
+#define __LTTNG_UST_SDT_NARG(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12, N, ...) N
-#define _LTTNG_SDT_PROBE_N(provider, name, N, ...) \
+#define _LTTNG_UST_SDT_PROBE_N(provider, name, N, ...) \
_SDT_PROBE(provider, name, N, (__VA_ARGS__))
-#define LTTNG_STAP_PROBEV(provider, name, ...) \
- _LTTNG_SDT_PROBE_N(provider, name, _LTTNG_SDT_NARG(0, ##__VA_ARGS__), ##__VA_ARGS__)
+#define LTTNG_UST_STAP_PROBEV(provider, name, ...) \
+ _LTTNG_UST_SDT_PROBE_N(provider, name, _LTTNG_UST_SDT_NARG(0, ##__VA_ARGS__), ##__VA_ARGS__)
#else
-#define LTTNG_STAP_PROBEV(...)
+#define LTTNG_UST_STAP_PROBEV(...)
#endif
#ifdef __cplusplus
extern "C" {
#endif
-#define tracepoint_enabled(provider, name) \
+#define lttng_ust_tracepoint_enabled(provider, name) \
caa_unlikely(CMM_LOAD_SHARED(__tracepoint_##provider##___##name.state))
-#define do_tracepoint(provider, name, ...) \
+#define lttng_ust_do_tracepoint(provider, name, ...) \
__tracepoint_cb_##provider##___##name(__VA_ARGS__)
-#define tracepoint(provider, name, ...) \
- do { \
- LTTNG_STAP_PROBEV(provider, name, ## __VA_ARGS__); \
- if (tracepoint_enabled(provider, name)) \
- do_tracepoint(provider, name, __VA_ARGS__); \
+#define lttng_ust_tracepoint(provider, name, ...) \
+ do { \
+ LTTNG_UST_STAP_PROBEV(provider, name, ## __VA_ARGS__); \
+ if (lttng_ust_tracepoint_enabled(provider, name)) \
+ lttng_ust_do_tracepoint(provider, name, __VA_ARGS__); \
} while (0)
-#define TP_ARGS(...) __VA_ARGS__
+#define LTTNG_UST_TP_ARGS(...) __VA_ARGS__
/*
- * TP_ARGS takes tuples of type, argument separated by a comma.
+ * LTTNG_UST_TP_ARGS takes tuples of type, argument separated by a comma.
* It can take up to 10 tuples (which means that less than 10 tuples is
* fine too).
* Each tuple is also separated by a comma.
#define _TP_ARGS_DATA_VAR(...) _TP_DATA_VAR_N(_TP_NARGS(0, ##__VA_ARGS__), ##__VA_ARGS__)
#define _TP_PARAMS(...) __VA_ARGS__
+/*
+ * sizeof(#_provider) - 1 : length of the provider string (excluding \0).
+ * sizeof(#_name) - 1 : length of the name string (excluding \0).
+ * + 1 : separator between provider and event name.
+ *
+ * Upper bound (inclusive) is LTTNG_UST_TRACEPOINT_NAME_LEN_MAX - 1 to
+ * account for \0.
+ *
+ * The comparison is:
+ * left hand side: sizeof(#_provider) - 1 + sizeof(#_name) - 1 + 1
+ * right hand side: LTTNG_UST_TRACEPOINT_NAME_LEN_MAX - 1
+ * operator: <= (inclusive)
+ * Simplified in the code below.
+ */
+#define lttng_ust_tracepoint_validate_name_len(_provider, _name) \
+ lttng_ust_static_assert(sizeof(#_provider) + sizeof(#_name) <= LTTNG_UST_TRACEPOINT_NAME_LEN_MAX, \
+ "Tracepoint name length is too long", \
+ Tracepoint_name_length_is_too_long)
+
/*
* The tracepoint cb is marked always inline so we can distinguish
* between caller's ip addresses within the probe using the return
* address.
*/
-#define _DECLARE_TRACEPOINT(_provider, _name, ...) \
+#define LTTNG_UST__DECLARE_TRACEPOINT(_provider, _name, ...) \
extern struct lttng_ust_tracepoint __tracepoint_##_provider##___##_name; \
-static inline __attribute__((always_inline, unused)) lttng_ust_notrace \
-void __tracepoint_cb_##_provider##___##_name(_TP_ARGS_PROTO(__VA_ARGS__)); \
+static inline \
+void __tracepoint_cb_##_provider##___##_name(_TP_ARGS_PROTO(__VA_ARGS__)) \
+ __attribute__((always_inline, unused)) lttng_ust_notrace; \
static \
void __tracepoint_cb_##_provider##___##_name(_TP_ARGS_PROTO(__VA_ARGS__)) \
{ \
end: \
tp_rcu_read_unlock(); \
} \
-static inline lttng_ust_notrace \
-void __tracepoint_register_##_provider##___##_name(char *name, \
- void (*func)(void), void *data); \
static inline \
-void __tracepoint_register_##_provider##___##_name(char *name, \
+void __tracepoint_register_##_provider##___##_name(char *provider_name, char *event_name, \
+ void (*func)(void), void *data) \
+ lttng_ust_notrace; \
+static inline \
+void __tracepoint_register_##_provider##___##_name(char *provider_name, char *event_name, \
void (*func)(void), void *data) \
{ \
- __tracepoint_probe_register(name, func, data, \
+ __tracepoint_probe_register(provider_name, event_name, func, data, \
__tracepoint_##_provider##___##_name.signature); \
} \
-static inline lttng_ust_notrace \
-void __tracepoint_unregister_##_provider##___##_name(char *name, \
- void (*func)(void), void *data); \
static inline \
-void __tracepoint_unregister_##_provider##___##_name(char *name, \
+void __tracepoint_unregister_##_provider##___##_name(char *provider_name, char *event_name, \
+ void (*func)(void), void *data) \
+ lttng_ust_notrace; \
+static inline \
+void __tracepoint_unregister_##_provider##___##_name(char *provider_name, char *event_name, \
void (*func)(void), void *data) \
{ \
- __tracepoint_probe_unregister(name, func, data); \
+ __tracepoint_probe_unregister(provider_name, event_name, func, data); \
}
-extern int __tracepoint_probe_register(const char *name, void (*func)(void),
- void *data, const char *signature);
-extern int __tracepoint_probe_unregister(const char *name, void (*func)(void),
- void *data);
+extern int __tracepoint_probe_register(const char *provider_name, const char *event_name,
+ void (*func)(void), void *data, const char *signature);
+extern int __tracepoint_probe_unregister(const char *provider_name, const char *event_name,
+ void (*func)(void), void *data);
/*
* tracepoint dynamic linkage handling (callbacks). Hidden visibility:
}
#ifndef _LGPL_SOURCE
-static inline void lttng_ust_notrace
-__tracepoint__init_urcu_sym(void);
+static inline void
+__tracepoint__init_urcu_sym(void)
+ lttng_ust_notrace;
static inline void
__tracepoint__init_urcu_sym(void)
{
"tp_rcu_dereference_sym"));
}
#else
-static inline void lttng_ust_notrace
-__tracepoint__init_urcu_sym(void);
+static inline void
+__tracepoint__init_urcu_sym(void)
+ lttng_ust_notrace;
static inline void
__tracepoint__init_urcu_sym(void)
{
}
#endif
-static void lttng_ust_notrace __attribute__((constructor))
-__tracepoints__init(void);
+static void
+__tracepoints__init(void)
+ lttng_ust_notrace __attribute__((constructor));
static void
__tracepoints__init(void)
{
__tracepoint__init_urcu_sym();
}
-static void lttng_ust_notrace __attribute__((destructor))
-__tracepoints__destroy(void);
+static void
+__tracepoints__destroy(void)
+ lttng_ust_notrace __attribute__((destructor));
static void
__tracepoints__destroy(void)
{
*/
#define _TP_EXTRACT_STRING(...) #__VA_ARGS__
-#define _DEFINE_TRACEPOINT(_provider, _name, _args) \
+#define LTTNG_UST__DEFINE_TRACEPOINT(_provider, _name, _args) \
+ lttng_ust_tracepoint_validate_name_len(_provider, _name); \
extern int __tracepoint_provider_##_provider; \
- static const char __tp_strtab_##_provider##___##_name[] \
+ static const char __tp_provider_strtab_##_provider##___##_name[] \
+ __attribute__((section("__tracepoints_strings"))) = \
+ #_provider; \
+ static const char __tp_name_strtab_##_provider##___##_name[] \
__attribute__((section("__tracepoints_strings"))) = \
- #_provider ":" #_name; \
+ #_name; \
struct lttng_ust_tracepoint __tracepoint_##_provider##___##_name \
__attribute__((section("__tracepoints"))) = { \
sizeof(struct lttng_ust_tracepoint), \
- __tp_strtab_##_provider##___##_name, \
+ __tp_provider_strtab_##_provider##___##_name, \
+ __tp_name_strtab_##_provider##___##_name, \
0, \
NULL, \
_TRACEPOINT_UNDEFINED_REF(_provider), \
__lttng_ust_variable_attribute_no_sanitize_address = \
&__tracepoint_##_provider##___##_name;
-static void lttng_ust_notrace __attribute__((constructor))
-__tracepoints__ptrs_init(void);
+static void
+__tracepoints__ptrs_init(void)
+ lttng_ust_notrace __attribute__((constructor));
static void
__tracepoints__ptrs_init(void)
{
}
}
-static void lttng_ust_notrace __attribute__((destructor))
-__tracepoints__ptrs_destroy(void);
+static void
+__tracepoints__ptrs_destroy(void)
+ lttng_ust_notrace __attribute__((destructor));
static void
__tracepoints__ptrs_destroy(void)
{
#else /* TRACEPOINT_DEFINE */
-#define _DEFINE_TRACEPOINT(_provider, _name, _args)
+#define LTTNG_UST__DEFINE_TRACEPOINT(_provider, _name, _args)
#endif /* #else TRACEPOINT_DEFINE */
+#if LTTNG_UST_COMPAT_API(0)
+#define tracepoint lttng_ust_tracepoint
+#define do_tracepoint lttng_ust_do_tracepoint
+#define tracepoint_enabled lttng_ust_tracepoint_enabled
+#define TP_ARGS LTTNG_UST_TP_ARGS
+#define TP_FIELDS LTTNG_UST_TP_FIELDS
+#endif /* #if LTTNG_UST_COMPAT_API(0) */
+
#ifdef __cplusplus
}
#endif
#endif /* #ifndef TRACEPOINT_ENUM */
-#ifndef TRACEPOINT_EVENT
+#ifndef LTTNG_UST_TRACEPOINT_EVENT
/*
- * How to use the TRACEPOINT_EVENT macro:
+ * How to use the LTTNG_UST_TRACEPOINT_EVENT macro:
*
* An example:
*
- * TRACEPOINT_EVENT(someproject_component, event_name,
+ * LTTNG_UST_TRACEPOINT_EVENT(someproject_component, event_name,
*
- * * TP_ARGS takes from 0 to 10 "type, field_name" pairs *
+ * * LTTNG_UST_TP_ARGS takes from 0 to 10 "type, field_name" pairs *
*
- * TP_ARGS(int, arg0, void *, arg1, char *, string, size_t, strlen,
+ * LTTNG_UST_TP_ARGS(int, arg0, void *, arg1, char *, string, size_t, strlen,
* long *, arg4, size_t, arg4_len),
*
- * * TP_FIELDS describes the event payload layout in the trace *
+ * * LTTNG_UST_TP_FIELDS describes the event payload layout in the trace *
*
- * TP_FIELDS(
+ * LTTNG_UST_TP_FIELDS(
* * Integer, printed in base 10 *
* ctf_integer(int, field_a, arg0)
*
* the provider:event identifier is limited to 127 characters.
*/
-#define TRACEPOINT_EVENT(provider, name, args, fields) \
- _DECLARE_TRACEPOINT(provider, name, _TP_PARAMS(args)) \
- _DEFINE_TRACEPOINT(provider, name, _TP_PARAMS(args))
+#define LTTNG_UST_TRACEPOINT_EVENT(provider, name, args, fields) \
+ LTTNG_UST__DECLARE_TRACEPOINT(provider, name, _TP_PARAMS(args)) \
+ LTTNG_UST__DEFINE_TRACEPOINT(provider, name, _TP_PARAMS(args))
+
+#define LTTNG_UST_TRACEPOINT_EVENT_CLASS(provider, name, args, fields)
-#define TRACEPOINT_EVENT_CLASS(provider, name, args, fields)
+#define LTTNG_UST_TRACEPOINT_EVENT_INSTANCE(provider, _template, name, args) \
+ LTTNG_UST__DECLARE_TRACEPOINT(provider, name, _TP_PARAMS(args)) \
+ LTTNG_UST__DEFINE_TRACEPOINT(provider, name, _TP_PARAMS(args))
-#define TRACEPOINT_EVENT_INSTANCE(provider, _template, name, args) \
- _DECLARE_TRACEPOINT(provider, name, _TP_PARAMS(args)) \
- _DEFINE_TRACEPOINT(provider, name, _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
+#endif /* #if LTTNG_UST_COMPAT_API(0) */
-#endif /* #ifndef TRACEPOINT_EVENT */
+#endif /* #ifndef LTTNG_UST_TRACEPOINT_EVENT */
#ifndef TRACEPOINT_LOGLEVEL
* debug information with function-level scope
*
* TRACE_DEBUG_LINE 13
- * debug information with line-level scope (TRACEPOINT_EVENT default)
+ * debug information with line-level scope (LTTNG_UST_TRACEPOINT_EVENT default)
*
* TRACE_DEBUG 14
* debug-level message
*
- * Declare tracepoint loglevels for tracepoints. A TRACEPOINT_EVENT
+ * Declare tracepoint loglevels for tracepoints. A LTTNG_UST_TRACEPOINT_EVENT
* should be declared prior to the the TRACEPOINT_LOGLEVEL for a given
* tracepoint name. The first field is the provider name, the second
* field is the name of the tracepoint, the third field is the loglevel