]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: debug: make the complain() function print the prefix
authorWilly Tarreau <w@1wt.eu>
Mon, 10 Aug 2026 15:49:39 +0000 (17:49 +0200)
committerWilly Tarreau <w@1wt.eu>
Thu, 13 Aug 2026 15:43:30 +0000 (17:43 +0200)
The prefix ("ABORT at", "FATAL:", "WARNING:") as well as the second level
("bug condition", ...) are entirely determined by the details bit field,
so there is no reason to have to build this string in the caller, instead
we can let complain() build it entirely from the details into the local
iovec, so let's do that.

The prefix is now dropped from the whole call chain as it's no longer
useful. This further reduces the code size by 17.5 kB.

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

index 20e9ae7586399c615209b41653ec7093c7a7aed1..7e11ed2c71da6bf338a5300cbc0a5a70c3904116 100644 (file)
@@ -301,7 +301,7 @@ 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, "ABORT at " file ":" #line ": " __VA_ARGS__); \
+                       complain(DBG_FATL_ABT, file ":" #line ": " __VA_ARGS__); \
                ha_backtrace_to_stderr(1);                              \
                abort_with_line(__LINE__);                              \
        } while (0)
@@ -392,28 +392,28 @@ extern __attribute__((__weak__)) struct debug_count __stop_dbg_cnt  HA_SECTION_S
 #define COUNT_GLITCH(...) _COUNT_GLITCH(__FILE__, __LINE__, __VA_ARGS__)
 
 /* This is the generic low-level macro dealing with conditional warnings and
- * bugs. The caller decides whether to crash or not and what prefix and suffix
- * to pass. The macro returns the boolean value of the condition as an int for
- * the case where it wouldn't die. The <details> flag is made of:
+ * bugs. The caller decides whether to crash or not and what suffix to pass.
+ * The macro returns the boolean value of the condition as an int for the case
+ * where it wouldn't die. The <details> flag is made of:
  *  - details & DBG_DET_FAT_FATL: crash yes/no;
  *  - details & DBG_DET_TYP_BUG: taint as bug instead of warn
  * The optional argument must be a single constant string that will be appended
  * on a second line after the condition message, to give a bit more context
  * about the problem.
  */
-#define _BUG_ON(cond, file, line, details, pfx, sfx, ...)                      \
+#define _BUG_ON(cond, file, line, details, sfx, ...)                           \
        (void)(unlikely(cond) ? ({                                              \
                __DBG_COUNT(cond, file, line, DBG_BUG, __VA_ARGS__);            \
-               __BUG_ON(cond, file, line, details, pfx, sfx, __VA_ARGS__);     \
+               __BUG_ON(cond, file, line, details, sfx, __VA_ARGS__);          \
                1; /* let's return the true condition */                        \
        }) : 0)
 
-#define __BUG_ON(cond, file, line, details, pfx, sfx, ...) do {                \
+#define __BUG_ON(cond, file, line, details, sfx, ...) do {             \
                const char *msg;                                        \
                if (sizeof("" __VA_ARGS__) > 1)                         \
-                       msg = pfx "condition \"" #cond "\" matched at " file ":" #line "" sfx "\n" __VA_ARGS__; \
+                       msg = "\"" #cond "\" matched at " file ":" #line "" sfx "\n" __VA_ARGS__; \
                else                                                    \
-                       msg = pfx "condition \"" #cond "\" matched at " file ":" #line "" sfx; \
+                       msg = "\"" #cond "\" matched at " file ":" #line "" sfx; \
                complain(details, msg);                                 \
                if (details & DBG_DET_FAT_FATL)                         \
                        ABORT_NOW();                                    \
@@ -426,20 +426,20 @@ extern __attribute__((__weak__)) struct debug_count __stop_dbg_cnt  HA_SECTION_S
  * certain unexpected conditions in field. Later on, in cores it will be
  * possible to verify these counters.
  */
-#define _BUG_ON_ONCE(cond, file, line, details, pfx, sfx, ...)                 \
+#define _BUG_ON_ONCE(cond, file, line, details, sfx, ...)                      \
        (void)(unlikely(cond) ? ({                                              \
                __DBG_COUNT(cond, file, line, DBG_BUG_ONCE, __VA_ARGS__);       \
-               __BUG_ON_ONCE(cond, file, line, details, pfx, sfx, __VA_ARGS__);\
+               __BUG_ON_ONCE(cond, file, line, details, sfx, __VA_ARGS__);     \
                1; /* let's return the true condition */                        \
        }) : 0)
 
