+#ifndef _WIN32
+
+namespace {
+
+struct sigaction oldSigsegvAction;
+
+void sigsegvSignalHandler(int signum, siginfo_t* info, void*) {
+ if (signum != SIGSEGV) {
+ std::cerr << "GuardPageAllocator signal handler called for signal: "
+ << signum;
+ return;
+ }
+
+ if (info &&
+ StackCache::isProtected(reinterpret_cast<intptr_t>(info->si_addr))) {
+ std::cerr << "folly::fibers Fiber stack overflow detected." << std::endl;
+ }
+
+ // Restore old signal handler and let it handle the signal.
+ sigaction(signum, &oldSigsegvAction, nullptr);
+ raise(signum);
+}
+
+bool isInJVM() {
+ auto getCreated = dlsym(RTLD_DEFAULT, "JNI_GetCreatedJavaVMs");
+ return getCreated;
+}
+
+void installSignalHandler() {
+ static std::once_flag onceFlag;
+ std::call_once(onceFlag, []() {
+ if (isInJVM()) {
+ // Don't install signal handler, since JVM internal signal handler doesn't
+ // work with SA_ONSTACK
+ return;
+ }
+
+ struct sigaction sa;
+ memset(&sa, 0, sizeof(sa));
+ sigemptyset(&sa.sa_mask);
+ // By default signal handlers are run on the signaled thread's stack.
+ // In case of stack overflow running the SIGSEGV signal handler on
+ // the same stack leads to another SIGSEGV and crashes the program.
+ // Use SA_ONSTACK, so alternate stack is used (only if configured via
+ // sigaltstack).
+ sa.sa_flags |= SA_SIGINFO | SA_ONSTACK;
+ sa.sa_sigaction = &sigsegvSignalHandler;
+ sigaction(SIGSEGV, &sa, &oldSigsegvAction);
+ });
+}
+} // namespace
+
+#endif
+