From c57da9a09debeaf7d6447e45d7b6ef8379521d21 Mon Sep 17 00:00:00 2001 From: DoctorRFer <224315159+DoctorRFer@users.noreply.github.com> Date: Fri, 25 Sep 2026 11:09:19 +0000 Subject: [PATCH] fix(logging): don't route USE_SEGGER LOG_* through SEGGER_RTT_printf (#11970) SEGGER_RTT_printf() only supports %c %d %u %x %X %s %p. A %f is skipped without consuming its double from the va_list, so a later %s reads part of that double as a pointer and HardFaults. On CanaryOne (USE_SEGGER defined in variant.h) this resets the device on every packet retransmission, via PacketHistory's "Reusing slot aged %.3fs TRACE %s" log line. It also means CanaryOne emits no logs over USB or the API, only over RTT. RedirectablePrint::write() already mirrors every character to RTT when USE_SEGGER is set, so drop the SEGGER-specific LOG_* macros and use the normal logging path: full printf support, the existing log semaphore, and RTT output preserved. Tested on CanaryOne (v2.7.26.54e0d8d + this change, USE_SEGGER still enabled): unacknowledged want_ack sends now retransmit twice and NAK (err=5) without a reset, and logs reach USB/API again. --- src/DebugConfiguration.h | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/src/DebugConfiguration.h b/src/DebugConfiguration.h index d155b1dfb5..99add71ab9 100644 --- a/src/DebugConfiguration.h +++ b/src/DebugConfiguration.h @@ -58,19 +58,11 @@ extern MemGet memGet; #endif #endif -#ifdef USE_SEGGER -// #undef DEBUG_PORT -#define LOG_DEBUG(...) SEGGER_RTT_printf(0, __VA_ARGS__) -#define LOG_INFO(...) SEGGER_RTT_printf(0, __VA_ARGS__) -#define LOG_WARN(...) SEGGER_RTT_printf(0, __VA_ARGS__) -#define LOG_ERROR(...) SEGGER_RTT_printf(0, __VA_ARGS__) -#define LOG_CRIT(...) SEGGER_RTT_printf(0, __VA_ARGS__) -#if MESHTASTIC_TRACE_LOGGING -#define LOG_TRACE(...) SEGGER_RTT_printf(0, __VA_ARGS__) -#else -#define LOG_TRACE(...) -#endif -#else +// USE_SEGGER no longer maps LOG_* to SEGGER_RTT_printf(): it has no float +// support, and a skipped %f leaves its argument on the va_list, so a later %s +// dereferences garbage and HardFaults (e.g. PacketHistory's +// "Reusing slot aged %.3fs TRACE %s"). RedirectablePrint::write() already +// mirrors every log character to RTT when USE_SEGGER is set. #if defined(DEBUG_PORT) && !defined(DEBUG_MUTE) #define LOG_DEBUG(...) DEBUG_PORT.log(MESHTASTIC_LOG_LEVEL_DEBUG, __VA_ARGS__) #define LOG_INFO(...) DEBUG_PORT.log(MESHTASTIC_LOG_LEVEL_INFO, __VA_ARGS__) @@ -90,7 +82,6 @@ extern MemGet memGet; #define LOG_CRIT(...) #define LOG_TRACE(...) #endif -#endif #if defined(DEBUG_HEAP) #define LOG_HEAP(...) DEBUG_PORT.log(MESHTASTIC_LOG_LEVEL_HEAP, __VA_ARGS__)