-#define __BUG_ON_ONCE(cond, file, line, details, pfx, sfx, ...) do {   \
+#define __BUG_ON_ONCE(cond, file, line, details, sfx, ...) do {                \
                static int __match_count_##line;                        \
                const char *msg;                                        \
                if (sizeof("" __VA_ARGS__) > 1)                         \
-                       msg = pfx "condition \"" #cond "\" matched at " file ":" #line "" sfx "\n" __VA_ARGS__; \
+                       msg = "\"" #cond "\" matched at " file ":" #line "" sfx "\n" __VA_ARGS__; \
                else                                                    \
-                       msg = pfx "condition \"" #cond "\" matched at " file ":" #line "" sfx; \
+                       msg = "\"" #cond "\" matched at " file ":" #line "" sfx; \
                if (_HA_ATOMIC_FETCH_ADD(&__match_count_##line, 1))     \
                        break;                                          \
                complain(details, msg);                                 \
@@ -465,27 +465,27 @@ extern __attribute__((__weak__)) struct debug_count __stop_dbg_cnt  HA_SECTION_S
 #if defined(DEBUG_STRICT) && (DEBUG_STRICT > 0)
 # if defined(DEBUG_STRICT_ACTION) && (DEBUG_STRICT_ACTION < 1)
 /* Lowest level: BUG_ON() warns, WARN_ON() warns, CHECK_IF() warns */
-#  define BUG_ON(cond, ...)   _BUG_ON     (cond, __FILE__, __LINE__, DBG_WARN_BUG, "WARNING: bug ",   " (not crashing but process is untrusted now, please report to developers)", __VA_ARGS__)
-#  define WARN_ON(cond, ...)  _BUG_ON     (cond, __FILE__, __LINE__, DBG_WARN_WRN, "WARNING: warn ",  " (please report to developers)", __VA_ARGS__)
-#  define CHECK_IF(cond, ...) _BUG_ON_ONCE(cond, __FILE__, __LINE__, DBG_WARN_CHK, "WARNING: check ", " (please report to developers)", __VA_ARGS__)
+#  define BUG_ON(cond, ...)   _BUG_ON     (cond, __FILE__, __LINE__, DBG_WARN_BUG,   " (not crashing but process is untrusted now, please report to developers)", __VA_ARGS__)
+#  define WARN_ON(cond, ...)  _BUG_ON     (cond, __FILE__, __LINE__, DBG_WARN_WRN,  " (please report to developers)", __VA_ARGS__)
+#  define CHECK_IF(cond, ...) _BUG_ON_ONCE(cond, __FILE__, __LINE__, DBG_WARN_CHK, " (please report to developers)", __VA_ARGS__)
 #  define COUNT_IF(cond, ...) _COUNT_IF   (cond, __FILE__, __LINE__, __VA_ARGS__)
 # elif !defined(DEBUG_STRICT_ACTION) || (DEBUG_STRICT_ACTION == 1)
 /* default level: BUG_ON() crashes, WARN_ON() warns, CHECK_IF() warns */
-#  define BUG_ON(cond, ...)   _BUG_ON     (cond, __FILE__, __LINE__, DBG_FATL_BUG, "FATAL: bug ",     "", __VA_ARGS__)
-#  define WARN_ON(cond, ...)  _BUG_ON     (cond, __FILE__, __LINE__, DBG_WARN_WRN, "WARNING: warn ",  " (please report to developers)", __VA_ARGS__)
-#  define CHECK_IF(cond, ...) _BUG_ON_ONCE(cond, __FILE__, __LINE__, DBG_WARN_CHK, "WARNING: check ", " (please report to developers)", __VA_ARGS__)
+#  define BUG_ON(cond, ...)   _BUG_ON     (cond, __FILE__, __LINE__, DBG_FATL_BUG,     "", __VA_ARGS__)
+#  define WARN_ON(cond, ...)  _BUG_ON     (cond, __FILE__, __LINE__, DBG_WARN_WRN,  " (please report to developers)", __VA_ARGS__)
+#  define CHECK_IF(cond, ...) _BUG_ON_ONCE(cond, __FILE__, __LINE__, DBG_WARN_CHK, " (please report to developers)", __VA_ARGS__)
 #  define COUNT_IF(cond, ...) _COUNT_IF   (cond, __FILE__, __LINE__, __VA_ARGS__)
 # elif defined(DEBUG_STRICT_ACTION) && (DEBUG_STRICT_ACTION == 2)
 /* Stricter level: BUG_ON() crashes, WARN_ON() crashes, CHECK_IF() warns */
-#  define BUG_ON(cond, ...)   _BUG_ON     (cond, __FILE__, __LINE__, DBG_FATL_BUG, "FATAL: bug ",     "", __VA_ARGS__)
-#  define WARN_ON(cond, ...)  _BUG_ON     (cond, __FILE__, __LINE__, DBG_FATL_WRN, "FATAL: warn ",    "", __VA_ARGS__)
-#  define CHECK_IF(cond, ...) _BUG_ON_ONCE(cond, __FILE__, __LINE__, DBG_WARN_CHK, "WARNING: check ", " (please report to developers)", __VA_ARGS__)
+#  define BUG_ON(cond, ...)   _BUG_ON     (cond, __FILE__, __LINE__, DBG_FATL_BUG,     "", __VA_ARGS__)
+#  define WARN_ON(cond, ...)  _BUG_ON     (cond, __FILE__, __LINE__, DBG_FATL_WRN,    "", __VA_ARGS__)
+#  define CHECK_IF(cond, ...) _BUG_ON_ONCE(cond, __FILE__, __LINE__, DBG_WARN_CHK, " (please report to developers)", __VA_ARGS__)
 #  define COUNT_IF(cond, ...) _COUNT_IF   (cond, __FILE__, __LINE__, __VA_ARGS__)
 # elif defined(DEBUG_STRICT_ACTION) && (DEBUG_STRICT_ACTION >= 3)
 /* Developer/CI level: BUG_ON() crashes, WARN_ON() crashes, CHECK_IF() crashes */
-#  define BUG_ON(cond, ...)   _BUG_ON     (cond, __FILE__, __LINE__, DBG_FATL_BUG, "FATAL: bug ",     "", __VA_ARGS__)
-#  define WARN_ON(cond, ...)  _BUG_ON     (cond, __FILE__, __LINE__, DBG_FATL_WRN, "FATAL: warn ",    "", __VA_ARGS__)
-#  define CHECK_IF(cond, ...) _BUG_ON_ONCE(cond, __FILE__, __LINE__, DBG_FATL_CHK, "FATAL: check ",   "", __VA_ARGS__)
+#  define BUG_ON(cond, ...)   _BUG_ON     (cond, __FILE__, __LINE__, DBG_FATL_BUG,     "", __VA_ARGS__)
+#  define WARN_ON(cond, ...)  _BUG_ON     (cond, __FILE__, __LINE__, DBG_FATL_WRN,    "", __VA_ARGS__)
+#  define CHECK_IF(cond, ...) _BUG_ON_ONCE(cond, __FILE__, __LINE__, DBG_FATL_CHK,   "", __VA_ARGS__)
 #  define COUNT_IF(cond, ...) _COUNT_IF   (cond, __FILE__, __LINE__, __VA_ARGS__)
 # endif
 #else /* DEBUG_STRICT not defined below */
@@ -508,18 +508,18 @@ extern __attribute__((__weak__)) struct debug_count __stop_dbg_cnt  HA_SECTION_S
 #if defined(DEBUG_STRICT) && (DEBUG_STRICT > 1)
 # if defined(DEBUG_STRICT_ACTION) && (DEBUG_STRICT_ACTION < 1)
 /* Lowest level: BUG_ON() warns, CHECK_IF() warns */
-#  define BUG_ON_HOT(cond, ...)   _BUG_ON_ONCE(cond, __FILE__, __LINE__, DBG_WARN_BUG, "WARNING: bug ",   " (not crashing but process is untrusted now, please report to developers)", __VA_ARGS__)
-#  define CHECK_IF_HOT(cond, ...) _BUG_ON_ONCE(cond, __FILE__, __LINE__, DBG_WARN_CHK, "WARNING: check ", " (please report to developers)", __VA_ARGS__)
+#  define BUG_ON_HOT(cond, ...)   _BUG_ON_ONCE(cond, __FILE__, __LINE__, DBG_WARN_BUG,   " (not crashing but process is untrusted now, please report to developers)", __VA_ARGS__)
+#  define CHECK_IF_HOT(cond, ...) _BUG_ON_ONCE(cond, __FILE__, __LINE__, DBG_WARN_CHK, " (please report to developers)", __VA_ARGS__)
 #  define COUNT_IF_HOT(cond, ...) _COUNT_IF   (cond, __FILE__, __LINE__, __VA_ARGS__)
 # elif !defined(DEBUG_STRICT_ACTION) || (DEBUG_STRICT_ACTION < 3)
 /* default level: BUG_ON() crashes, CHECK_IF() warns */
-#  define BUG_ON_HOT(cond, ...)   _BUG_ON     (cond, __FILE__, __LINE__, DBG_FATL_BUG, "FATAL: bug ",     "", __VA_ARGS__)
-#  define CHECK_IF_HOT(cond, ...) _BUG_ON_ONCE(cond, __FILE__, __LINE__, DBG_WARN_CHK, "WARNING: check ", " (please report to developers)", __VA_ARGS__)
+#  define BUG_ON_HOT(cond, ...)   _BUG_ON     (cond, __FILE__, __LINE__, DBG_FATL_BUG,     "", __VA_ARGS__)
+#  define CHECK_IF_HOT(cond, ...) _BUG_ON_ONCE(cond, __FILE__, __LINE__, DBG_WARN_CHK, " (please report to developers)", __VA_ARGS__)
 #  define COUNT_IF_HOT(cond, ...) _COUNT_IF   (cond, __FILE__, __LINE__, __VA_ARGS__)
 # elif defined(DEBUG_STRICT_ACTION) && (DEBUG_STRICT_ACTION >= 3)
 /* Developer/CI level: BUG_ON() crashes, CHECK_IF() crashes */
-#  define BUG_ON_HOT(cond, ...)   _BUG_ON     (cond, __FILE__, __LINE__, DBG_FATL_BUG, "FATAL: bug ",     "", __VA_ARGS__)
-#  define CHECK_IF_HOT(cond, ...) _BUG_ON_ONCE(cond, __FILE__, __LINE__, DBG_FATL_CHK, "FATAL: check ",   "", __VA_ARGS__)
+#  define BUG_ON_HOT(cond, ...)   _BUG_ON     (cond, __FILE__, __LINE__, DBG_FATL_BUG,     "", __VA_ARGS__)
+#  define CHECK_IF_HOT(cond, ...) _BUG_ON_ONCE(cond, __FILE__, __LINE__, DBG_FATL_CHK,   "", __VA_ARGS__)
 #  define COUNT_IF_HOT(cond, ...) _COUNT_IF   (cond, __FILE__, __LINE__, __VA_ARGS__)
 # endif
 #else /* DEBUG_STRICT <= 1 below */
index 42f65af6ef29211dbd63736cba1be2bc7c8997c8..8484d0f367e53b600b54401dee1d0eee8488b835 100644 (file)
@@ -973,12 +973,41 @@ void ha_stuck_warning(void)
 void complain(uint details, const char *msg)
 {
        struct iovec iovec[10];
+       const char *pfx;
        int vec = 0;
 
        iovec[vec].iov_base = "\n";
        iovec[vec].iov_len  = 1;
        vec++;
 
+       pfx = NULL;
+       if (details & DBG_DET_TYP_ABT)
+               pfx = "ABORT at ";
+       else if (details & DBG_DET_FAT_FATL)
+               pfx = "FATAL: ";
+       else if (details & DBG_DET_FAT_WARN)
+               pfx = "WARNING: ";
+
+       if (pfx) {
+               iovec[vec].iov_base = (char *)pfx;
+               iovec[vec].iov_len  = strlen(pfx);
+               vec++;
+       }
+
+       pfx = NULL;
+       if (details & DBG_DET_TYP_BUG)
+               pfx = "bug condition ";
+       else if (details & DBG_DET_TYP_WRN)
+               pfx = "warn condition ";
+       else if (details & DBG_DET_TYP_CHK)
+               pfx = "check condition ";
+
+       if (pfx) {
+               iovec[vec].iov_base = (char *)pfx;
+               iovec[vec].iov_len  = strlen(pfx);
+               vec++;
+       }
+
        iovec[vec].iov_base = (char *)msg;
        iovec[vec].iov_len  = strlen(msg);
        vec++;