From f077fc2093a190f45dcd4d6ea54c284c412faae6 Mon Sep 17 00:00:00 2001 From: David Marchand Date: Thu, 30 Jan 2025 12:36:11 +0100 Subject: [PATCH] trace: fix undefined behavior in register Passing the tracepoint handler casted to a void (*)(void) means that, at runtime, the registering code will invoke each handler with no stack allocated. This is an undefined behavior with reading current stack, but doing nothing with the values. This can be seen with UBsan. Signed-off-by: David Marchand --- lib/eal/include/rte_trace_point.h | 4 ++ lib/eal/include/rte_trace_point_register.h | 50 +++++++++++++++++----- 2 files changed, 44 insertions(+), 10 deletions(-) diff --git a/lib/eal/include/rte_trace_point.h b/lib/eal/include/rte_trace_point.h index 62a972db92..84b8521ae9 100644 --- a/lib/eal/include/rte_trace_point.h +++ b/lib/eal/include/rte_trace_point.h @@ -36,6 +36,8 @@ extern "C" { /** The tracepoint object. */ typedef RTE_ATOMIC(uint64_t) rte_trace_point_t; +#ifndef _RTE_TRACE_POINT_REGISTER_H_ + /** * Macro to define the tracepoint arguments in RTE_TRACE_POINT macro. @@ -53,6 +55,8 @@ _tp _args \ __VA_ARGS__ \ } +#endif /* _RTE_TRACE_POINT_REGISTER_H_ */ + /** * Create a tracepoint. * diff --git a/lib/eal/include/rte_trace_point_register.h b/lib/eal/include/rte_trace_point_register.h index 1d6198b32f..7b4f17e910 100644 --- a/lib/eal/include/rte_trace_point_register.h +++ b/lib/eal/include/rte_trace_point_register.h @@ -18,6 +18,43 @@ extern "C" { RTE_DECLARE_PER_LCORE(volatile int, trace_point_sz); +#define RTE_TRACE_POINT_ARGS_COUNT_(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,N, ...) \ + N +#define RTE_TRACE_POINT_ARGS_COUNT(...) \ + RTE_TRACE_POINT_ARGS_COUNT_(__VA_ARGS__,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0) + +#define RTE_TRACE_POINT_ARGS_1(a) __rte_unused a +#define RTE_TRACE_POINT_ARGS_2(a, ...) __rte_unused a, RTE_TRACE_POINT_ARGS_1(__VA_ARGS__) +#define RTE_TRACE_POINT_ARGS_3(a, ...) __rte_unused a, RTE_TRACE_POINT_ARGS_2(__VA_ARGS__) +#define RTE_TRACE_POINT_ARGS_4(a, ...) __rte_unused a, RTE_TRACE_POINT_ARGS_3(__VA_ARGS__) +#define RTE_TRACE_POINT_ARGS_5(a, ...) __rte_unused a, RTE_TRACE_POINT_ARGS_4(__VA_ARGS__) +#define RTE_TRACE_POINT_ARGS_6(a, ...) __rte_unused a, RTE_TRACE_POINT_ARGS_5(__VA_ARGS__) +#define RTE_TRACE_POINT_ARGS_7(a, ...) __rte_unused a, RTE_TRACE_POINT_ARGS_6(__VA_ARGS__) +#define RTE_TRACE_POINT_ARGS_8(a, ...) __rte_unused a, RTE_TRACE_POINT_ARGS_7(__VA_ARGS__) +#define RTE_TRACE_POINT_ARGS_9(a, ...) __rte_unused a, RTE_TRACE_POINT_ARGS_8(__VA_ARGS__) +#define RTE_TRACE_POINT_ARGS_10(a, ...) __rte_unused a, RTE_TRACE_POINT_ARGS_9(__VA_ARGS__) +#define RTE_TRACE_POINT_ARGS_11(a, ...) __rte_unused a, RTE_TRACE_POINT_ARGS_10(__VA_ARGS__) +#define RTE_TRACE_POINT_ARGS_12(a, ...) __rte_unused a, RTE_TRACE_POINT_ARGS_11(__VA_ARGS__) +#define RTE_TRACE_POINT_ARGS_13(a, ...) __rte_unused a, RTE_TRACE_POINT_ARGS_12(__VA_ARGS__) +#define RTE_TRACE_POINT_ARGS_14(a, ...) __rte_unused a, RTE_TRACE_POINT_ARGS_13(__VA_ARGS__) +#define RTE_TRACE_POINT_ARGS_15(a, ...) __rte_unused a, RTE_TRACE_POINT_ARGS_14(__VA_ARGS__) +#define RTE_TRACE_POINT_ARGS_FUNC(a) RTE_TRACE_POINT_ARGS_ ## a +#define RTE_TRACE_POINT_ARGS_EXPAND(...) __VA_ARGS__ +#define RTE_TRACE_POINT_ARGS_(N, ...) \ + RTE_TRACE_POINT_ARGS_EXPAND(RTE_TRACE_POINT_ARGS_FUNC(N))(__VA_ARGS__) +#define RTE_TRACE_POINT_ARGS(...) \ + (RTE_TRACE_POINT_ARGS_(RTE_TRACE_POINT_ARGS_COUNT(0, __VA_ARGS__), __VA_ARGS__)) + +#define __RTE_TRACE_POINT(_mode, _tp, _args, ...) \ +extern rte_trace_point_t __##_tp; \ +static __rte_always_inline void _tp _args { } \ +static __rte_always_inline void \ +_tp ## _register (void) \ +{ \ + __rte_trace_point_emit_header_##_mode(&__##_tp); \ + __VA_ARGS__ \ +} + #define RTE_TRACE_POINT_REGISTER(trace, name) \ rte_trace_point_t __rte_section("__rte_trace_point") __##trace; \ static const char __##trace##_name[] = RTE_STR(name); \ @@ -26,7 +63,7 @@ RTE_INIT(trace##_init) \ if (!rte_trace_feature_is_enabled()) \ return; \ __rte_trace_point_register(&__##trace, __##trace##_name, \ - (void (*)(void)) trace); \ + trace ## _register); \ } #define __rte_trace_point_emit_header_generic(t) \ @@ -36,22 +73,15 @@ RTE_INIT(trace##_init) \ __rte_trace_point_emit_header_generic(t) #define __rte_trace_point_emit(in, type) \ -do { \ - RTE_SET_USED(in); \ __rte_trace_point_emit_field(sizeof(type), RTE_STR(in), \ - RTE_STR(type)); \ -} while (0) + RTE_STR(type)) #define rte_trace_point_emit_string(in) \ -do { \ - RTE_SET_USED(in); \ __rte_trace_point_emit_field(__RTE_TRACE_EMIT_STRING_LEN_MAX, \ - RTE_STR(in)"[32]", "string_bounded_t"); \ -} while (0) + RTE_STR(in)"[32]", "string_bounded_t") #define rte_trace_point_emit_blob(in, len) \ do { \ - RTE_SET_USED(in); \ __rte_trace_point_emit(len, uint8_t); \ __rte_trace_point_emit_field(RTE_TRACE_BLOB_LEN_MAX, \ RTE_STR(in)"[" RTE_STR(RTE_TRACE_BLOB_LEN_MAX)"]", \