diff options
author | Eelco Dolstra <edolstra@gmail.com> | 2022-10-14 17:12:45 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-14 17:12:45 +0200 |
commit | 9f7877abacbf3f0371b3b0969f7380c6c6db58a5 (patch) | |
tree | e148ea49ebcd8b134ac52bce831aa21cf8f8bde1 /src | |
parent | 8196d4f4e94407396b4ba37bd89c91ad0d4062f0 (diff) | |
parent | ab4eb39386eab091f8682efa69e104f4ed74c1ca (diff) |
Merge pull request #7172 from hercules-ci/libmain-extraStackOverflowHandler
libmain: Make stack overflow handler configurable
Diffstat (limited to 'src')
-rw-r--r-- | src/libmain/shared.hh | 20 | ||||
-rw-r--r-- | src/libmain/stack.cc | 12 |
2 files changed, 29 insertions, 3 deletions
diff --git a/src/libmain/shared.hh b/src/libmain/shared.hh index 0cc56d47d..3c37fd627 100644 --- a/src/libmain/shared.hh +++ b/src/libmain/shared.hh @@ -113,5 +113,25 @@ struct PrintFreed /* Install a SIGSEGV handler to detect stack overflows. */ void detectStackOverflow(); +/* Pluggable behavior to run in case of a stack overflow. + + Default value: defaultStackOverflowHandler. + + This is called by the handler installed by detectStackOverflow(). + + This gives Nix library consumers a limit opportunity to report the error + condition. The handler should exit the process. + See defaultStackOverflowHandler() for a reference implementation. + + NOTE: Use with diligence, because this runs in the signal handler, with very + limited stack space and a potentially a corrupted heap, all while the failed + thread is blocked indefinitely. All functions called must be reentrant. */ +extern std::function<void(siginfo_t * info, void * ctx)> stackOverflowHandler; + +/* The default, robust implementation of stackOverflowHandler. + + Prints an error message directly to stderr using a syscall instead of the + logger. Exits the process immediately after. */ +void defaultStackOverflowHandler(siginfo_t * info, void * ctx); } diff --git a/src/libmain/stack.cc b/src/libmain/stack.cc index b0a4a4c5d..10f71c1dc 100644 --- a/src/libmain/stack.cc +++ b/src/libmain/stack.cc @@ -1,4 +1,5 @@ #include "error.hh" +#include "shared.hh" #include <cstring> #include <cstddef> @@ -29,9 +30,7 @@ static void sigsegvHandler(int signo, siginfo_t * info, void * ctx) ptrdiff_t diff = (char *) info->si_addr - sp; if (diff < 0) diff = -diff; if (diff < 4096) { - char msg[] = "error: stack overflow (possible infinite recursion)\n"; - [[gnu::unused]] auto res = write(2, msg, strlen(msg)); - _exit(1); // maybe abort instead? + nix::stackOverflowHandler(info, ctx); } } @@ -67,5 +66,12 @@ void detectStackOverflow() #endif } +std::function<void(siginfo_t * info, void * ctx)> stackOverflowHandler(defaultStackOverflowHandler); + +void defaultStackOverflowHandler(siginfo_t * info, void * ctx) { + char msg[] = "error: stack overflow (possible infinite recursion)\n"; + [[gnu::unused]] auto res = write(2, msg, strlen(msg)); + _exit(1); // maybe abort instead? +} } |