Allow use after static destruction took place

This commit is contained in:
Alexey Rybalchenko 2019-01-17 13:37:59 +01:00
parent 2d5dd004cb
commit ddf4a3d125
3 changed files with 93 additions and 74 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
build/ build/
.vscode

View File

@ -13,6 +13,7 @@
#include <chrono> #include <chrono>
#include <ctime> // strftime #include <ctime> // strftime
#include <iomanip> // setw, setfill #include <iomanip> // setw, setfill
#include <cstdio> // printf
using namespace std; using namespace std;
@ -84,6 +85,8 @@ Severity Logger::fMinSeverity = Severity::info;
function<void()> Logger::fFatalCallback; function<void()> Logger::fFatalCallback;
unordered_map<string, pair<Severity, function<void(const string& content, const LogMetaData& metadata)>>> Logger::fCustomSinks; unordered_map<string, pair<Severity, function<void(const string& content, const LogMetaData& metadata)>>> Logger::fCustomSinks;
mutex Logger::fMtx; mutex Logger::fMtx;
bool Logger::fIsDestructed = false;
Logger::DestructionHelper fDestructionHelper;
#if defined(__APPLE__) || defined(__FreeBSD__) #if defined(__APPLE__) || defined(__FreeBSD__)
const string Logger::fProcessName = getprogname(); const string Logger::fProcessName = getprogname();
@ -199,6 +202,7 @@ string Logger::VerbosityName(Verbosity verbosity)
Logger::Logger(Severity severity, const string& file, const string& line, const string& func) Logger::Logger(Severity severity, const string& file, const string& line, const string& func)
{ {
if (!fIsDestructed) {
chrono::time_point<chrono::system_clock> now = chrono::system_clock::now(); chrono::time_point<chrono::system_clock> now = chrono::system_clock::now();
size_t pos = file.rfind("/"); size_t pos = file.rfind("/");
@ -211,6 +215,7 @@ Logger::Logger(Severity severity, const string& file, const string& line, const
fMetaData.severity_name = fSeverityNames.at(static_cast<size_t>(severity)); fMetaData.severity_name = fSeverityNames.at(static_cast<size_t>(severity));
fMetaData.severity = severity; fMetaData.severity = severity;
} }
}
void Logger::SetConsoleSeverity(const Severity severity) void Logger::SetConsoleSeverity(const Severity severity)
{ {
@ -524,6 +529,10 @@ void Logger::RemoveCustomSink(const string& key)
Logger& Logger::Log() Logger& Logger::Log()
{ {
if (fIsDestructed) {
return *this;
}
char tsstr[32]; char tsstr[32];
{ {
lock_guard<mutex> lock(fMtx); // localtime is not threadsafe, guard it lock_guard<mutex> lock(fMtx); // localtime is not threadsafe, guard it
@ -639,6 +648,11 @@ Logger& Logger::operator<<(ostream& (*manip) (ostream&))
Logger::~Logger() noexcept(false) Logger::~Logger() noexcept(false)
{ {
if (fIsDestructed) {
printf("post-static destruction output: %s\n", fContent.str().c_str());
return;
}
for (auto& it : fCustomSinks) { for (auto& it : fCustomSinks) {
if (LoggingCustom(it.second.first)) { if (LoggingCustom(it.second.first)) {
lock_guard<mutex> lock(fMtx); lock_guard<mutex> lock(fMtx);

View File

@ -335,6 +335,10 @@ class Logger
virtual ~Logger() noexcept(false); virtual ~Logger() noexcept(false);
// protection for use after static destruction took place
static bool fIsDestructed;
static struct DestructionHelper { ~DestructionHelper() { Logger::fIsDestructed = true; }} fDestructionHelper;
private: private:
LogMetaData fMetaData; LogMetaData fMetaData;