From 458992b06d80eb568141f60a33d38e12e894e27a Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Tue, 5 May 2020 08:07:47 +0300 Subject: [PATCH] Prevent UB in DeleteLock() function --- src/sync.cpp | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/src/sync.cpp b/src/sync.cpp index b86c57e49..afb5ad51b 100644 --- a/src/sync.cpp +++ b/src/sync.cpp @@ -78,21 +78,16 @@ typedef std::map, LockStack> LockOrders; typedef std::set > InvLockOrders; struct LockData { - // Very ugly hack: as the global constructs and destructors run single - // threaded, we use this boolean to know whether LockData still exists, - // as DeleteLock can get called by global RecursiveMutex destructors - // after LockData disappears. - bool available; - LockData() : available(true) {} - ~LockData() { available = false; } - LockOrders lockorders; InvLockOrders invlockorders; std::mutex dd_mutex; }; + LockData& GetLockData() { - static LockData lockdata; - return lockdata; + // This approach guarantees that the object is not destroyed until after its last use. + // The operating system automatically reclaims all the memory in a program's heap when that program exits. + static LockData& lock_data = *new LockData(); + return lock_data; } static thread_local LockStack g_lockstack; @@ -207,10 +202,6 @@ void AssertLockNotHeldInternal(const char* pszName, const char* pszFile, int nLi void DeleteLock(void* cs) { LockData& lockdata = GetLockData(); - if (!lockdata.available) { - // We're already shutting down. - return; - } std::lock_guard lock(lockdata.dd_mutex); std::pair item = std::make_pair(cs, nullptr); LockOrders::iterator it = lockdata.lockorders.lower_bound(item);