From: Willy Tarreau Date: Tue, 11 Aug 2026 09:21:50 +0000 (+0200) Subject: MEDIUM: debug: add a new version of complain() that takes a debug_count struct X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1f374058be842b7d3464c224b8975626d0cfcb7b;p=thirdparty%2Fhaproxy.git MEDIUM: debug: add a new version of complain() that takes a debug_count struct complain_with_dbg() takes a debug_count struct in argument from which it retrieves everything it needs: - details - type - file name - line number - description - vaargs This is done by making the common _complain() able to decode such elements from a debug_count when presented. complain() passes a NULL there and uses its msg, while complain_with_dbg() passes the debug_count and no msg. This allows us to get rid of all the pre-made redundant messages and to save 70 kB of code. We're now around 136 kB under the initial size. --- diff --git a/include/haproxy/bug.h b/include/haproxy/bug.h index 93040ab2f..69018d37f 100644 --- a/include/haproxy/bug.h +++ b/include/haproxy/bug.h @@ -169,6 +169,7 @@ struct debug_count { /* report a bug on stderr */ void complain(uint details, const char *msg); +void complain_with_dbg(struct debug_count *dbg); void ha_backtrace_to_stderr(int hint); /* Let's make DEBUG_STRESS equal to zero if not set or not valid, or to @@ -364,11 +365,7 @@ 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) { \ - const char *msg = \ - (sizeof("" __VA_ARGS__) > 1) ? \ - "\"" #_cond "\" matched at " _file ":" #_line "\x1e" __VA_ARGS__ : \ - "\"" #_cond "\" matched at " _file ":" #_line; \ - complain(_details, msg); \ + complain_with_dbg(&__dbg_cnt_##_line); \ if (_details & DBG_DET_FAT_FATL) \ ABORT_NOW(); \ else if (_details & DBG_DET_FAT_WARN) \ diff --git a/src/debug.c b/src/debug.c index 56da25d29..47546ba5f 100644 --- a/src/debug.c +++ b/src/debug.c @@ -971,11 +971,13 @@ void ha_stuck_warning(void) * in some taining of the process to happen. If the string contains an RS char * (\x1e) then it's used as a delimiter: the main message stops there, and what * follows is a new line that will be appended after another LF (normally it's - * used to give extra info to the user about the issue's location). + * used to give extra info to the user about the issue's location). When + * is non-null, it is used as a source for the message, file, line number, type + * etc. */ -static void _complain(uint details, const char *msg) +static void _complain(uint details, const char *msg, struct debug_count *dbg) { - struct iovec iovec[10]; + struct iovec iovec[20]; const char *pfx; const char *rs; int vec = 0; @@ -1012,14 +1014,49 @@ static void _complain(uint details, const char *msg) vec++; } - /* make rs point either to the RS or to \0 */ - rs = strchr(msg, '\x1e'); - if (!rs) - rs = msg + strlen(msg); + if (dbg) { + /* Using only . is ignored and may be NULL. + * Make rs point either to the RS or to \0. + * Output format: \" \" " matched at " ":" + * (7 fields). + */ + rs = strchr(dbg->desc, '\x1e'); + if (!rs) + rs = dbg->desc + strlen(dbg->desc); - iovec[vec].iov_base = (char *)msg; - iovec[vec].iov_len = rs - msg; - vec++; + iovec[vec].iov_base = "\""; + iovec[vec].iov_len = 1; + vec++; + + iovec[vec].iov_base = (char *)dbg->desc; + iovec[vec].iov_len = rs - dbg->desc; + vec++; + + iovec[vec].iov_base = "\" matched at "; + iovec[vec].iov_len = strlen(iovec[vec].iov_base); + vec++; + + iovec[vec].iov_base = (char *)dbg->file; + iovec[vec].iov_len = strlen(iovec[vec].iov_base); + vec++; + + iovec[vec].iov_base = ":"; + iovec[vec].iov_len = 1; + vec++; + + iovec[vec].iov_base = (char *)ultoa(dbg->line); + iovec[vec].iov_len = strlen(iovec[vec].iov_base); + vec++; + } else { + /* Using the field. Make rs point either to the RS or to \0 */ + rs = strchr(msg, '\x1e'); + if (!rs) + rs = msg + strlen(msg); + + iovec[vec].iov_base = (char *)msg; + iovec[vec].iov_len = rs - msg; + vec++; + } /* suffixes may be printed for warning-level */ if (details & DBG_DET_FAT_WARN) { @@ -1059,7 +1096,13 @@ static void _complain(uint details, const char *msg) /* the exported function */ void complain(uint details, const char *msg) { - _complain(details, msg); + _complain(details, msg, NULL); +} + +/* the same, for use with a debug_count struct */ +void complain_with_dbg(struct debug_count *dbg) +{ + _complain(dbg->details, NULL, dbg); } /* parse a "debug dev exit" command. It always returns 1, though it should never return. */