]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: debug: do not dump a context-less backtrace in ABORT_NOW()
authorWilly Tarreau <w@1wt.eu>
Tue, 11 Aug 2026 12:20:45 +0000 (14:20 +0200)
committerWilly Tarreau <w@1wt.eu>
Thu, 13 Aug 2026 15:43:30 +0000 (17:43 +0200)
Originally before 2.4, ABORT_NOW() was used to instantly stop the program
with as little damage as possible in order to help debug it, keeping
registers intact.

This was modified in 2.4-dev6 by commit 5baf4fe31ad ("MEDIUM: debug:
now always print a backtrace on CRASH_NOW() and friends") because the
same macro was shared with BUG_ON() and we didn't have the backtrace.
But by doing this we lost the ability to debug the precise crash
location.

Later in 3.0, we added support for an extra contextual info with commit
d417863828 ("MINOR: debug: support passing an optional message in
ABORT_NOW()"). This became even more fishy because at this point,
ABORT_NOW() called empty would only emit a backtrace, while when
passed an argument, it would emit "ABORT at <file>:<line>: <arg>",
losing the registers despite what the comment would say.

Now that we can type call places, it becomes possible to fix it again
so that ABORT_NOW() honors its two promises:
  - no register mangling when called with no argument ;
  - location + backtrace + message when called with an argument.

This patch simply conditions the call to ha_backtrace_to_stderr() to
the presence of an argument, without touching the abort_with_line()
call. It's done using an extra if to minimize the diff as it's only
temporary. For BUG_ON(), the trace calls are factored before the call
to an argument-less ABORT_NOW() since that one will not print the
message anymore.

include/haproxy/bug.h

index 69018d37f84d87bf4c8b03a280ca219d487cdf6f..8d7776224e555eb33e7a616fa1bf0ca9eaff9819 100644 (file)
@@ -303,7 +303,8 @@ 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__); \
-               ha_backtrace_to_stderr(1);                              \
+               if (sizeof("" __VA_ARGS__) > 1)                         \
+                       ha_backtrace_to_stderr(1);                      \
                abort_with_line(__LINE__);                              \
        } while (0)
 
@@ -366,10 +367,10 @@ extern __attribute__((__weak__)) struct debug_count __stop_dbg_cnt  HA_SECTION_S
                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_NOW();                                    \
-                       else if (_details & DBG_DET_FAT_WARN)                   \
-                               ha_backtrace_to_stderr(0);                      \
                }                                                               \
        }
 
@@ -426,10 +427,10 @@ 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_NOW();                            \
-                       else if (details & DBG_DET_FAT_WARN)            \
-                               ha_backtrace_to_stderr(0);              \
                }                                                       \
        }