]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: debug: use \x1e (RS) to delimit the condition from vaargs in DBG_COUNT()
authorWilly Tarreau <w@1wt.eu>
Mon, 10 Aug 2026 17:02:28 +0000 (19:02 +0200)
committerWilly Tarreau <w@1wt.eu>
Thu, 13 Aug 2026 15:43:30 +0000 (17:43 +0200)
The principle here is to reduce the reliance on multiple pointers in the
debug_count struct while still keeping a delimitation between records.
For this, we use the ASCII record separator character (\x1e or RS) that
is not present in the rest of our messages and has no reason to land there
by accident.

This slightly reduces the code size (2kB) but the purpose is to prepare
a next step where these definitions will benefit the BUG_ON*() macros.

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

index 7e11ed2c71da6bf338a5300cbc0a5a70c3904116..061e5bad92310b17f456fc09eaede82518f5d25d 100644 (file)
@@ -322,7 +322,8 @@ extern __attribute__((__weak__)) struct debug_count __stop_dbg_cnt  HA_SECTION_S
 /* This macro adds a pass counter at the line where it's declared. It can be
  * used by the various BUG_ON, COUNT_IF etc flavors. The condition is only
  * passed for the sake of being turned into a string; the caller is expected
- * to have already verified it.
+ * to have already verified it. The descripton and optional comments are
+ * delimited by \x1e (record separator).
  */
 #define __DBG_COUNT(_cond, _file, _line, _type, ...) do {                      \
                static struct debug_count __dbg_cnt_##_line HA_SECTION("dbg_cnt") \
@@ -333,8 +334,8 @@ extern __attribute__((__weak__)) struct debug_count __stop_dbg_cnt  HA_SECTION_S
                        .type = _type,                                          \
                        .desc = (sizeof("" #_cond) > 1) ?                       \
                                  (sizeof("" __VA_ARGS__) > 1) ?                \
-                                 "\"" #_cond "\" [" __VA_ARGS__ "]" :          \
-                                 "\"" #_cond "\"" :                            \
+                                 "" #_cond "\x1e" __VA_ARGS__ :                \
+                                 "" #_cond :                                   \
                                "" __VA_ARGS__,                                 \
                        .count = 0,                                             \
                };                                                              \
index 8484d0f367e53b600b54401dee1d0eee8488b835..a9cb9ed8ff02caa9db12993d54907b23b3f1242e 100644 (file)
@@ -2567,6 +2567,7 @@ static int debug_iohandler_counters(struct appctx *appctx)
        chunk_printf(&trash, "Count     Type Location function(): \"condition\" [comment]\n");
        for (ptr = ctx->start; ptr != ctx->stop; ptr++) {
                const char *p, *name;
+               const char *rs; /* record separator */
 
                if (ctx->types && !(ctx->types & (1 << ptr->type)))
                        continue;
@@ -2579,11 +2580,21 @@ static int debug_iohandler_counters(struct appctx *appctx)
                                name = p + 1;
                }
 
+               /* make rs point either to the RS or to \0 */
+               rs = strchr(ptr->desc, '\x1e');
+               if (!rs)
+                       rs = ptr->desc + strlen(ptr->desc);
+
                if (ptr->type < DBG_COUNTER_TYPES)
-                       chunk_appendf(&trash, "%-10u %3s %s:%d %s()%s%s%s\n",
+                       chunk_appendf(&trash,
+                                     "%-10u %3s %s:%d %s()" // cnt, type, name, line, func
+                                     "%s%.*s%s%s%s%s%s\n", // \" <desc> \", ...
                                      ptr->count, bug_type[ptr->type],
                                      name, ptr->line, ptr->func,
-                                     *ptr->desc ? ": " : "", ptr->desc,
+                                     *ptr->desc ? ": \"" : "",
+                                     (uint)(rs - ptr->desc), ptr->desc, /* .*s: first part */
+                                     *ptr->desc ? "\"" : "",
+                                     *rs ? " [" : "", *rs ? rs + 1 : "", *rs ? "]" : "", /* opt comment */
                                      (ptr->type == DBG_COUNT_IF && !debug_enable_counters) ? " (stopped)" : "");
 
                if (applet_putchk(appctx, &trash) == -1) {
@@ -2708,6 +2719,12 @@ static int init_debug()
                for (ptr = &__start_dbg_cnt; ptr < &__stop_dbg_cnt; ptr++) {
                        for (p = ptr->desc; *p; p++) {
                                if (*p < 0x20 || *p >= 0x7f) {
+                                       /* \x1E (record separator) is used as the delimiter between
+                                        * description and comments. It may only appear once and may
+                                        * not appear at the end of the string.
+                                        */
+                                       if (*p == '\x1e' && *(p + 1) && !strchr(p + 1, '\x1e'))
+                                               continue;
                                        ha_warning("Invalid character 0x%02x at position %d in description string at %s:%d %s()\n",
                                                   (uchar)*p, (int)(p - ptr->desc), ptr->file, ptr->line, ptr->func);
                                        ret = ERR_WARN;