Restore stack size in child processes

Fixes #4673.
This commit is contained in:
Eelco Dolstra 2021-04-07 13:40:13 +02:00
parent 9b9e703df4
commit 906adadacd
3 changed files with 32 additions and 12 deletions

View file

@ -32,6 +32,7 @@
#ifdef __linux__ #ifdef __linux__
#include <sys/prctl.h> #include <sys/prctl.h>
#include <sys/resource.h>
#endif #endif
@ -1618,11 +1619,37 @@ static void restoreSignals()
throw SysError("restoring signals"); throw SysError("restoring signals");
} }
#if __linux__
rlim_t savedStackSize = 0;
#endif
void setStackSize(size_t stackSize)
{
#if __linux__
struct rlimit limit;
if (getrlimit(RLIMIT_STACK, &limit) == 0 && limit.rlim_cur < stackSize) {
savedStackSize = limit.rlim_cur;
limit.rlim_cur = stackSize;
setrlimit(RLIMIT_STACK, &limit);
}
#endif
}
void restoreProcessContext() void restoreProcessContext()
{ {
restoreSignals(); restoreSignals();
restoreAffinity(); restoreAffinity();
#if __linux__
if (savedStackSize) {
struct rlimit limit;
if (getrlimit(RLIMIT_STACK, &limit) == 0) {
limit.rlim_cur = savedStackSize;
setrlimit(RLIMIT_STACK, &limit);
}
}
#endif
} }
/* RAII helper to automatically deregister a callback. */ /* RAII helper to automatically deregister a callback. */

View file

@ -300,6 +300,10 @@ std::pair<int, std::string> runProgram(const RunOptions & options);
void runProgram2(const RunOptions & options); void runProgram2(const RunOptions & options);
/* Change the stack size. */
void setStackSize(size_t stackSize);
/* Restore the original inherited Unix process context (such as signal /* Restore the original inherited Unix process context (such as signal
masks, stack size, CPU affinity). */ masks, stack size, CPU affinity). */
void restoreProcessContext(); void restoreProcessContext();

View file

@ -17,10 +17,6 @@
#include <netdb.h> #include <netdb.h>
#include <netinet/in.h> #include <netinet/in.h>
#if __linux__
#include <sys/resource.h>
#endif
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
extern std::string chrootHelperName; extern std::string chrootHelperName;
@ -335,14 +331,7 @@ int main(int argc, char * * argv)
{ {
// Increase the default stack size for the evaluator and for // Increase the default stack size for the evaluator and for
// libstdc++'s std::regex. // libstdc++'s std::regex.
#if __linux__ nix::setStackSize(64 * 1024 * 1024);
rlim_t stackSize = 64 * 1024 * 1024;
struct rlimit limit;
if (getrlimit(RLIMIT_STACK, &limit) == 0 && limit.rlim_cur < stackSize) {
limit.rlim_cur = stackSize;
setrlimit(RLIMIT_STACK, &limit);
}
#endif
return nix::handleExceptions(argv[0], [&]() { return nix::handleExceptions(argv[0], [&]() {
nix::mainWrapped(argc, argv); nix::mainWrapped(argc, argv);