ASan: make copied files in log entries safe at init.

Ensure that if we copy file-names of log entries while startup
logging is active, we free them, but only once startup logging is
disabled, or on shutdown. This is needed to avoid crashes when
we use file-name copying for the Qt message handler.
This commit is contained in:
James Turner 2020-09-05 10:43:01 +01:00 committed by Automatic Release Builder
parent 35b1d321fe
commit 3e804605b7

View File

@ -139,8 +139,8 @@ public:
logTimer.stamp(); logTimer.stamp();
} }
virtual void operator()(sgDebugClass c, sgDebugPriority p, void operator()(sgDebugClass c, sgDebugPriority p,
const char* file, int line, const std::string& message) const char* file, int line, const std::string& message) override
{ {
if (!shouldLog(c, p)) return; if (!shouldLog(c, p)) return;
@ -402,6 +402,13 @@ public:
~LogStreamPrivate() ~LogStreamPrivate()
{ {
removeCallbacks(); removeCallbacks();
// house-keeping, avoid leak warnings if we exit before disabling
// startup logging
{
std::lock_guard<std::mutex> g(m_lock);
clearStartupEntriesLocked();
}
} }
std::mutex m_lock; std::mutex m_lock;
@ -448,10 +455,18 @@ public:
{ {
std::lock_guard<std::mutex> g(m_lock); std::lock_guard<std::mutex> g(m_lock);
m_startupLogging = on; m_startupLogging = on;
m_startupEntries.clear(); clearStartupEntriesLocked();
} }
} }
void clearStartupEntriesLocked()
{
std::for_each(m_startupEntries.begin(), m_startupEntries.end(), [](const LogEntry& e) {
if (e.freeFilename) free(const_cast<char*>(e.file));
});
m_startupEntries.clear();
}
void run() override void run() override
{ {
while (1) { while (1) {
@ -475,7 +490,9 @@ public:
entry.file, entry.line, entry.message); entry.file, entry.line, entry.message);
} }
if (entry.freeFilename) { // frrr the filename if required. For startup entries
// we wait and do this later
if (!m_startupLogging && entry.freeFilename) {
free(const_cast<char*>(entry.file)); free(const_cast<char*>(entry.file));
} }
} // of main thread loop } // of main thread loop
@ -536,9 +553,9 @@ public:
PauseThread pause(this); PauseThread pause(this);
m_logPriority = p; m_logPriority = p;
m_logClass = c; m_logClass = c;
for (auto cb : m_consoleCallbacks) { for (auto cb : m_consoleCallbacks) {
cb->setLogLevels(c, p); cb->setLogLevels(c, p);
} }
} }
bool would_log( sgDebugClass c, sgDebugPriority p ) const bool would_log( sgDebugClass c, sgDebugPriority p ) const