From: Willy Tarreau Date: Mon, 10 Aug 2026 15:49:39 +0000 (+0200) Subject: MEDIUM: debug: make the complain() function print the prefix X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=28a09c38ffb154d057ce11b062d220c05ca9b052;p=thirdparty%2Fhaproxy.git MEDIUM: debug: make the complain() function print the prefix 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. --- diff --git a/include/haproxy/bug.h b/include/haproxy/bug.h index 20e9ae758..7e11ed2c7 100644 --- a/include/haproxy/bug.h +++ b/include/haproxy/bug.h @@ -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
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
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 */ diff --git a/src/debug.c b/src/debug.c index 42f65af6e..8484d0f36 100644 --- a/src/debug.c +++ b/src/debug.c @@ -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++;