From f6aeca052212c341c3bae4b4da9f983c6804623e Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Wed, 15 Oct 2025 22:14:59 +0200 Subject: [PATCH 1/4] Clarify setStackSize error message Show the actual attempted stack size value (capped at hard limit) separately from the desired value, making it clearer what's happening when the hard limit is lower than requested. --- src/libutil/current-process.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libutil/current-process.cc b/src/libutil/current-process.cc index c7d3b78d0..988621014 100644 --- a/src/libutil/current-process.cc +++ b/src/libutil/current-process.cc @@ -65,13 +65,15 @@ void setStackSize(size_t stackSize) struct rlimit limit; if (getrlimit(RLIMIT_STACK, &limit) == 0 && static_cast(limit.rlim_cur) < stackSize) { savedStackSize = limit.rlim_cur; - limit.rlim_cur = std::min(static_cast(stackSize), limit.rlim_max); + auto requestedSize = std::min(static_cast(stackSize), limit.rlim_max); + limit.rlim_cur = requestedSize; if (setrlimit(RLIMIT_STACK, &limit) != 0) { logger->log( lvlError, HintFmt( - "Failed to increase stack size from %1% to %2% (maximum allowed stack size: %3%): %4%", + "Failed to increase stack size from %1% to %2% (desired: %3%, maximum allowed: %4%): %5%", savedStackSize, + requestedSize, stackSize, limit.rlim_max, std::strerror(errno)) From 2349c3dbde77ea7ef32a89eea2c09048d93c671e Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Wed, 15 Oct 2025 22:40:31 +0200 Subject: [PATCH 2/4] setStackSize: Warn when the desired stack size can't be set --- src/libutil/current-process.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/libutil/current-process.cc b/src/libutil/current-process.cc index 988621014..10522d5ae 100644 --- a/src/libutil/current-process.cc +++ b/src/libutil/current-process.cc @@ -65,6 +65,16 @@ void setStackSize(size_t stackSize) struct rlimit limit; if (getrlimit(RLIMIT_STACK, &limit) == 0 && static_cast(limit.rlim_cur) < stackSize) { savedStackSize = limit.rlim_cur; + if (limit.rlim_max < static_cast(stackSize)) { + logger->log( + lvlWarn, + HintFmt( + "Stack size hard limit is %1%, which is less than the desired %2%. If possible, increase the hard limit, e.g. with 'ulimit -Hs %3%'.", + limit.rlim_max, + stackSize, + stackSize / 1024) + .str()); + } auto requestedSize = std::min(static_cast(stackSize), limit.rlim_max); limit.rlim_cur = requestedSize; if (setrlimit(RLIMIT_STACK, &limit) != 0) { From 08e218eb0b315bf176923dd331318c8c28d270b7 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Tue, 4 Nov 2025 22:51:33 +0100 Subject: [PATCH 3/4] Reduce the stack size to a bit under 64 MiB --- src/nix/main.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/nix/main.cc b/src/nix/main.cc index 74d22e433..217e5fa9b 100644 --- a/src/nix/main.cc +++ b/src/nix/main.cc @@ -566,7 +566,9 @@ int main(int argc, char ** argv) #ifndef _WIN32 // Increase the default stack size for the evaluator and for // libstdc++'s std::regex. - nix::setStackSize(64 * 1024 * 1024); + // This used to be 64 MiB, but macOS as deployed on GitHub Actions has a + // hard limit slightly under that, so we round it down a bit. + nix::setStackSize(60 * 1024 * 1024); #endif return nix::handleExceptions(argv[0], [&]() { nix::mainWrapped(argc, argv); }); From 261f674a2531eb4d4a5473a0179ec792dbd79ca2 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Tue, 4 Nov 2025 23:14:21 +0100 Subject: [PATCH 4/4] tests: Suppress environment-dependent warnings ... via _NIX_TEST_NO_ENVIRONMENT_WARNINGS This environment variable suppresses warnings that depend on the test environment (such as ulimit warnings in builds on systems with lower limits, which may well succeed if it weren't for the warning). This prevents non-deterministic test failures in golden/characterization tests. Alternative considered: filtering stderr in test scripts, but that approach is fragile with binary test output, and potentially multiple call sites. --- src/libutil/current-process.cc | 19 +++++++++++-------- tests/functional/common/vars.sh | 3 +++ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/libutil/current-process.cc b/src/libutil/current-process.cc index 10522d5ae..c07ed8371 100644 --- a/src/libutil/current-process.cc +++ b/src/libutil/current-process.cc @@ -7,6 +7,7 @@ #include "nix/util/file-system.hh" #include "nix/util/processes.hh" #include "nix/util/signals.hh" +#include "nix/util/environment-variables.hh" #include #ifdef __APPLE__ @@ -66,14 +67,16 @@ void setStackSize(size_t stackSize) if (getrlimit(RLIMIT_STACK, &limit) == 0 && static_cast(limit.rlim_cur) < stackSize) { savedStackSize = limit.rlim_cur; if (limit.rlim_max < static_cast(stackSize)) { - logger->log( - lvlWarn, - HintFmt( - "Stack size hard limit is %1%, which is less than the desired %2%. If possible, increase the hard limit, e.g. with 'ulimit -Hs %3%'.", - limit.rlim_max, - stackSize, - stackSize / 1024) - .str()); + if (getEnv("_NIX_TEST_NO_ENVIRONMENT_WARNINGS") != "1") { + logger->log( + lvlWarn, + HintFmt( + "Stack size hard limit is %1%, which is less than the desired %2%. If possible, increase the hard limit, e.g. with 'ulimit -Hs %3%'.", + limit.rlim_max, + stackSize, + stackSize / 1024) + .str()); + } } auto requestedSize = std::min(static_cast(stackSize), limit.rlim_max); limit.rlim_cur = requestedSize; diff --git a/tests/functional/common/vars.sh b/tests/functional/common/vars.sh index ed4b47727..d4d917dae 100644 --- a/tests/functional/common/vars.sh +++ b/tests/functional/common/vars.sh @@ -49,6 +49,9 @@ if ! isTestOnNixOS; then fi export _NIX_IN_TEST=$TEST_ROOT/shared export _NIX_TEST_NO_LSOF=1 + # Suppress warnings that depend on the test environment (e.g., ulimit warnings) + # to avoid non-deterministic test failures in golden tests + export _NIX_TEST_NO_ENVIRONMENT_WARNINGS=1 export NIX_REMOTE=${NIX_REMOTE_-} fi # ! isTestOnNixOS