From f641d544ea2630c5a52c0cbc5db947d34461cea7 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Wed, 17 Mar 2021 12:44:51 -0400 Subject: [PATCH] Refactoring: Introduce extensibility scheme for tracepoint structures - Introduce struct_size extensibility scheme for all tracepoint public structures, except for struct lttng_ust_tracepoint_probe which is embedded in a public array of structures, thus making it tricky for instrumentation sites to efficiently skip over the array elements without reading their size. - Remove padding from those structures. Signed-off-by: Mathieu Desnoyers Change-Id: I2387a62c03f6f729c59ddc3fafa3a9b5546fb287 --- include/lttng/tracepoint-types.h | 29 +++++++++++++++++++++++-- include/lttng/tracepoint.h | 37 +++++++++++++++++++++++++++----- 2 files changed, 59 insertions(+), 7 deletions(-) diff --git a/include/lttng/tracepoint-types.h b/include/lttng/tracepoint-types.h index ceb476a6..5354c369 100644 --- a/include/lttng/tracepoint-types.h +++ b/include/lttng/tracepoint-types.h @@ -7,19 +7,44 @@ #ifndef _LTTNG_TRACEPOINT_TYPES_H #define _LTTNG_TRACEPOINT_TYPES_H +#include + +/* + * Tracepoint probe definition + * + * IMPORTANT: this structure is part of the ABI between instrumented + * applications and UST. This structure is fixed-size because it is part + * of a public array of structures. Rather than extending this + * structure, struct lttng_ust_tracepoint should be extended instead. + */ + struct lttng_ust_tracepoint_probe { void (*func)(void); void *data; }; -#define LTTNG_UST_TRACEPOINT_PADDING 16 +/* + * Tracepoint definition + * + * IMPORTANT: this structure is part of the ABI between instrumented + * applications 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 { + uint32_t struct_size; + const char *name; int state; struct lttng_ust_tracepoint_probe *probes; int *tracepoint_provider_ref; const char *signature; - char padding[LTTNG_UST_TRACEPOINT_PADDING]; + + /* End of base ABI. Fields below should be used after checking struct_size. */ }; #endif /* _LTTNG_TRACEPOINT_TYPES_H */ diff --git a/include/lttng/tracepoint.h b/include/lttng/tracepoint.h index bcab5e2d..71f3e36c 100644 --- a/include/lttng/tracepoint.h +++ b/include/lttng/tracepoint.h @@ -210,8 +210,18 @@ extern int __tracepoint_probe_unregister(const char *name, void (*func)(void), /* * tracepoint dynamic linkage handling (callbacks). Hidden visibility: * shared across objects in a module/main executable. + * + * IMPORTANT: this structure is part of the ABI between instrumented + * applications 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_dlopen { + uint32_t struct_size; + void *liblttngust_handle; int (*tracepoint_register_lib)(struct lttng_ust_tracepoint * const *tracepoints_start, @@ -220,6 +230,8 @@ struct lttng_ust_tracepoint_dlopen { void (*rcu_read_lock_sym)(void); void (*rcu_read_unlock_sym)(void); void *(*rcu_dereference_sym)(void *p); + + /* End of base ABI. Fields below should be used after checking struct_size. */ }; extern struct lttng_ust_tracepoint_dlopen tracepoint_dlopen; @@ -235,7 +247,9 @@ int __tracepoint_registered int __tracepoint_ptrs_registered __attribute__((weak, visibility("hidden"))); struct lttng_ust_tracepoint_dlopen tracepoint_dlopen - __attribute__((weak, visibility("hidden"))); + __attribute__((weak, visibility("hidden"))) = { + .struct_size = sizeof(struct lttng_ust_tracepoint_dlopen), +}; /* * Deal with gcc O1 optimisation issues with weak hidden symbols. gcc * 4.8 and prior does not have the same behavior for symbol scoping on @@ -253,17 +267,31 @@ struct lttng_ust_tracepoint_dlopen *tracepoint_dlopen_ptr * Tracepoint dynamic linkage handling (callbacks). Hidden visibility: shared * across objects in a module/main executable. The callbacks are used to * control and check if the destructors should be executed. + * + * IMPORTANT: this structure is part of the ABI between instrumented + * applications 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_destructors_syms { + uint32_t struct_size; + void (*tracepoint_disable_destructors)(void); int (*tracepoint_get_destructors_state)(void); + + /* End of base ABI. Fields below should be used after checking struct_size. */ }; extern struct lttng_ust_tracepoint_destructors_syms tracepoint_destructors_syms; extern struct lttng_ust_tracepoint_destructors_syms *tracepoint_destructors_syms_ptr; struct lttng_ust_tracepoint_destructors_syms tracepoint_destructors_syms - __attribute__((weak, visibility("hidden"))); + __attribute__((weak, visibility("hidden"))) = { + .struct_size = sizeof(struct lttng_ust_tracepoint_destructors_syms), +}; struct lttng_ust_tracepoint_destructors_syms *tracepoint_destructors_syms_ptr __attribute__((weak, visibility("hidden"))); @@ -414,14 +442,13 @@ extern struct lttng_ust_tracepoint * const __stop___tracepoints_ptrs[] __attribute__((section("__tracepoints_strings"))) = \ #_provider ":" #_name; \ struct lttng_ust_tracepoint __tracepoint_##_provider##___##_name \ - __attribute__((section("__tracepoints"))) = \ - { \ + __attribute__((section("__tracepoints"))) = { \ + sizeof(struct lttng_ust_tracepoint), \ __tp_strtab_##_provider##___##_name, \ 0, \ NULL, \ _TRACEPOINT_UNDEFINED_REF(_provider), \ _TP_EXTRACT_STRING(_args), \ - { }, \ }; \ static struct lttng_ust_tracepoint * \ __tracepoint_ptr_##_provider##___##_name \ -- 2.34.1