From 0425826fe89e0ad3111aee6cc352ad24d8c38525 Mon Sep 17 00:00:00 2001 From: Nikolay Igotti Date: Mon, 17 Feb 2020 13:45:09 +0300 Subject: [PATCH] Fix GC deinit race leading to bogus leak reports. (#3865) --- runtime/src/main/cpp/CyclicCollector.cpp | 2 +- runtime/src/main/cpp/Memory.cpp | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/runtime/src/main/cpp/CyclicCollector.cpp b/runtime/src/main/cpp/CyclicCollector.cpp index d2b27add5f2..d7f12009b65 100644 --- a/runtime/src/main/cpp/CyclicCollector.cpp +++ b/runtime/src/main/cpp/CyclicCollector.cpp @@ -169,7 +169,7 @@ class CyclicCollector { restartCount = 0; restart: COLLECTOR_LOG("start cycle GC\n"); - if (restartCount > 10) { + if (restartCount > 10 && !terminateCollector_) { COLLECTOR_LOG("wait for some time to avoid GC trashing\n"); struct timeval tv; struct timespec ts; diff --git a/runtime/src/main/cpp/Memory.cpp b/runtime/src/main/cpp/Memory.cpp index e9435d98aae..9375fe1fb5c 100644 --- a/runtime/src/main/cpp/Memory.cpp +++ b/runtime/src/main/cpp/Memory.cpp @@ -1748,11 +1748,18 @@ MemoryState* initMemory() { } void deinitMemory(MemoryState* memoryState) { + static int pendingDeinit = 0; + atomicAdd(&pendingDeinit, 1); #if USE_GC bool lastMemoryState = atomicAdd(&aliveMemoryStatesCount, -1) == 0; + bool checkLeaks = g_checkLeaks && lastMemoryState; if (lastMemoryState) { garbageCollect(memoryState, true); #if USE_CYCLIC_GC + // If there are other pending deinits (rare situation) - just skip the leak checker. + if (atomicGet(&pendingDeinit) > 1) { + checkLeaks = false; + } cyclicDeinit(); #endif // USE_CYCLIC_GC } @@ -1770,9 +1777,10 @@ void deinitMemory(MemoryState* memoryState) { konanDestructInstance(memoryState->tlsMap); RuntimeAssert(memoryState->finalizerQueue == nullptr, "Finalizer queue must be empty"); RuntimeAssert(memoryState->finalizerQueueSize == 0, "Finalizer queue must be empty"); - #endif // USE_GC + atomicAdd(&pendingDeinit, -1); + #if TRACE_MEMORY if (IsStrictMemoryModel && lastMemoryState && allocCount > 0) { MEMORY_LOG("*** Memory leaks, leaked %d containers ***\n", allocCount); @@ -1780,7 +1788,7 @@ void deinitMemory(MemoryState* memoryState) { } #else #if USE_GC - if (IsStrictMemoryModel && lastMemoryState && allocCount > 0 && g_checkLeaks) { + if (IsStrictMemoryModel && allocCount > 0 && checkLeaks) { char buf[1024]; konan::snprintf(buf, sizeof(buf), "Memory leaks detected, %d objects leaked!\n"