diff options
author | Tiger Wang <ziwei.tiger@outlook.com> | 2021-04-21 17:07:48 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-21 17:07:48 +0200 |
commit | 1100b04b59b461f1a2cc3dfe7b53b5473daa7992 (patch) | |
tree | ef38a4a731e0c03c6f923708bac0249560ab611f /src/OSSupport/ConsoleSignalHandler.h | |
parent | Resets ticks alive on death (#5197) (diff) | |
download | cuberite-1100b04b59b461f1a2cc3dfe7b53b5473daa7992.tar cuberite-1100b04b59b461f1a2cc3dfe7b53b5473daa7992.tar.gz cuberite-1100b04b59b461f1a2cc3dfe7b53b5473daa7992.tar.bz2 cuberite-1100b04b59b461f1a2cc3dfe7b53b5473daa7992.tar.lz cuberite-1100b04b59b461f1a2cc3dfe7b53b5473daa7992.tar.xz cuberite-1100b04b59b461f1a2cc3dfe7b53b5473daa7992.tar.zst cuberite-1100b04b59b461f1a2cc3dfe7b53b5473daa7992.zip |
Diffstat (limited to 'src/OSSupport/ConsoleSignalHandler.h')
-rw-r--r-- | src/OSSupport/ConsoleSignalHandler.h | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/src/OSSupport/ConsoleSignalHandler.h b/src/OSSupport/ConsoleSignalHandler.h new file mode 100644 index 000000000..23e63d555 --- /dev/null +++ b/src/OSSupport/ConsoleSignalHandler.h @@ -0,0 +1,130 @@ + +// ConsoleSignalHandler.h + +// Intercepts signals for graceful CTRL-C (and others) handling. + +// This file MUST NOT be included from anywhere other than main.cpp. + + + + + +#include <csignal> + + + + + +// Because SIG_DFL or SIG_IGN could be NULL instead of nullptr, we need to disable the Clang warning here: +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunknown-warning-option" +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" +#endif + +static void NonCtrlHandler(int a_Signal) +{ + LOGD("Terminate event raised from std::signal"); + + switch (a_Signal) + { + case SIGSEGV: + { + PrintStackTrace(); + + LOGERROR( + "Failure report: \n\n" + " :( | Cuberite has encountered an error and needs to close\n" + " | SIGSEGV: Segmentation fault\n" + " |\n" +#ifdef BUILD_ID + " | Cuberite " BUILD_SERIES_NAME " (id: " BUILD_ID ")\n" + " | from commit " BUILD_COMMIT_ID "\n" +#endif + ); + + std::signal(SIGSEGV, SIG_DFL); + return; + } + case SIGABRT: +#ifdef SIGABRT_COMPAT + case SIGABRT_COMPAT: +#endif + { + PrintStackTrace(); + + LOGERROR( + "Failure report: \n\n" + " :( | Cuberite has encountered an error and needs to close\n" + " | SIGABRT: Server self-terminated due to an internal fault\n" + " |\n" +#ifdef BUILD_ID + " | Cuberite " BUILD_SERIES_NAME " (id: " BUILD_ID ")\n" + " | from commit " BUILD_COMMIT_ID "\n" +#endif + ); + + std::signal(SIGSEGV, SIG_DFL); + return; + } + case SIGINT: + case SIGTERM: + { + // Server is shutting down, wait for it... + cRoot::Stop(); + return; + } + } +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + + + + + +#ifdef _WIN32 + +/** Handle CTRL events in windows, including console window close. */ +static BOOL CtrlHandler(DWORD fdwCtrlType) +{ + cRoot::Stop(); + LOGD("Terminate event raised from the Windows CtrlHandler"); + + // Delay as much as possible to try to get the server to shut down cleanly - 10 seconds given by Windows: + std::this_thread::sleep_for(std::chrono::seconds(10)); + + // Returning from main() automatically aborts this handler thread. + + return TRUE; +} + +#endif + + + + + +namespace ConsoleSignalHandler +{ + static void Register() + { + std::signal(SIGSEGV, NonCtrlHandler); + std::signal(SIGTERM, NonCtrlHandler); + std::signal(SIGINT, NonCtrlHandler); + std::signal(SIGABRT, NonCtrlHandler); +#ifdef SIGABRT_COMPAT + std::signal(SIGABRT_COMPAT, NonCtrlHandler); +#endif +#ifdef SIGPIPE + std::signal(SIGPIPE, SIG_IGN); // Ignore (PR #2487). +#endif + +#ifdef _WIN32 + SetConsoleCtrlHandler(reinterpret_cast<PHANDLER_ROUTINE>(CtrlHandler), TRUE); +#endif + } +}; |