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 <odanrc@yahoo.com.br>
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
Maintainer: Jason Lowe-Power <power.jg@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Jui-min Lee
2021-05-27 09:22:24 +08:00
parent 5c34457a38
commit 6723b06275
2 changed files with 70 additions and 22 deletions

View File

@@ -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;
}

View File

@@ -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;
}