diff options
author | Robert Hensing <robert@roberthensing.nl> | 2022-10-14 12:37:34 +0200 |
---|---|---|
committer | Robert Hensing <robert@roberthensing.nl> | 2022-10-14 12:53:46 +0200 |
commit | ab4eb39386eab091f8682efa69e104f4ed74c1ca (patch) | |
tree | e148ea49ebcd8b134ac52bce831aa21cf8f8bde1 /src/libmain | |
parent | 0d756757877ecfb09fd2003cf887dfdf8067b702 (diff) |
libmain: Make the entire stack overflow handler pluggable
Diffstat (limited to 'src/libmain')
-rw-r--r-- | src/libmain/shared.hh | 7 | ||||
-rw-r--r-- | src/libmain/stack.cc | 16 |
2 files changed, 12 insertions, 11 deletions
diff --git a/src/libmain/shared.hh b/src/libmain/shared.hh index 66d29a1f7..3c37fd627 100644 --- a/src/libmain/shared.hh +++ b/src/libmain/shared.hh @@ -113,14 +113,15 @@ struct PrintFreed /* Install a SIGSEGV handler to detect stack overflows. */ void detectStackOverflow(); -/* Pluggable behavior to run before _exit(1) in case of a stack overflow. +/* Pluggable behavior to run in case of a stack overflow. - Default value: do nothing, return immediately. + 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. + 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 diff --git a/src/libmain/stack.cc b/src/libmain/stack.cc index a6d10f738..10f71c1dc 100644 --- a/src/libmain/stack.cc +++ b/src/libmain/stack.cc @@ -30,10 +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)); - nix::extraStackOverflowHandler(info, ctx); - _exit(1); // maybe abort instead? + nix::stackOverflowHandler(info, ctx); } } @@ -69,9 +66,12 @@ void detectStackOverflow() #endif } -std::function<void(siginfo_t * info, void * ctx)> extraStackOverflowHandler( - [](siginfo_t * info, void * ctx) { - } -); +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? +} } |