Skip to content

Merge to Master for 1.93 - #500

Open
mborland wants to merge 15 commits into
masterfrom
develop
Open

mborland wants to merge 15 commits into
masterfrom
develop

Conversation

@mborland

Copy link
Copy Markdown
Member

No description provided.

Flamefire and others added 15 commits July 16, 2026 15:52
Random shuffling (based on current time) might yield the same exact order
with a probability proportional to the number of tests/suites.
Make it less likely by increasing the number of tests.
LCov has too many issues matching collected lines to the source when the
`BOOST_TEST_*` macros are used.
E.g. it reports that it found covered lines after the end of the file.
GHA CI runners run out of memory with the amount of tests and combinations.
Seemingly random failures across multiple compilers and C++ standards
GHA: Use the shared workflow from Boost.CI for tests
…carding the caller's (#495) (#496)

* Report the failing condition in BOOST_TEST_SYS_ASSERT

The macro takes `cond` but stringizes the literal token `exp`, so every one
of its call sites produces the same text regardless of what failed:

    system_error produced by: exp: Out of memory

All six uses in execution_monitor.ipp are sigaction/sigaltstack/signal calls,
and the message identifies none of them. Stringize the parameter.

* Correct the documented default for p_use_alt_stack

The documentation says the flag defaults to false; execution_monitor's
constructor initialises it to true. The true default is why the alternate
stack is installed on paths that never set the property.

* Size the alternate signal stack from the kernel's own minimum

BOOST_TEST_ALT_STACK_SIZE is SIGSTKSZ. glibc 2.34+ made that dynamic --
sysconf(_SC_SIGSTKSZ) -- so it tracks what the running kernel requires.
Other C libraries still define it as a compile time constant: musl uses
8192.

The kernel derives its real minimum from the CPU's XSAVE area and
publishes it as auxv AT_MINSIGSTKSZ, and that is the figure sigaltstack(2)
validates against. Measured, it tracks the XSAVE size plus ~940 bytes of
signal frame:

    Xeon E5-2687W v2 (AVX)   XSAVE   832 -> AT_MINSIGSTKSZ  1776
    Core i9-13900K   (AVX2)  XSAVE  2696 -> AT_MINSIGSTKSZ  3632
    AMX-capable host                     -> AT_MINSIGSTKSZ 11952

~11 KB is reached once AMX tile state (8192 bytes) sits on top of
AVX-512's ~2.7 KB, i.e. Sapphire Rapids and later. On such a host under
musl the kernel minimum exceeds the hardcoded 8192, sigaltstack fails with
ENOMEM, and the test binary aborts before running anything:

    Test setup error: system_error produced by: exp: Out of memory

Prefer AT_MINSIGSTKSZ where it is available, and never go below
MINSIGSTKSZ. Verified under musl in an Alpine container that getauxval is
present and returns the expected value; musl also defines AT_MINSIGSTKSZ
itself, so the fallback define is only for libcs that do not.

No effect where SIGSTKSZ is already dynamic: on glibc the value chosen is
identical before and after, because SIGSTKSZ there already exceeds the
kernel minimum.

* Restore the caller's alternate signal stack instead of disabling it

The install is guarded twice: it happens only when alt_stack is non-null,
and only when no alternate stack is currently active. The teardown is not
guarded at all -- it runs whenever BOOST_TEST_USE_ALT_STACK is compiled in,
and unconditionally disables whatever is installed.

So a program that installs its own alternate signal stack before invoking
Boost.Test loses it at the end of the first monitored scope, and never gets
it back. That is caller state the library did not create.

Demonstrated with a test that installs a 64 KiB stack before main() and
checks it from a test case:

    before this change  ss_size 14528, i.e. Boost's own  (check fails)
    after               ss_size 65536, the caller's      (check passes)

The sequence is: the caller installs; Boost's first handler queries, sees
an active stack and correctly skips its install; the matching destructor
then disables it anyway; every later scope finds nothing active and gets
Boost's own.

Record whether this handler installed the stack, and restore what was
there rather than blanket-disabling. Where Boost did install, the saved
value is a disabled stack in every case reachable today -- the install
only runs when SS_DISABLE was set -- so behaviour is unchanged for
programs that install nothing.

* Take AT_MINSIGSTKSZ from <sys/auxv.h> rather than restating its value

Review feedback on #496: the fallback '#define AT_MINSIGSTKSZ 51' was a
magic number with no provenance.

It is kernel ABI, from linux/auxvec.h, but it does not need restating here
at all. Both glibc and musl expose the constant through <sys/auxv.h>,
which this code already includes -- checked on glibc 2.42 and on musl in
an alpine:edge container, both report 51 from that header alone. Alpine
does not even ship linux/auxvec.h with musl-dev, and does not need to.

So gate the feature on the constant being provided instead of supplying
it. A libc with the header but not the constant now falls back to
SIGSTKSZ, exactly as before this series, rather than compiling against a
value this header invented.

Verified after the change that the feature still enables on both:

    glibc  alt_stack_size() = 14528  (SIGSTKSZ 14528, AT_MINSIGSTKSZ 3632)
    musl   alt_stack_size() =  8192  (SIGSTKSZ  8192, AT_MINSIGSTKSZ 3632)
It should be "*the* following context"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants