forked from lix-project/lix
libmain: Make the entire stack overflow handler pluggable
This commit is contained in:
parent
0d75675787
commit
ab4eb39386
|
@ -113,14 +113,15 @@ struct PrintFreed
|
||||||
/* Install a SIGSEGV handler to detect stack overflows. */
|
/* Install a SIGSEGV handler to detect stack overflows. */
|
||||||
void detectStackOverflow();
|
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 is called by the handler installed by detectStackOverflow().
|
||||||
|
|
||||||
This gives Nix library consumers a limit opportunity to report the error
|
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
|
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
|
limited stack space and a potentially a corrupted heap, all while the failed
|
||||||
|
|
|
@ -30,10 +30,7 @@ static void sigsegvHandler(int signo, siginfo_t * info, void * ctx)
|
||||||
ptrdiff_t diff = (char *) info->si_addr - sp;
|
ptrdiff_t diff = (char *) info->si_addr - sp;
|
||||||
if (diff < 0) diff = -diff;
|
if (diff < 0) diff = -diff;
|
||||||
if (diff < 4096) {
|
if (diff < 4096) {
|
||||||
char msg[] = "error: stack overflow (possible infinite recursion)\n";
|
nix::stackOverflowHandler(info, ctx);
|
||||||
[[gnu::unused]] auto res = write(2, msg, strlen(msg));
|
|
||||||
nix::extraStackOverflowHandler(info, ctx);
|
|
||||||
_exit(1); // maybe abort instead?
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,9 +66,12 @@ void detectStackOverflow()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
std::function<void(siginfo_t * info, void * ctx)> extraStackOverflowHandler(
|
std::function<void(siginfo_t * info, void * ctx)> stackOverflowHandler(defaultStackOverflowHandler);
|
||||||
[](siginfo_t * info, void * ctx) {
|
|
||||||
|
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?
|
||||||
}
|
}
|
||||||
);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue