]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: debug: merge the counter and message emission into complain()
authorWilly Tarreau <w@1wt.eu>
Tue, 11 Aug 2026 11:43:46 +0000 (13:43 +0200)
committerWilly Tarreau <w@1wt.eu>
Thu, 13 Aug 2026 15:43:30 +0000 (17:43 +0200)
The event counter in debug mode moved to complain_with_dbg(). This
ensures that the deferencing of the counter, the atomic ops, the
condition to skip the emission are all centralized and are no longer
inline in the BUG_ON() location.

The trace emission that was now systematic after calls to complain*()
now moved to the shared _complain(), where it is emitted based on the
elements present in the details passed to the function (fatal/warning).

This saves another 56kB, so we're at -193kB compared to initial work.
The total preprocessor output is now ~7% smaller in bytes than initial
work, and ~10% in words, and builds ~7% faster (7.05s vs 7.55s before
on a 64-core EPYC). The part of the reasonable cleanup is now done.

However the complain_with_dbg function now appears in the caller's
stack as tail jumps are not always done, but we have plans for this.

include/haproxy/bug.h
src/debug.c

index f78dadcf4899d889d59b8c35c2c597e3a143679b..cd429232550402fb8a73ec74f7dd340f80e5da61 100644 (file)
@@ -303,8 +303,6 @@ static __attribute__((noinline,noreturn,unused)) void abort_with_line(uint line)
 #define __ABORT_NOW(file, line, ...) do {                              \
                if (sizeof("" __VA_ARGS__) > 1)                         \
                        complain(DBG_FATL_ABT, file ":" #line ": " __VA_ARGS__); \
-               if (sizeof("" __VA_ARGS__) > 1)                         \
-                       ha_backtrace_to_stderr(1);                      \
                abort_with_line(__LINE__);                              \
        } while (0)
 
@@ -365,13 +363,9 @@ extern __attribute__((__weak__)) struct debug_count __stop_dbg_cnt  HA_SECTION_S
                };                                                              \
                HA_WEAK(__start_dbg_cnt);                                       \
                HA_WEAK(__stop_dbg_cnt);                                        \
-               if (!_HA_ATOMIC_FETCH_ADD(&__dbg_cnt_##_line.count, 1) || _type != DBG_BUG_ONCE) { \
-                       complain_with_dbg(&__dbg_cnt_##_line);                  \
-                       if (_details & (DBG_DET_FAT_FATL|DBG_DET_FAT_WARN))     \
-                               ha_backtrace_to_stderr(!!(_details & DBG_DET_FAT_FATL)); \
-                       if (_details & DBG_DET_FAT_FATL)                        \
-                               abort_with_line(__LINE__);                      \
-               }                                                               \
+               complain_with_dbg(&__dbg_cnt_##_line);                          \
+               if (_details & DBG_DET_FAT_FATL)                                \
+                       abort_with_line(__LINE__);                              \
        }
 
 /* Matrix for DEBUG_COUNTERS:
@@ -427,8 +421,6 @@ extern __attribute__((__weak__)) struct debug_count __stop_dbg_cnt  HA_SECTION_S
                    ({ static int __match_count_##line;                 \
                       !_HA_ATOMIC_FETCH_ADD(&__match_count_##line, 1); })) { \
                        complain(details, msg);                         \
-                       if (details & (DBG_DET_FAT_FATL|DBG_DET_FAT_WARN)) \
-                               ha_backtrace_to_stderr(!!(details & DBG_DET_FAT_FATL)); \
                        if (details & DBG_DET_FAT_FATL)                 \
                                abort_with_line(__LINE__);              \
                }                                                       \
index 47546ba5ffec3a0fc143c05bbbd55506cb395225..0b15465b2f0ef103821747baa78bd918bd2d930a 100644 (file)
@@ -1097,12 +1097,26 @@ static void _complain(uint details, const char *msg, struct debug_count *dbg)
 void complain(uint details, const char *msg)
 {
        _complain(details, msg, NULL);
+
+       /* we may have to emit a backtrace on FATL/WARN.
+        * This must be the last statement for a tail jump.
+        */
+       if (details & (DBG_DET_FAT_FATL|DBG_DET_FAT_WARN))
+               ha_backtrace_to_stderr(!!(details & DBG_DET_FAT_FATL));
 }
 
 /* the same, for use with a debug_count struct */
 void complain_with_dbg(struct debug_count *dbg)
 {
+       if (_HA_ATOMIC_FETCH_ADD(&dbg->count, 1) && dbg->type == DBG_BUG_ONCE)
+               return;
        _complain(dbg->details, NULL, dbg);
+
+       /* we may have to emit a backtrace on FATL/WARN.
+        * This must be the last statement for a tail jump.
+        */
+       if (dbg->details & (DBG_DET_FAT_FATL|DBG_DET_FAT_WARN))
+               ha_backtrace_to_stderr(!!(dbg->details & DBG_DET_FAT_FATL));
 }
 
 /* parse a "debug dev exit" command. It always returns 1, though it should never return. */