X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=include%2Flttng%2Fust-tracepoint-event.h;h=88953108e65506573dc6740e54ab69f7323fdd1a;hb=8029811d7126f23d0a2cc796f8cb4b86474541bb;hp=f6e3a5e87f98ca596adfe94cdfb3d2f626210bc8;hpb=46d522007b647e0b64d18d0ed518205c2bbad424;p=lttng-ust.git diff --git a/include/lttng/ust-tracepoint-event.h b/include/lttng/ust-tracepoint-event.h index f6e3a5e8..88953108 100644 --- a/include/lttng/ust-tracepoint-event.h +++ b/include/lttng/ust-tracepoint-event.h @@ -21,6 +21,7 @@ */ #include +#include #include #include #include @@ -74,6 +75,8 @@ /* Reset all macros within TRACEPOINT_EVENT */ #include +static inline lttng_ust_notrace +void _TP_COMBINE_TOKENS(__tracepoint_provider_mismatch_, TRACEPOINT_PROVIDER)(void); static inline void _TP_COMBINE_TOKENS(__tracepoint_provider_mismatch_, TRACEPOINT_PROVIDER)(void) { @@ -87,6 +90,8 @@ void _TP_COMBINE_TOKENS(__tracepoint_provider_mismatch_, TRACEPOINT_PROVIDER)(vo #define TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, _args) \ __tracepoint_provider_mismatch_##_provider(); +static inline lttng_ust_notrace +void _TP_COMBINE_TOKENS(__tracepoint_provider_check_, TRACEPOINT_PROVIDER)(void); static inline void _TP_COMBINE_TOKENS(__tracepoint_provider_check_, TRACEPOINT_PROVIDER)(void) { @@ -301,10 +306,66 @@ size_t __event_get_size__##_provider##___##_name(size_t *__dynamic_len, _TP_ARGS #undef _ctf_integer_ext #define _ctf_integer_ext(_type, _item, _src, _byte_order, _base, _nowrite) \ if (lttng_is_signed_type(_type)) { \ - int64_t __ctf_tmp_int64 = (int64_t) (_type) (_src); \ + int64_t __ctf_tmp_int64; \ + switch (sizeof(_type)) { \ + case 1: \ + { \ + union { _type t; int8_t v; } __tmp = { (_type) (_src) }; \ + __ctf_tmp_int64 = (int64_t) __tmp.v; \ + break; \ + } \ + case 2: \ + { \ + union { _type t; int16_t v; } __tmp = { (_type) (_src) }; \ + __ctf_tmp_int64 = (int64_t) __tmp.v; \ + break; \ + } \ + case 4: \ + { \ + union { _type t; int32_t v; } __tmp = { (_type) (_src) }; \ + __ctf_tmp_int64 = (int64_t) __tmp.v; \ + break; \ + } \ + case 8: \ + { \ + union { _type t; int64_t v; } __tmp = { (_type) (_src) }; \ + __ctf_tmp_int64 = (int64_t) __tmp.v; \ + break; \ + } \ + default: \ + abort(); \ + }; \ memcpy(__stack_data, &__ctf_tmp_int64, sizeof(int64_t)); \ } else { \ - uint64_t __ctf_tmp_uint64 = (uint64_t) (_type) (_src); \ + uint64_t __ctf_tmp_uint64; \ + switch (sizeof(_type)) { \ + case 1: \ + { \ + union { _type t; uint8_t v; } __tmp = { (_type) (_src) }; \ + __ctf_tmp_uint64 = (uint64_t) __tmp.v; \ + break; \ + } \ + case 2: \ + { \ + union { _type t; uint16_t v; } __tmp = { (_type) (_src) }; \ + __ctf_tmp_uint64 = (uint64_t) __tmp.v; \ + break; \ + } \ + case 4: \ + { \ + union { _type t; uint32_t v; } __tmp = { (_type) (_src) }; \ + __ctf_tmp_uint64 = (uint64_t) __tmp.v; \ + break; \ + } \ + case 8: \ + { \ + union { _type t; uint64_t v; } __tmp = { (_type) (_src) }; \ + __ctf_tmp_uint64 = (uint64_t) __tmp.v; \ + break; \ + } \ + default: \ + abort(); \ + }; \ memcpy(__stack_data, &__ctf_tmp_uint64, sizeof(uint64_t)); \ } \ __stack_data += sizeof(int64_t); @@ -463,10 +524,24 @@ size_t __event_get_align__##_provider##___##_name(_TP_ARGS_PROTO(_args)) \ __chan->ops->event_write(&__ctx, _src, \ sizeof(_type) * __get_dynamic_len(dest)); +/* + * __chan->ops->u.has_strcpy is a flag letting us know if the LTTng-UST + * tracepoint provider ABI implements event_strcpy. This dynamic check + * can be removed when the tracepoint provider ABI moves to 2. + */ +#if (LTTNG_UST_PROVIDER_MAJOR > 1) +#error "Tracepoint probe provider major version has changed. Please remove dynamic check for has_strcpy." +#endif + #undef _ctf_string #define _ctf_string(_item, _src, _nowrite) \ lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(*(_src))); \ - __chan->ops->event_write(&__ctx, _src, __get_dynamic_len(dest)); + if (__chan->ops->u.has_strcpy) \ + __chan->ops->event_strcpy(&__ctx, _src, \ + __get_dynamic_len(dest)); \ + else \ + __chan->ops->event_write(&__ctx, _src, \ + __get_dynamic_len(dest)); /* Beware: this get len actually consumes the len value */ #undef __get_dynamic_len @@ -478,6 +553,18 @@ size_t __event_get_align__##_provider##___##_name(_TP_ARGS_PROTO(_args)) \ #undef TP_FIELDS #define TP_FIELDS(...) __VA_ARGS__ +/* + * For state dump, check that "session" argument (mandatory) matches the + * session this event belongs to. Ensures that we write state dump data only + * into the started session, not into all sessions. + */ +#undef _TP_SESSION_CHECK +#ifdef TP_SESSION_CHECK +#define _TP_SESSION_CHECK(session, csession) (session == csession) +#else /* TP_SESSION_CHECK */ +#define _TP_SESSION_CHECK(session, csession) 1 +#endif /* TP_SESSION_CHECK */ + /* * Using twice size for filter stack data to hold size and pointer for * each field (worse case). For integers, max size required is 64-bit. @@ -505,6 +592,8 @@ void __event_probe__##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args)) \ \ if (0) \ (void) __dynamic_len_idx; /* don't warn if unused */ \ + if (!_TP_SESSION_CHECK(session, __chan->session)) \ + return; \ if (caa_unlikely(!CMM_ACCESS_ONCE(__chan->session->active))) \ return; \ if (caa_unlikely(!CMM_ACCESS_ONCE(__chan->enabled))) \ @@ -532,6 +621,7 @@ void __event_probe__##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args)) \ __event_align = __event_get_align__##_provider##___##_name(_TP_ARGS_VAR(_args)); \ lib_ring_buffer_ctx_init(&__ctx, __chan->chan, __event, __event_len, \ __event_align, -1, __chan->handle); \ + __ctx.ip = __builtin_return_address(0); \ __ret = __chan->ops->event_reserve(&__ctx, __event->id); \ if (__ret < 0) \ return; \ @@ -669,6 +759,8 @@ static struct lttng_probe_desc _TP_COMBINE_TOKENS(__probe_desc___, TRACEPOINT_PR .minor = LTTNG_UST_PROVIDER_MINOR, }; +static int _TP_COMBINE_TOKENS(__probe_register_refcount___, TRACEPOINT_PROVIDER); + /* * Stage 9 of tracepoint event generation. * @@ -676,6 +768,8 @@ static struct lttng_probe_desc _TP_COMBINE_TOKENS(__probe_desc___, TRACEPOINT_PR * * Generate the constructor as an externally visible symbol for use when * linking the probe statically. + * + * Register refcount is protected by libc dynamic loader mutex. */ /* Reset all macros within TRACEPOINT_EVENT */ @@ -687,6 +781,10 @@ _TP_COMBINE_TOKENS(__lttng_events_init__, TRACEPOINT_PROVIDER)(void) { int ret; + if (_TP_COMBINE_TOKENS(__probe_register_refcount___, + TRACEPOINT_PROVIDER)++) { + return; + } /* * __tracepoint_provider_check_ ## TRACEPOINT_PROVIDER() is a * static inline function that ensures every probe PROVIDER @@ -697,7 +795,10 @@ _TP_COMBINE_TOKENS(__lttng_events_init__, TRACEPOINT_PROVIDER)(void) */ _TP_COMBINE_TOKENS(__tracepoint_provider_check_, TRACEPOINT_PROVIDER)(); ret = lttng_probe_register(&_TP_COMBINE_TOKENS(__probe_desc___, TRACEPOINT_PROVIDER)); - assert(!ret); + if (ret) { + fprintf(stderr, "LTTng-UST: Error (%d) while registering tracepoint probe. Duplicate registration of tracepoint probes having the same name is not allowed.\n", ret); + abort(); + } } static void lttng_ust_notrace __attribute__((destructor)) @@ -705,6 +806,10 @@ _TP_COMBINE_TOKENS(__lttng_events_exit__, TRACEPOINT_PROVIDER)(void); static void _TP_COMBINE_TOKENS(__lttng_events_exit__, TRACEPOINT_PROVIDER)(void) { + if (--_TP_COMBINE_TOKENS(__probe_register_refcount___, + TRACEPOINT_PROVIDER)) { + return; + } lttng_probe_unregister(&_TP_COMBINE_TOKENS(__probe_desc___, TRACEPOINT_PROVIDER)); }