From bb8da4303851642318b626aad507ab7c39f6a80d Mon Sep 17 00:00:00 2001 From: Alexey Tikhonov Date: Mon, 1 Nov 2021 20:09:02 +0100 Subject: [PATCH] DEBUG: avoid backtrace dups. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In case the same error(s) is repeated again and again repeating the same backtrace doesn't add much value. In this case let's add just a note. Reviewed-by: Tomáš Halman --- src/util/debug.c | 4 +-- src/util/debug_backtrace.c | 51 +++++++++++++++++++++++++++++++++++--- 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/src/util/debug.c b/src/util/debug.c index 7c03fb7df..953123718 100644 --- a/src/util/debug.c +++ b/src/util/debug.c @@ -42,7 +42,7 @@ void sss_debug_backtrace_init(void); void sss_debug_backtrace_vprintf(int level, const char *format, va_list ap); void sss_debug_backtrace_printf(int level, const char *format, ...); -void sss_debug_backtrace_endmsg(int level); +void sss_debug_backtrace_endmsg(const char *file, long line, int level); const char *debug_prg_name = "sssd"; @@ -359,7 +359,7 @@ void sss_vdebug_fn(const char *file, if (flags & APPEND_LINE_FEED) { sss_debug_backtrace_printf(level, "\n"); } - sss_debug_backtrace_endmsg(level); + sss_debug_backtrace_endmsg(file, line, level); } void sss_debug_fn(const char *file, diff --git a/src/util/debug_backtrace.c b/src/util/debug_backtrace.c index d99325ab6..e376f815b 100644 --- a/src/util/debug_backtrace.c +++ b/src/util/debug_backtrace.c @@ -30,6 +30,9 @@ extern FILE *_sss_debug_file; static const unsigned SSS_DEBUG_BACKTRACE_DEFAULT_SIZE = 100*1024; /* bytes */ static const unsigned SSS_DEBUG_BACKTRACE_LEVEL = SSSDBG_BE_FO; +/* Size of locations history to keep to avoid duplicating backtraces */ +#define SSS_DEBUG_BACKTRACE_LOCATIONS 5 + /* --> * ring buffer = [*******t...\n............e000] @@ -46,12 +49,21 @@ static struct { char *buffer; /* buffer start */ char *end; /* end data border */ char *tail; /* tail of "current" message */ + + /* locations where last backtraces happened */ + struct { + const char *file; + long line; + } locations[SSS_DEBUG_BACKTRACE_LOCATIONS]; + unsigned last_location_idx; } _bt; static inline bool _all_levels_enabled(void); static inline bool _backtrace_is_enabled(int level); static inline bool _is_trigger_level(int level); +static void _store_location(const char *file, long line); +static bool _is_recent_location(const char *file, long line); static void _backtrace_vprintf(const char *format, va_list ap); static void _backtrace_printf(const char *format, ...); static void _backtrace_dump(void); @@ -75,6 +87,8 @@ void sss_debug_backtrace_init(void) _bt.enabled = true; _bt.initialized = true; + /* locations[] & last_location_idx are zero-initialized */ + _backtrace_printf(" * "); } @@ -116,7 +130,7 @@ void sss_debug_backtrace_printf(int level, const char *format, ...) } -void sss_debug_backtrace_endmsg(int level) +void sss_debug_backtrace_endmsg(const char *file, long line, int level) { if (DEBUG_IS_SET(level)) { _debug_fflush(); @@ -124,7 +138,16 @@ void sss_debug_backtrace_endmsg(int level) if (_backtrace_is_enabled(level)) { if (_is_trigger_level(level)) { - _backtrace_dump(); + if (!_is_recent_location(file, line)) { + _backtrace_dump(); + _store_location(file, line); + } else { + fprintf(_sss_debug_file ? _sss_debug_file : stderr, + " * ... skipping repetitive backtrace ...\n"); + /* and reset */ + _bt.end = _bt.buffer; + _bt.tail = _bt.buffer; + } } _backtrace_printf(" * "); } @@ -191,7 +214,29 @@ static inline bool _backtrace_is_enabled(int level) } - /* prints to buffer */ +static void _store_location(const char *file, long line) +{ + _bt.last_location_idx = (_bt.last_location_idx + 1) % SSS_DEBUG_BACKTRACE_LOCATIONS; + /* __FILE__ is a character string literal with static storage duration. */ + _bt.locations[_bt.last_location_idx].file = file; + _bt.locations[_bt.last_location_idx].line = line; +} + + +static bool _is_recent_location(const char *file, long line) +{ + for (unsigned idx = 0; idx < SSS_DEBUG_BACKTRACE_LOCATIONS; ++idx) { + if ((line == _bt.locations[idx].line) && + (_bt.locations[idx].file != NULL) && + (strcmp(file, _bt.locations[idx].file) == 0)) { + return true; + } + } + return false; +} + + +/* prints to buffer */ static void _backtrace_vprintf(const char *format, va_list ap) { int buff_tail_size = _bt.size - (_bt.tail - _bt.buffer); -- 2.26.3