Memory leak checker API. (#3368)

This commit is contained in:
Nikolay Igotti
2019-09-23 17:41:26 +03:00
committed by GitHub
parent b393e4f900
commit b7e868ad05
3 changed files with 40 additions and 5 deletions
+21 -4
View File
@@ -102,6 +102,8 @@ FrameOverlay exportFrameOverlay;
volatile int allocCount = 0; volatile int allocCount = 0;
volatile int aliveMemoryStatesCount = 0; volatile int aliveMemoryStatesCount = 0;
KBoolean g_checkLeaks = KonanNeedDebugInfo;
// TODO: can we pass this variable as an explicit argument? // TODO: can we pass this variable as an explicit argument?
THREAD_LOCAL_VARIABLE MemoryState* memoryState = nullptr; THREAD_LOCAL_VARIABLE MemoryState* memoryState = nullptr;
THREAD_LOCAL_VARIABLE FrameOverlay* currentFrame = nullptr; THREAD_LOCAL_VARIABLE FrameOverlay* currentFrame = nullptr;
@@ -1724,10 +1726,16 @@ void deinitMemory(MemoryState* memoryState) {
} }
#else #else
#if USE_GC #if USE_GC
if (IsStrictMemoryModel && lastMemoryState) if (IsStrictMemoryModel && lastMemoryState && allocCount > 0 && g_checkLeaks) {
RuntimeAssert(allocCount == 0, "Memory leaks found"); char buf[1024];
#endif konan::snprintf(buf, sizeof(buf),
#endif "Memory leaks detected, %d objects leaked!\n"
"Use `Platform.isMemoryLeakCheckerActive = false` to avoid this check.\n", allocCount);
konan::consoleErrorUtf8(buf, konan::strnlen(buf, sizeof(buf)));
konan::abort();
}
#endif // USE_GC
#endif // TRACE_MEMORY
PRINT_EVENT(memoryState) PRINT_EVENT(memoryState)
DEINIT_EVENT(memoryState) DEINIT_EVENT(memoryState)
@@ -2941,4 +2949,13 @@ void Kotlin_Any_share(ObjHeader* obj) {
shareAny(obj); shareAny(obj);
} }
KBoolean Konan_Platform_getMemoryLeakChecker() {
return g_checkLeaks;
}
void Konan_Platform_setMemoryLeakChecker(KBoolean value) {
g_checkLeaks = value;
}
} // extern "C" } // extern "C"
+1
View File
@@ -143,6 +143,7 @@ static void onThreadExitCallback(void* value) {
free(record); free(record);
record = next; record = next;
} }
pthread_setspecific(terminationKey, nullptr);
} }
static void onThreadExitInit() { static void onThreadExitInit() {
@@ -81,6 +81,17 @@ public object Platform {
public val isDebugBinary: Boolean public val isDebugBinary: Boolean
get() = Platform_isDebugBinary() get() = Platform_isDebugBinary()
/**
* If the memory leak checker is activated, by default `true` in debug mode, `false` in release.
* When memory leak checker is activated, and leak is detected during last Kotlin context
* deinitialization process - error message with leak information is printed and application
* execution is aborted.
*
* @see isDebugBinary
*/
public var isMemoryLeakCheckerActive: Boolean
get() = Platform_getMemoryLeakChecker()
set(value) = Platform_setMemoryLeakChecker(value)
} }
@SymbolName("Konan_Platform_canAccessUnaligned") @SymbolName("Konan_Platform_canAccessUnaligned")
@@ -99,4 +110,10 @@ private external fun Platform_getCpuArchitecture(): Int
private external fun Platform_getMemoryModel(): Int private external fun Platform_getMemoryModel(): Int
@SymbolName("Konan_Platform_isDebugBinary") @SymbolName("Konan_Platform_isDebugBinary")
private external fun Platform_isDebugBinary(): Boolean private external fun Platform_isDebugBinary(): Boolean
@SymbolName("Konan_Platform_getMemoryLeakChecker")
private external fun Platform_getMemoryLeakChecker(): Boolean
@SymbolName("Konan_Platform_setMemoryLeakChecker")
private external fun Platform_setMemoryLeakChecker(value: Boolean): Unit