From 3e804605b7931a732121f3854da95d31c6567d38 Mon Sep 17 00:00:00 2001 From: James Turner Date: Sat, 5 Sep 2020 10:43:01 +0100 Subject: [PATCH] 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. --- simgear/debug/logstream.cxx | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/simgear/debug/logstream.cxx b/simgear/debug/logstream.cxx index e843a659..5610973c 100644 --- a/simgear/debug/logstream.cxx +++ b/simgear/debug/logstream.cxx @@ -139,8 +139,8 @@ public: logTimer.stamp(); } - virtual void operator()(sgDebugClass c, sgDebugPriority p, - const char* file, int line, const std::string& message) + void operator()(sgDebugClass c, sgDebugPriority p, + const char* file, int line, const std::string& message) override { if (!shouldLog(c, p)) return; @@ -402,6 +402,13 @@ public: ~LogStreamPrivate() { removeCallbacks(); + + // house-keeping, avoid leak warnings if we exit before disabling + // startup logging + { + std::lock_guard g(m_lock); + clearStartupEntriesLocked(); + } } std::mutex m_lock; @@ -448,10 +455,18 @@ public: { std::lock_guard g(m_lock); 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(e.file)); + }); + m_startupEntries.clear(); + } + void run() override { while (1) { @@ -474,8 +489,10 @@ public: (*cb)(entry.debugClass, entry.debugPriority, 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(entry.file)); } } // of main thread loop @@ -536,9 +553,9 @@ public: PauseThread pause(this); m_logPriority = p; m_logClass = c; - for (auto cb : m_consoleCallbacks) { - cb->setLogLevels(c, p); - } + for (auto cb : m_consoleCallbacks) { + cb->setLogLevels(c, p); + } } bool would_log( sgDebugClass c, sgDebugPriority p ) const