From: Willy Tarreau Date: Tue, 11 Aug 2026 11:43:46 +0000 (+0200) Subject: MEDIUM: debug: merge the counter and message emission into complain() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=30c03d50f6b49999e69fc7daa868adf0e54b0c81;p=thirdparty%2Fhaproxy.git MEDIUM: debug: merge the counter and message emission into complain() 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. --- diff --git a/include/haproxy/bug.h b/include/haproxy/bug.h index f78dadcf4..cd4292325 100644 --- a/include/haproxy/bug.h +++ b/include/haproxy/bug.h @@ -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__); \ } \ diff --git a/src/debug.c b/src/debug.c index 47546ba5f..0b15465b2 100644 --- a/src/debug.c +++ b/src/debug.c @@ -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. */