diff --git a/src/httpserver.cpp b/src/httpserver.cpp --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -384,8 +384,8 @@ // libevent doesn't support debug logging, in which case we should // clear the BCLog::LIBEVENT flag. if (!UpdateHTTPServerLogging( - GetLogger().WillLogCategory(BCLog::LIBEVENT))) { - GetLogger().DisableCategory(BCLog::LIBEVENT); + LogInstance().WillLogCategory(BCLog::LIBEVENT))) { + LogInstance().DisableCategory(BCLog::LIBEVENT); } #ifdef WIN32 diff --git a/src/init.cpp b/src/init.cpp --- a/src/init.cpp +++ b/src/init.cpp @@ -294,7 +294,7 @@ } static void HandleSIGHUP(int) { - GetLogger().m_reopen_file = true; + LogInstance().m_reopen_file = true; } #else static BOOL WINAPI consoleCtrlHandler(DWORD dwCtrlType) { @@ -1359,9 +1359,8 @@ * careful about what global state you rely on here. */ void InitLogging() { - BCLog::Logger &logger = GetLogger(); - logger.m_print_to_file = !gArgs.IsArgNegated("-debuglogfile"); - logger.m_file_path = AbsPathForConfigVal( + LogInstance().m_print_to_file = !gArgs.IsArgNegated("-debuglogfile"); + LogInstance().m_file_path = AbsPathForConfigVal( gArgs.GetArg("-debuglogfile", DEFAULT_DEBUGLOGFILE)); // Add newlines to the logfile to distinguish this execution from the last @@ -1369,11 +1368,11 @@ // debug.log. LogPrintf("\n\n\n\n\n"); - logger.m_print_to_console = gArgs.GetBoolArg( + LogInstance().m_print_to_console = gArgs.GetBoolArg( "-printtoconsole", !gArgs.GetBoolArg("-daemon", false)); - logger.m_log_timestamps = + LogInstance().m_log_timestamps = gArgs.GetBoolArg("-logtimestamps", DEFAULT_LOGTIMESTAMPS); - logger.m_log_time_micros = + LogInstance().m_log_time_micros = gArgs.GetBoolArg("-logtimemicros", DEFAULT_LOGTIMEMICROS); fLogIPs = gArgs.GetBoolArg("-logips", DEFAULT_LOGIPS); @@ -1528,7 +1527,7 @@ categories.begin(), categories.end(), [](std::string cat) { return cat == "0" || cat == "none"; })) { for (const auto &cat : categories) { - if (!GetLogger().EnableCategory(cat)) { + if (!LogInstance().EnableCategory(cat)) { InitWarning( strprintf(_("Unsupported logging category %s=%s."), "-debug", cat)); @@ -1539,7 +1538,7 @@ // Now remove the logging categories which were explicitly excluded for (const std::string &cat : gArgs.GetArgs("-debugexclude")) { - if (!GetLogger().DisableCategory(cat)) { + if (!LogInstance().DisableCategory(cat)) { InitWarning(strprintf(_("Unsupported logging category %s=%s."), "-debugexclude", cat)); } @@ -1839,7 +1838,7 @@ CreatePidFile(GetPidFile(), getpid()); #endif - BCLog::Logger &logger = GetLogger(); + BCLog::Logger &logger = LogInstance(); if (logger.m_print_to_file) { if (gArgs.GetBoolArg("-shrinkdebugfile", logger.DefaultShrinkDebugFile())) { diff --git a/src/logging.h b/src/logging.h --- a/src/logging.h +++ b/src/logging.h @@ -109,11 +109,11 @@ } // namespace BCLog -BCLog::Logger &GetLogger(); +BCLog::Logger &LogInstance(); /** Return true if log accepts specified category */ static inline bool LogAcceptCategory(BCLog::LogFlags category) { - return GetLogger().WillLogCategory(category); + return LogInstance().WillLogCategory(category); } /** Returns a string with the log categories. */ @@ -149,13 +149,13 @@ #define LogPrint(category, ...) \ do { \ if (LogAcceptCategory((category))) { \ - GetLogger().LogPrintStr(tfm::format(__VA_ARGS__)); \ + LogInstance().LogPrintStr(tfm::format(__VA_ARGS__)); \ } \ } while (0) #define LogPrintf(...) \ do { \ - GetLogger().LogPrintStr(tfm::format(__VA_ARGS__)); \ + LogInstance().LogPrintStr(tfm::format(__VA_ARGS__)); \ } while (0) #endif diff --git a/src/logging.cpp b/src/logging.cpp --- a/src/logging.cpp +++ b/src/logging.cpp @@ -11,22 +11,24 @@ bool fLogIPs = DEFAULT_LOGIPS; const char *const DEFAULT_DEBUGLOGFILE = "debug.log"; -/** - * NOTE: the logger instance is leaked on exit. This is ugly, but will be - * cleaned up by the OS/libc. Defining a logger as a global object doesn't work - * since the order of destruction of static/global objects is undefined. - * Consider if the logger gets destroyed, and then some later destructor calls - * LogPrintf, maybe indirectly, and you get a core dump at shutdown trying to - * access the logger. When the shutdown sequence is fully audited and tested, - * explicit destruction of these objects can be implemented by changing this - * from a raw pointer to a std::unique_ptr. - * - * This method of initialization was originally introduced in - * ee3374234c60aba2cc4c5cd5cac1c0aefc2d817c. - */ -BCLog::Logger &GetLogger() { - static BCLog::Logger *const logger = new BCLog::Logger(); - return *logger; +BCLog::Logger &LogInstance() { + /** + * NOTE: the logger instance is leaked on exit. This is ugly, but will be + * cleaned up by the OS/libc. Defining a logger as a global object doesn't + * work since the order of destruction of static/global objects is + * undefined. Consider if the logger gets destroyed, and then some later + * destructor calls LogPrintf, maybe indirectly, and you get a core dump at + * shutdown trying to access the logger. When the shutdown sequence is fully + * audited and tested, explicit destruction of these objects can be + * implemented by changing this from a raw pointer to a std::unique_ptr. + * Since the destructor is never called, the logger and all its members must + * have a trivial destructor. + * + * This method of initialization was originally introduced in + * ee3374234c60aba2cc4c5cd5cac1c0aefc2d817c. + */ + static BCLog::Logger *g_logger{new BCLog::Logger()}; + return *g_logger; } static int FileWriteStr(const std::string &str, FILE *fp) { diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -409,9 +409,9 @@ bool success; if (enable) { - success = GetLogger().EnableCategory(cat); + success = LogInstance().EnableCategory(cat); } else { - success = GetLogger().DisableCategory(cat); + success = LogInstance().DisableCategory(cat); } if (!success) { @@ -466,7 +466,7 @@ HelpExampleRpc("logging", "[\"all\"], \"[libevent]\"")); } - uint32_t original_log_categories = GetLogger().GetCategoryMask(); + uint32_t original_log_categories = LogInstance().GetCategoryMask(); if (request.params[0].isArray()) { EnableOrDisableLogCategories(request.params[0], true); } @@ -475,7 +475,7 @@ EnableOrDisableLogCategories(request.params[1], false); } - uint32_t updated_log_categories = GetLogger().GetCategoryMask(); + uint32_t updated_log_categories = LogInstance().GetCategoryMask(); uint32_t changed_log_categories = original_log_categories ^ updated_log_categories; @@ -488,8 +488,8 @@ */ if (changed_log_categories & BCLog::LIBEVENT) { if (!UpdateHTTPServerLogging( - GetLogger().WillLogCategory(BCLog::LIBEVENT))) { - GetLogger().DisableCategory(BCLog::LIBEVENT); + LogInstance().WillLogCategory(BCLog::LIBEVENT))) { + LogInstance().DisableCategory(BCLog::LIBEVENT); if (changed_log_categories == BCLog::LIBEVENT) { throw JSONRPCError(RPC_INVALID_PARAMETER, "libevent logging cannot be updated when " diff --git a/src/seeder/main.cpp b/src/seeder/main.cpp --- a/src/seeder/main.cpp +++ b/src/seeder/main.cpp @@ -494,7 +494,7 @@ int main(int argc, char **argv) { // The logger dump everything on the console by default. - GetLogger().m_print_to_console = true; + LogInstance().m_print_to_console = true; signal(SIGPIPE, SIG_IGN); setbuf(stdout, nullptr);