]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: debug: unify __BUG_ON() and __BUG_ON_ONCE()
authorWilly Tarreau <w@1wt.eu>
Mon, 10 Aug 2026 18:07:01 +0000 (20:07 +0200)
committerWilly Tarreau <w@1wt.eu>
Thu, 13 Aug 2026 15:43:30 +0000 (17:43 +0200)
We can do that thanks to the debug type. The line counter moved into an
if () block conditioned by the type so it continues to emit nothing for
regular bugs.

Surprizingly, the code grew by 1 kB. It's apparently caused by having
an impossible "if" statement containing a "break". Splitting the macro
in two to put the BUG_ON_ONCE() callers aside showed that having only
"if (0) break;" in the block was sufficient to make gcc deoptimize it
and result in this same growth. This was observed with 9.5. Let's
consider this a temporary limitation and keep it this way.

include/haproxy/bug.h

index dcfeea58b3b6864095dd4a8371fb0b1980349607..efabaab5f6769b9a33af05b8a0e49b12f5e3a6cf 100644 (file)
@@ -409,12 +409,18 @@ extern __attribute__((__weak__)) struct debug_count __stop_dbg_cnt  HA_SECTION_S
                1; /* let's return the true condition */                        \
        }) : 0)
 
+/* This is called by _BUG_ON() and _BUG_ON_ONCE() to handle the event. */
 #define __BUG_ON(cond, file, line, type, details, ...) do {            \
                const char *msg;                                        \
                if (sizeof("" __VA_ARGS__) > 1)                         \
                        msg = "\"" #cond "\" matched at " file ":" #line "\x1e" __VA_ARGS__; \
                else                                                    \
                        msg = "\"" #cond "\" matched at " file ":" #line; \
+               if (type == DBG_BUG_ONCE) {                             \
+                       static int __match_count_##line;                \
+                       if (_HA_ATOMIC_FETCH_ADD(&__match_count_##line, 1)) \
+                               break;                                  \
+               }                                                       \
                complain(details, msg);                                 \
                if (details & DBG_DET_FAT_FATL)                         \
                        ABORT_NOW();                                    \
@@ -430,27 +436,10 @@ extern __attribute__((__weak__)) struct debug_count __stop_dbg_cnt  HA_SECTION_S
 #define _BUG_ON_ONCE(cond, file, line, details, ...)                           \
        (void)(unlikely(cond) ? ({                                              \
                __DBG_COUNT(cond, file, line, DBG_BUG_ONCE, __VA_ARGS__);       \
-               __BUG_ON_ONCE(cond, file, line, DBG_BUG_ONCE, details, __VA_ARGS__); \
+               __BUG_ON(cond, file, line, DBG_BUG_ONCE, details, __VA_ARGS__); \
                1; /* let's return the true condition */                        \
        }) : 0)
 
-#define __BUG_ON_ONCE(cond, file, line, type, details, ...) do {       \
-               static int __match_count_##line;                        \
-               const char *msg;                                        \
-               if (sizeof("" __VA_ARGS__) > 1)                         \
-                       msg = "\"" #cond "\" matched at " file ":" #line "\x1e" __VA_ARGS__; \
-               else                                                    \
-                       msg = "\"" #cond "\" matched at " file ":" #line; \
-               if (_HA_ATOMIC_FETCH_ADD(&__match_count_##line, 1))     \
-                       break;                                          \
-               complain(details, msg);                                 \
-               if (details & DBG_DET_FAT_FATL)                         \
-                       ABORT_NOW();                                    \
-               else if (details & DBG_DET_FAT_WARN)                    \
-                       ha_backtrace_to_stderr(0);                      \
-       } while (0)
-
-
 /* DEBUG_STRICT enables/disables runtime checks on condition <cond>
  * DEBUG_STRICT_ACTION indicates the level of verification on the rules when
  * <cond> is true: