aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRobert Hensing <robert@roberthensing.nl>2022-10-14 12:37:34 +0200
committerRobert Hensing <robert@roberthensing.nl>2022-10-14 12:53:46 +0200
commitab4eb39386eab091f8682efa69e104f4ed74c1ca (patch)
treee148ea49ebcd8b134ac52bce831aa21cf8f8bde1 /src
parent0d756757877ecfb09fd2003cf887dfdf8067b702 (diff)
libmain: Make the entire stack overflow handler pluggable
Diffstat (limited to 'src')
-rw-r--r--src/libmain/shared.hh7
-rw-r--r--src/libmain/stack.cc16
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?
+}
}