BUG/MINOR: debug: restore complain tail jumps with clang
Commit
9752f802b3869c96446f7e84e43d89360695c0f8 introduced
eliminate_tail_calls to turn the final call of a function into a jump.
Commit
431b6b1cd92a54f4a53b66a5ff27a64381ff9a23 then applied it to
complain() and complain_with_dbg() so that these wrappers would not appear
in diagnostic backtraces.
The GCC expansion enables sibling-call optimization. The Clang expansion
currently uses disable_tail_calls, which has the opposite meaning: Clang
documents it as preventing tail-call optimization inside the attributed
function.
This is visible through HAProxy's own "debug dev check" command. GCC 11
omits complain_with_dbg() from the resulting backtrace, while Clang 14 and
Clang 18 retain one complain_with_dbg() frame. The builds otherwise succeed,
so build success alone does not expose the difference.
Making eliminate_tail_calls empty for Clang removes the inverse attribute,
but is not sufficient by itself: both tested Clang versions then inline
ha_backtrace_to_stderr() into the wrapper and still retain its frame. Also
mark the callee noinline so that Clang emits the intended final jump.
The resulting source was tested on x86-64 at master revision
3081fdb5846b1b7ab8f93d1f28b31af13502f5db. Normal GCC 11, Clang 14, and
Clang 18 builds passed, and "debug dev check" omitted the wrapper frame in
all three repaired builds. Object-code inspection confirmed a final jump.
CI-aligned no-features builds with GCC 13 and Clang 18 also passed, including
143 default, bug, and devel regression tests for each compiler. A broader
Clang 14 run passed 167 regression tests. The enabled unit tests passed for
the repaired GCC and Clang builds. Clang 13 never optimizes the call in any
case.
The user-visible effect is limited to developer backtrace quality. This is
not a security or performance fix. This is submitted as an RFC because a
maintainer may prefer a Clang-specific spelling or a reusable noinline
abstraction. This is the approach I had in mind, and any suggestions would
be appreciated.
No backport is needed because both introducing commits are only in the 3.5
development branch.