Blame SOURCES/0006-DEBUG-avoid-backtrace-dups.patch

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