From ad870231cbb8d000dddbb20f49b3670bfbc9c4cd Mon Sep 17 00:00:00 2001 From: furszy Date: Sun, 29 Sep 2019 12:44:32 -0300 Subject: [PATCH] [Startup][Refactor][Backport] * OS memory allocation fail handler. * OS signal handler registration method created to remove code duplication. * AppInitBasicSetup() method created, organizing better the setup step of the wallet initialization. --- src/init.cpp | 64 ++++++++++++++++++++++++++++++++++++---------------- src/init.h | 6 +++++ 2 files changed, 51 insertions(+), 19 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index ff65039996895..00a57a0133846 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -307,7 +307,7 @@ void Shutdown() */ void HandleSIGTERM(int) { - fRequestShutdown = true; + StartShutdown(); } void HandleSIGHUP(int) @@ -315,6 +315,17 @@ void HandleSIGHUP(int) fReopenDebugLog = true; } +#ifndef WIN32 +static void registerSignalHandler(int signal, void(*handler)(int)) +{ + struct sigaction sa; + sa.sa_handler = handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sigaction(signal, &sa, nullptr); +} +#endif + bool static InitError(const std::string& str) { uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_ERROR); @@ -748,10 +759,20 @@ bool AppInitServers() return true; } -/** Initialize pivx. - * @pre Parameters should be parsed and config file should be read. - */ -bool AppInit2() +[[noreturn]] static void new_handler_terminate() +{ + // Rather than throwing std::bad-alloc if allocation fails, terminate + // immediately to (try to) avoid chain corruption. + // Since LogPrintf may itself allocate memory, set the handler directly + // to terminate first. + std::set_new_handler(std::terminate); + LogPrintf("Error: Out of memory. Terminating.\n"); + + // The log was successful, terminate now. + std::terminate(); +}; + +bool AppInitBasicSetup() { // ********************************************************* Step 1: setup #ifdef _MSC_VER @@ -764,7 +785,7 @@ bool AppInit2() _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); #endif #ifdef WIN32 -// Enable Data Execution Prevention (DEP) + // Enable Data Execution Prevention (DEP) // Minimum supported OS versions: WinXP SP3, WinVista >= SP1, Win Server 2008 // A failure is non-critical and needs no further attention! #ifndef PROCESS_DEP_ENABLE @@ -790,26 +811,31 @@ bool AppInit2() umask(077); } - - // Clean shutdown on SIGTERM - struct sigaction sa; - sa.sa_handler = HandleSIGTERM; - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - sigaction(SIGTERM, &sa, NULL); - sigaction(SIGINT, &sa, NULL); + // Clean shutdown on SIGTERMx + registerSignalHandler(SIGTERM, HandleSIGTERM); + registerSignalHandler(SIGINT, HandleSIGTERM); // Reopen debug.log on SIGHUP - struct sigaction sa_hup; - sa_hup.sa_handler = HandleSIGHUP; - sigemptyset(&sa_hup.sa_mask); - sa_hup.sa_flags = 0; - sigaction(SIGHUP, &sa_hup, NULL); + registerSignalHandler(SIGHUP, HandleSIGHUP); // Ignore SIGPIPE, otherwise it will bring the daemon down if the client closes unexpectedly signal(SIGPIPE, SIG_IGN); #endif + std::set_new_handler(new_handler_terminate); + + return true; +} + +/** Initialize pivx. + * @pre Parameters should be parsed and config file should be read. + */ +bool AppInit2() +{ + // ********************************************************* Step 1: setup + if (!AppInitBasicSetup()) + return false; + // ********************************************************* Step 2: parameter interactions // Set this early so that parameter interactions go to console fPrintToConsole = GetBoolArg("-printtoconsole", false); diff --git a/src/init.h b/src/init.h index 17aab3ef62b39..c2f0644d06646 100644 --- a/src/init.h +++ b/src/init.h @@ -29,6 +29,12 @@ void Shutdown(); void PrepareShutdown(); bool AppInit2(); +/** Initialize PIVX core: Basic context setup. + * @note This can be done before daemonization. Do not call Shutdown() if this function fails. + * @pre Parameters should be parsed and config file should be read. + */ +bool AppInitBasicSetup(); + /** The help message mode determines what help message to show */ enum HelpMessageMode { HMM_BITCOIND,