From 6723b0627583daa6b7b2c249837a841df30851c9 Mon Sep 17 00:00:00 2001 From: Jui-min Lee Date: Thu, 27 May 2021 09:22:24 +0800 Subject: [PATCH] base: Construct loggers on the heap Loggers was previously declared as global variables, hence are unsafe to be used inside other global objects' destructor (e.g. scMainFiber). This CL makes them heap allocated objects hold by function static variables. As a result: 1. The loggers never get destructed at the end of program, which makes them safe to be used in global objects' destructor. 2. The loggers are constructed ondemand instead of relying on linker's unknown way of ordering, which makes them safe to be used in global objects' constructor. Change-Id: Ieb499d2fa4c5c1c015324cb72b055115b0933ab8 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/46079 Reviewed-by: Daniel Carvalho Reviewed-by: Jason Lowe-Power Maintainer: Jason Lowe-Power Tested-by: kokoro --- src/base/gtest/logging_mock.cc | 46 ++++++++++++++++++++++++++-------- src/base/logging.cc | 46 ++++++++++++++++++++++++++-------- 2 files changed, 70 insertions(+), 22 deletions(-) diff --git a/src/base/gtest/logging_mock.cc b/src/base/gtest/logging_mock.cc index e09a1445eb..572d05710e 100644 --- a/src/base/gtest/logging_mock.cc +++ b/src/base/gtest/logging_mock.cc @@ -71,16 +71,40 @@ class GTestExitLogger : public Logger void exit() override { throw GTestException(); } }; -GTestExitLogger panicLogger("panic: "); -GTestExitLogger fatalLogger("fatal: "); -GTestLogger warnLogger("warn: "); -GTestLogger infoLogger("info: "); -GTestLogger hackLogger("hack: "); - } // anonymous namespace -Logger &Logger::getPanic() { return panicLogger; } -Logger &Logger::getFatal() { return fatalLogger; } -Logger &Logger::getWarn() { return warnLogger; } -Logger &Logger::getInfo() { return infoLogger; } -Logger &Logger::getHack() { return hackLogger; } +// We intentionally put all the loggers on the heap to prevent them from being +// destructed at the end of the program. This make them safe to be used inside +// destructor of other global objects. Also, we make them function static +// veriables to ensure they are initialized ondemand, so it is also safe to use +// them inside constructor of other global objects. + +Logger& +Logger::getPanic() { + static GTestExitLogger* panic_logger = new GTestExitLogger("panic: "); + return *panic_logger; +} + +Logger& +Logger::getFatal() { + static GTestExitLogger* fatal_logger = new GTestExitLogger("fatal: "); + return *fatal_logger; +} + +Logger& +Logger::getWarn() { + static GTestLogger* warn_logger = new GTestLogger("warn: "); + return *warn_logger; +} + +Logger& +Logger::getInfo() { + static GTestLogger* info_logger = new GTestLogger("info: "); + return *info_logger; +} + +Logger& +Logger::getHack() { + static GTestLogger* hack_logger = new GTestLogger("hack: "); + return *hack_logger; +} diff --git a/src/base/logging.cc b/src/base/logging.cc index 12904554ce..f96d10149c 100644 --- a/src/base/logging.cc +++ b/src/base/logging.cc @@ -70,16 +70,40 @@ class FatalLogger : public ExitLogger void exit() override { ::exit(1); } }; -ExitLogger panicLogger("panic: "); -FatalLogger fatalLogger("fatal: "); -Logger warnLogger("warn: "); -Logger infoLogger("info: "); -Logger hackLogger("hack: "); - } // anonymous namespace -Logger &Logger::getPanic() { return panicLogger; } -Logger &Logger::getFatal() { return fatalLogger; } -Logger &Logger::getWarn() { return warnLogger; } -Logger &Logger::getInfo() { return infoLogger; } -Logger &Logger::getHack() { return hackLogger; } +// We intentionally put all the loggers on the heap to prevent them from being +// destructed at the end of the program. This make them safe to be used inside +// destructor of other global objects. Also, we make them function static +// veriables to ensure they are initialized ondemand, so it is also safe to use +// them inside constructor of other global objects. + +Logger& +Logger::getPanic() { + static ExitLogger* panic_logger = new ExitLogger("panic: "); + return *panic_logger; +} + +Logger& +Logger::getFatal() { + static FatalLogger* fatal_logger = new FatalLogger("fatal: "); + return *fatal_logger; +} + +Logger& +Logger::getWarn() { + static Logger* warn_logger = new Logger("warn: "); + return *warn_logger; +} + +Logger& +Logger::getInfo() { + static Logger* info_logger = new Logger("info: "); + return *info_logger; +} + +Logger& +Logger::getHack() { + static Logger* hack_logger = new Logger("hack: "); + return *hack_logger; +}