mirror of
https://github.com/Dasharo/zephyr.git
synced 2026-03-06 14:57:20 -08:00
logging: Prevent multiple arguments evaluation
Logging v2 is utilizing complex preprocessing operations to prepare message at compile time. Multiple operations are peformed on log message arguments. However, it is expected that argument will be evaluated only once (e.g. it can be a call to a function with side effects). Adding additional layer which creates copies of user arguments on stack and passes them to further processing. Updated test for log_msg2 which is using internal macro which got renamed. Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
This commit is contained in:
committed by
Carles Cufí
parent
154ca8526c
commit
a662e69cad
@@ -324,7 +324,7 @@ do { \
|
||||
* @param ... Optional string with arguments (fmt, ...). It may be empty.
|
||||
*/
|
||||
#ifdef CONFIG_LOG2_ALWAYS_RUNTIME
|
||||
#define Z_LOG_MSG2_CREATE3(_try_0cpy, _mode, _cstr_cnt, _domain_id, _source,\
|
||||
#define Z_LOG_MSG2_CREATE2(_try_0cpy, _mode, _cstr_cnt, _domain_id, _source,\
|
||||
_level, _data, _dlen, ...) \
|
||||
do {\
|
||||
Z_LOG_MSG2_STR_VAR(_fmt, ##__VA_ARGS__) \
|
||||
@@ -357,42 +357,45 @@ do { \
|
||||
} \
|
||||
(void)_mode; \
|
||||
} while (0)
|
||||
#endif /* CONFIG_LOG2_ALWAYS_RUNTIME */
|
||||
|
||||
#define Z_LOG_MSG2_CREATE2(_try_0cpy, _mode, _domain_id, _source,\
|
||||
_level, _data, _dlen, ...) \
|
||||
Z_LOG_MSG2_CREATE3(_try_0cpy, _mode, UTIL_CAT(Z_LOG_FUNC_PREFIX_, _level), \
|
||||
_domain_id, _source, _level, _data, _dlen, \
|
||||
Z_LOG_STR(_level, __VA_ARGS__))
|
||||
#if defined(__cplusplus)
|
||||
#define Z_AUTO_TYPE auto
|
||||
#else
|
||||
#define Z_AUTO_TYPE __auto_type
|
||||
#endif
|
||||
|
||||
/* Macro for getting name of a local variable with the exception of the first argument
|
||||
* which is a formatted string in log message.
|
||||
*/
|
||||
#define Z_LOG_LOCAL_ARG_NAME(idx, arg) COND_CODE_0(idx, (arg), (_v##idx))
|
||||
|
||||
/* Create local variable from input variable (expect first (fmt) argument). */
|
||||
#ifdef __cplusplus
|
||||
/* Create local variable from input variable (expect for the first (fmt) argument). */
|
||||
#define Z_LOG_LOCAL_ARG_CREATE(idx, arg) \
|
||||
COND_CODE_0(idx, (), (auto Z_LOG_LOCAL_ARG_NAME(idx, arg) = (arg) + 0))
|
||||
#else
|
||||
#define Z_LOG_LOCAL_ARG_CREATE(idx, arg) \
|
||||
COND_CODE_0(idx, (), (__auto_type Z_LOG_LOCAL_ARG_NAME(idx, arg) = (arg) + 0))
|
||||
#endif
|
||||
COND_CODE_0(idx, (), (Z_AUTO_TYPE Z_LOG_LOCAL_ARG_NAME(idx, arg) = (arg) + 0))
|
||||
|
||||
/* First level of processing creates stack variables to be passed for further processing.
|
||||
* This is done to prevent multiple evaluations of input arguments (in case argument
|
||||
* evaluation has consequences, e.g. it is a function call).
|
||||
* evaluation has side effects, e.g. it is a non-pure function call).
|
||||
*/
|
||||
#define Z_LOG_MSG2_CREATE(_try_0cpy, _mode, _domain_id, _source, _level, _data, _dlen, ...) \
|
||||
#define Z_LOG_MSG2_CREATE2(_try_0cpy, _mode, _cstr_cnt, _domain_id, _source, \
|
||||
_level, _data, _dlen, ...) \
|
||||
do { \
|
||||
_Pragma("GCC diagnostic push") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wpointer-arith\"") \
|
||||
FOR_EACH_IDX(Z_LOG_LOCAL_ARG_CREATE, (;), __VA_ARGS__); \
|
||||
_Pragma("GCC diagnostic pop") \
|
||||
Z_LOG_MSG2_CREATE2(_try_0cpy, _mode, _domain_id, _source,\
|
||||
Z_LOG_MSG2_CREATE3(_try_0cpy, _mode, _cstr_cnt, _domain_id, _source,\
|
||||
_level, _data, _dlen, \
|
||||
FOR_EACH_IDX(Z_LOG_LOCAL_ARG_NAME, (,), __VA_ARGS__)); \
|
||||
} while (0)
|
||||
#endif /* CONFIG_LOG2_ALWAYS_RUNTIME */
|
||||
|
||||
|
||||
#define Z_LOG_MSG2_CREATE(_try_0cpy, _mode, _domain_id, _source,\
|
||||
_level, _data, _dlen, ...) \
|
||||
Z_LOG_MSG2_CREATE2(_try_0cpy, _mode, UTIL_CAT(Z_LOG_FUNC_PREFIX_, _level), \
|
||||
_domain_id, _source, _level, _data, _dlen, \
|
||||
Z_LOG_STR(_level, __VA_ARGS__))
|
||||
|
||||
/** @brief Allocate log message.
|
||||
*
|
||||
|
||||
@@ -15,6 +15,24 @@ if(NOT CONFIG_LOG_MODE_MINIMAL)
|
||||
log_msg2.c
|
||||
)
|
||||
|
||||
# Determine if __auto_type is supported. If not then runtime approach must always
|
||||
# be used.
|
||||
# Supported by:
|
||||
# - C++ (auto)
|
||||
# - GCC 4.9.0 https://gcc.gnu.org/gcc-4.9/changes.html
|
||||
# - Clang 3.8
|
||||
if (NOT CONFIG_LOG2_ALWAYS_RUNTIME)
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||
if(CMAKE_C_COMPILER_VERSION VERSION_LESS "3.8.0")
|
||||
message(WARNING "Compiler version requires CONFIG_LOG2_ALWAYS_RUNTIME to be set")
|
||||
endif()
|
||||
endif()
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||
if(CMAKE_C_COMPILER_VERSION VERSION_LESS "4.9.0")
|
||||
message(WARNING "Compiler version requires CONFIG_LOG2_ALWAYS_RUNTIME to be set")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
zephyr_sources_ifdef(
|
||||
CONFIG_LOG_BACKEND_UART
|
||||
|
||||
Reference in New Issue
Block a user