diff --git a/kotlin-native/backend.native/tests/build.gradle b/kotlin-native/backend.native/tests/build.gradle index ee9a2b1b614..b21012613d8 100644 --- a/kotlin-native/backend.native/tests/build.gradle +++ b/kotlin-native/backend.native/tests/build.gradle @@ -783,9 +783,7 @@ task array_to_any(type: KonanLocalTest) { } standaloneTest("runtime_basic_init") { - disabled = (project.testTarget == 'wasm32') // -g not yet properly works for WASM. source = "runtime/basic/init.kt" - flags = ['-g'] expectedExitStatus = 0 } @@ -941,20 +939,6 @@ standaloneTest("cleaner_in_main_without_checker") { goldValue = "" } -standaloneTest("cleaner_leak_release") { - enabled = !project.globalTestArgs.contains('-g') && (project.testTarget != 'wasm32') // Cleaners need workers - source = "runtime/basic/cleaner_leak.kt" - goldValue = "" -} - -standaloneTest("cleaner_leak_debug") { - enabled = !project.globalTestArgs.contains('-opt') && (project.testTarget != 'wasm32') // Cleaners need workers - source = "runtime/basic/cleaner_leak.kt" - flags = ['-g'] - expectedExitStatusChecker = { it != 0 } - outputChecker = { s -> (s =~ /Cleaner (0x)?[0-9a-fA-F]+ was disposed during program exit/).find() } -} - standaloneTest("cleaner_leak_without_checker") { enabled = (project.testTarget != 'wasm32') // Cleaners need workers source = "runtime/basic/cleaner_leak_without_checker.kt" @@ -1066,9 +1050,8 @@ task worker11(type: KonanLocalTest) { } standaloneTest("worker_threadlocal_no_leak") { - disabled = project.globalTestArgs.contains('-opt') || (project.testTarget == 'wasm32') // Needs debug build and pthreads. + disabled = (project.testTarget == 'wasm32') // Needs pthreads. source = "runtime/workers/worker_threadlocal_no_leak.kt" - flags = ['-g'] } task freeze0(type: KonanLocalTest) { @@ -1168,17 +1151,15 @@ task enumIdentity(type: KonanLocalTest) { } standaloneTest("leakWorker") { - disabled = project.globalTestArgs.contains('-opt') || (project.testTarget == 'wasm32') // Needs debug build and pthreads. + disabled = (project.testTarget == 'wasm32') // Needs pthreads. source = "runtime/workers/leak_worker.kt" - flags = ['-g'] expectedExitStatusChecker = { it != 0 } outputChecker = { s -> s.contains("Unfinished workers detected, 1 workers leaked!") } } standaloneTest("leakMemoryWithWorkerTermination") { - disabled = project.globalTestArgs.contains('-opt') || (project.testTarget == 'wasm32') // Needs debug build and pthreads. + disabled = (project.testTarget == 'wasm32') // Needs pthreads. source = "runtime/workers/leak_memory_with_worker_termination.kt" - flags = ['-g'] expectedExitStatusChecker = { it != 0 } outputChecker = { s -> s.contains("Memory leaks detected, 1 objects leaked!") } } @@ -2965,7 +2946,6 @@ standaloneTest("cycle_detector") { standaloneTest("cycle_collector") { disabled = true // Needs USE_CYCLIC_GC, which is disabled. - flags = ['-g'] source = "runtime/memory/cycle_collector.kt" } @@ -2975,9 +2955,14 @@ standaloneTest("cycle_collector_deadlock1") { } standaloneTest("leakMemory") { - disabled = project.globalTestArgs.contains('-opt') || (project.testTarget == 'wasm32') // Needs debug build. source = "runtime/memory/leak_memory.kt" - flags = ['-g'] + expectedExitStatusChecker = { it != 0 } + outputChecker = { s -> s.contains("Memory leaks detected, 1 objects leaked!") } +} + +standaloneTest("leakMemoryWithTestRunner") { + source = "runtime/memory/leak_memory_test_runner.kt" + flags = ['-tr'] expectedExitStatusChecker = { it != 0 } outputChecker = { s -> s.contains("Memory leaks detected, 1 objects leaked!") } } @@ -4084,17 +4069,13 @@ interopTest("interop_kt43265") { } interopTest("interop_leakMemoryWithRunningThreadUnchecked") { - disabled = project.globalTestArgs.contains('-opt') || (project.testTarget == 'wasm32') // Needs debug build. interop = 'leakMemoryWithRunningThread' source = "interop/leakMemoryWithRunningThread/unchecked.kt" - flags = ['-g'] } interopTest("interop_leakMemoryWithRunningThreadChecked") { - disabled = project.globalTestArgs.contains('-opt') || (project.testTarget == 'wasm32') // Needs debug build. interop = 'leakMemoryWithRunningThread' source = "interop/leakMemoryWithRunningThread/checked.kt" - flags = ['-g'] expectedExitStatusChecker = { it != 0 } outputChecker = { s -> s.contains("Cannot run checkers when there are 1 alive runtimes at the shutdown") } } @@ -4192,7 +4173,6 @@ if (PlatformInfo.isAppleTarget(project)) { goldValue = "OK\n" source = "interop/objc_with_initializer/objc_test.kt" interop = 'objcMisc' - flags = ['-g'] doBeforeBuild { mkdir(buildDir) @@ -4395,11 +4375,10 @@ dynamicTest("interop_concurrentRuntime") { } dynamicTest("interop_kt42397") { - disabled = project.target.name != project.hostName || project.globalTestArgs.contains('-opt') + disabled = project.target.name != project.hostName source = "interop/kt42397/knlibrary.kt" cSource = "$projectDir/interop/kt42397/test.cpp" clangTool = "clang++" - flags = ['-g'] } dynamicTest("interop_cleaners_main_thread") { @@ -4447,12 +4426,11 @@ dynamicTest("interop_migrating_main_thread") { } dynamicTest("interop_memory_leaks") { - disabled = (project.target.name != project.hostName) || - project.globalTestArgs.contains('-opt') || (project.testTarget == 'wasm32') // Needs debug build. + disabled = (project.target.name != project.hostName) source = "interop/memory_leaks/lib.kt" cSource = "$projectDir/interop/memory_leaks/main.cpp" clangTool = "clang++" - flags = ['-g', '-Xdestroy-runtime-mode=legacy'] // Runtime cannot be destroyed with interop with on-shutdown. + flags = ['-Xdestroy-runtime-mode=legacy'] // Runtime cannot be destroyed with interop with on-shutdown. expectedExitStatusChecker = { it != 0 } outputChecker = { s -> s.contains("Memory leaks detected, 1 objects leaked!") } } @@ -4732,7 +4710,6 @@ if (isAppleTarget(project)) { enabled = !project.globalTestArgs.contains('-opt') framework("Kt42397") { sources = ['framework/kt42397'] - opts = ['-g'] } swiftSources = ['framework/kt42397'] } diff --git a/kotlin-native/backend.native/tests/framework/kt42397/knlibrary.kt b/kotlin-native/backend.native/tests/framework/kt42397/knlibrary.kt index 3d4a4d25cb0..06efdf7daca 100644 --- a/kotlin-native/backend.native/tests/framework/kt42397/knlibrary.kt +++ b/kotlin-native/backend.native/tests/framework/kt42397/knlibrary.kt @@ -1,3 +1,5 @@ +import kotlin.native.Platform + // The following 2 singletons are unused. However, since we are generating ObjC bindings for them, // they should be marked as used, so that the code generator emits their deinitialization. @@ -10,3 +12,7 @@ class B { fun foo() = 2 } } + +fun enableMemoryChecker() { + Platform.isMemoryLeakCheckerActive = true +} diff --git a/kotlin-native/backend.native/tests/framework/kt42397/test.swift b/kotlin-native/backend.native/tests/framework/kt42397/test.swift index e154ca1c476..f1456a18ebc 100644 --- a/kotlin-native/backend.native/tests/framework/kt42397/test.swift +++ b/kotlin-native/backend.native/tests/framework/kt42397/test.swift @@ -7,6 +7,7 @@ class Results { func runTestKt42397(pointer: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer? { autoreleasepool { + KnlibraryKt.enableMemoryChecker() let results = pointer.bindMemory(to: Results.self, capacity: 1).pointee results.aFoo = A().foo() results.bFoo = B.Companion().foo() diff --git a/kotlin-native/backend.native/tests/interop/kt42397/knlibrary.kt b/kotlin-native/backend.native/tests/interop/kt42397/knlibrary.kt index eaefd5a1ad6..f58807bc0c1 100644 --- a/kotlin-native/backend.native/tests/interop/kt42397/knlibrary.kt +++ b/kotlin-native/backend.native/tests/interop/kt42397/knlibrary.kt @@ -1,5 +1,7 @@ package knlibrary +import kotlin.native.Platform + // The following 2 singletons are unused. However, since we are generating C bindings for them, // they should be marked as used, so that the code generator emits their deinitialization. @@ -8,3 +10,7 @@ object A {} class B { companion object {} } + +fun enableMemoryChecker() { + Platform.isMemoryLeakCheckerActive = true +} diff --git a/kotlin-native/backend.native/tests/interop/kt42397/test.cpp b/kotlin-native/backend.native/tests/interop/kt42397/test.cpp index 2bd5cc286db..983f6684961 100644 --- a/kotlin-native/backend.native/tests/interop/kt42397/test.cpp +++ b/kotlin-native/backend.native/tests/interop/kt42397/test.cpp @@ -6,6 +6,8 @@ int main() { auto t = std::thread([] { auto lib = testlib_symbols(); + lib->kotlin.root.knlibrary.enableMemoryChecker(); + // Initialize A and B.Companion and get their stable pointers. auto a = lib->kotlin.root.knlibrary.A._instance(); auto bCompanion = lib->kotlin.root.knlibrary.B.Companion._instance(); diff --git a/kotlin-native/backend.native/tests/interop/leakMemoryWithRunningThread/checked.kt b/kotlin-native/backend.native/tests/interop/leakMemoryWithRunningThread/checked.kt index 309fce99f4a..d3e429b105a 100644 --- a/kotlin-native/backend.native/tests/interop/leakMemoryWithRunningThread/checked.kt +++ b/kotlin-native/backend.native/tests/interop/leakMemoryWithRunningThread/checked.kt @@ -1,5 +1,6 @@ import leakMemory.* import kotlin.native.concurrent.* +import kotlin.native.Platform import kotlin.test.* import kotlinx.cinterop.* @@ -13,6 +14,7 @@ fun ensureInititalized() { } fun main() { + Platform.isMemoryLeakCheckerActive = true kotlin.native.internal.Debugging.forceCheckedShutdown = true assertTrue(global.value == 0) // Created a thread, made sure Kotlin is initialized there. diff --git a/kotlin-native/backend.native/tests/interop/leakMemoryWithRunningThread/unchecked.kt b/kotlin-native/backend.native/tests/interop/leakMemoryWithRunningThread/unchecked.kt index db770cabe48..ab569d77530 100644 --- a/kotlin-native/backend.native/tests/interop/leakMemoryWithRunningThread/unchecked.kt +++ b/kotlin-native/backend.native/tests/interop/leakMemoryWithRunningThread/unchecked.kt @@ -1,5 +1,6 @@ import leakMemory.* import kotlin.native.concurrent.* +import kotlin.native.Platform import kotlin.test.* import kotlinx.cinterop.* @@ -13,6 +14,7 @@ fun ensureInititalized() { } fun main() { + Platform.isMemoryLeakCheckerActive = true kotlin.native.internal.Debugging.forceCheckedShutdown = false assertTrue(global.value == 0) // Created a thread, made sure Kotlin is initialized there. diff --git a/kotlin-native/backend.native/tests/interop/memory_leaks/lib.kt b/kotlin-native/backend.native/tests/interop/memory_leaks/lib.kt index cfab7ec7202..f02b04d9368 100644 --- a/kotlin-native/backend.native/tests/interop/memory_leaks/lib.kt +++ b/kotlin-native/backend.native/tests/interop/memory_leaks/lib.kt @@ -4,6 +4,11 @@ */ import kotlinx.cinterop.* +import kotlin.native.Platform + +fun enableMemoryChecker() { + Platform.isMemoryLeakCheckerActive = true +} fun leakMemory() { StableRef.create(Any()) diff --git a/kotlin-native/backend.native/tests/interop/memory_leaks/main.cpp b/kotlin-native/backend.native/tests/interop/memory_leaks/main.cpp index ee9bbfc3613..e2fb6c8358f 100644 --- a/kotlin-native/backend.native/tests/interop/memory_leaks/main.cpp +++ b/kotlin-native/backend.native/tests/interop/memory_leaks/main.cpp @@ -9,6 +9,7 @@ int main() { std::thread t([]() { + testlib_symbols()->kotlin.root.enableMemoryChecker(); testlib_symbols()->kotlin.root.leakMemory(); }); t.join(); diff --git a/kotlin-native/backend.native/tests/interop/objc_with_initializer/objc_test.kt b/kotlin-native/backend.native/tests/interop/objc_with_initializer/objc_test.kt index fdce20d8a3f..fc7dd5e1de7 100644 --- a/kotlin-native/backend.native/tests/interop/objc_with_initializer/objc_test.kt +++ b/kotlin-native/backend.native/tests/interop/objc_with_initializer/objc_test.kt @@ -1,7 +1,9 @@ import objc_misc.* +import kotlin.native.Platform val a = B.giveC()!! as C fun main() { + Platform.isMemoryLeakCheckerActive = true println("OK") -} \ No newline at end of file +} diff --git a/kotlin-native/backend.native/tests/runtime/basic/cleaner_leak.kt b/kotlin-native/backend.native/tests/runtime/basic/cleaner_leak.kt deleted file mode 100644 index 01f2a5277a2..00000000000 --- a/kotlin-native/backend.native/tests/runtime/basic/cleaner_leak.kt +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license - * that can be found in the LICENSE file. - */ -@file:OptIn(ExperimentalStdlibApi::class) - -import kotlin.test.* - -import kotlin.native.internal.* - -// This cleaner won't be run, because it's deinitialized with globals after -// cleaners are disabled. -val globalCleaner = createCleaner(42) { - println(it) -} - -fun main() { - // Cleaner holds onto a finalization lambda. If it doesn't get executed, - // the memory will leak. Suppress memory leak checker to check for cleaners - // leak only. - Platform.isMemoryLeakCheckerActive = false - // Make sure cleaner is initialized. - assertNotNull(globalCleaner) -} diff --git a/kotlin-native/backend.native/tests/runtime/basic/cleaner_leak_with_checker.kt b/kotlin-native/backend.native/tests/runtime/basic/cleaner_leak_with_checker.kt index 053c1146d7c..b0bd8060574 100644 --- a/kotlin-native/backend.native/tests/runtime/basic/cleaner_leak_with_checker.kt +++ b/kotlin-native/backend.native/tests/runtime/basic/cleaner_leak_with_checker.kt @@ -16,10 +16,6 @@ val globalCleaner = createCleaner(42) { } fun main() { - // Cleaner holds onto a finalization lambda. If it doesn't get executed, - // the memory will leak. Suppress memory leak checker to check for cleaners - // leak only. - Platform.isMemoryLeakCheckerActive = false Platform.isCleanersLeakCheckerActive = true // Make sure cleaner is initialized. assertNotNull(globalCleaner) diff --git a/kotlin-native/backend.native/tests/runtime/basic/cleaner_leak_without_checker.kt b/kotlin-native/backend.native/tests/runtime/basic/cleaner_leak_without_checker.kt index 7391ef50de0..76eb9c1e461 100644 --- a/kotlin-native/backend.native/tests/runtime/basic/cleaner_leak_without_checker.kt +++ b/kotlin-native/backend.native/tests/runtime/basic/cleaner_leak_without_checker.kt @@ -16,11 +16,6 @@ val globalCleaner = createCleaner(42) { } fun main() { - // Cleaner holds onto a finalization lambda. If it doesn't get executed, - // the memory will leak. Suppress memory leak checker to check for cleaners - // leak only. - Platform.isMemoryLeakCheckerActive = false - Platform.isCleanersLeakCheckerActive = false // Make sure cleaner is initialized. assertNotNull(globalCleaner) } diff --git a/kotlin-native/backend.native/tests/runtime/memory/cycle_collector.kt b/kotlin-native/backend.native/tests/runtime/memory/cycle_collector.kt index 88ec23dcce7..484e560e3cb 100644 --- a/kotlin-native/backend.native/tests/runtime/memory/cycle_collector.kt +++ b/kotlin-native/backend.native/tests/runtime/memory/cycle_collector.kt @@ -1,5 +1,6 @@ import kotlin.native.concurrent.* import kotlin.native.internal.GC +import kotlin.native.Platform import kotlin.test.* fun test1() { @@ -175,6 +176,7 @@ fun test9() { } fun main() { + Platform.isMemoryLeakCheckerActive = true kotlin.native.internal.GC.cyclicCollectorEnabled = true test1() test2() @@ -187,4 +189,4 @@ fun main() { test7() test8() test9() -} \ No newline at end of file +} diff --git a/kotlin-native/backend.native/tests/runtime/memory/cycle_detector.kt b/kotlin-native/backend.native/tests/runtime/memory/cycle_detector.kt index 0f4113856e7..668c9241db3 100644 --- a/kotlin-native/backend.native/tests/runtime/memory/cycle_detector.kt +++ b/kotlin-native/backend.native/tests/runtime/memory/cycle_detector.kt @@ -1,5 +1,6 @@ import kotlin.native.concurrent.* import kotlin.native.internal.GC +import kotlin.native.Platform import kotlin.test.* class Holder(var other: Any?) @@ -32,6 +33,11 @@ fun assertArrayEquals( } } +@BeforeTest +fun enableMemoryChecker() { + Platform.isMemoryLeakCheckerActive = true +} + @Test fun noCycles() { val atomic1 = AtomicReference(null) diff --git a/kotlin-native/backend.native/tests/runtime/memory/leak_memory.kt b/kotlin-native/backend.native/tests/runtime/memory/leak_memory.kt index 487662fff28..0d6351cfaa5 100644 --- a/kotlin-native/backend.native/tests/runtime/memory/leak_memory.kt +++ b/kotlin-native/backend.native/tests/runtime/memory/leak_memory.kt @@ -1,5 +1,7 @@ import kotlinx.cinterop.* +import kotlin.native.Platform fun main() { + Platform.isMemoryLeakCheckerActive = true StableRef.create(Any()) } diff --git a/kotlin-native/backend.native/tests/runtime/memory/leak_memory_test_runner.kt b/kotlin-native/backend.native/tests/runtime/memory/leak_memory_test_runner.kt new file mode 100644 index 00000000000..5facc72141b --- /dev/null +++ b/kotlin-native/backend.native/tests/runtime/memory/leak_memory_test_runner.kt @@ -0,0 +1,14 @@ +import kotlin.test.* + +import kotlinx.cinterop.* +import kotlin.native.Platform + +@BeforeTest +fun enableMemoryChecker() { + Platform.isMemoryLeakCheckerActive = true +} + +@Test +fun test() { + StableRef.create(Any()) +} diff --git a/kotlin-native/backend.native/tests/runtime/workers/leak_memory_with_worker_termination.kt b/kotlin-native/backend.native/tests/runtime/workers/leak_memory_with_worker_termination.kt index 32a9d0a3a69..00262efbe68 100644 --- a/kotlin-native/backend.native/tests/runtime/workers/leak_memory_with_worker_termination.kt +++ b/kotlin-native/backend.native/tests/runtime/workers/leak_memory_with_worker_termination.kt @@ -1,7 +1,9 @@ import kotlin.native.concurrent.* +import kotlin.native.Platform import kotlinx.cinterop.* fun main() { + Platform.isMemoryLeakCheckerActive = true val worker = Worker.start() // Make sure worker is initialized. worker.execute(TransferMode.SAFE, {}, {}).result; diff --git a/kotlin-native/backend.native/tests/runtime/workers/leak_worker.kt b/kotlin-native/backend.native/tests/runtime/workers/leak_worker.kt index 1df5bfac135..1afd59ebb20 100644 --- a/kotlin-native/backend.native/tests/runtime/workers/leak_worker.kt +++ b/kotlin-native/backend.native/tests/runtime/workers/leak_worker.kt @@ -1,7 +1,9 @@ import kotlin.native.concurrent.* +import kotlin.native.Platform import kotlinx.cinterop.* fun main() { + Platform.isMemoryLeakCheckerActive = true val worker = Worker.start() // Make sure worker is initialized. worker.execute(TransferMode.SAFE, {}, {}).result; diff --git a/kotlin-native/backend.native/tests/runtime/workers/worker_threadlocal_no_leak.kt b/kotlin-native/backend.native/tests/runtime/workers/worker_threadlocal_no_leak.kt index 567e6d1f185..edf615d9d5a 100644 --- a/kotlin-native/backend.native/tests/runtime/workers/worker_threadlocal_no_leak.kt +++ b/kotlin-native/backend.native/tests/runtime/workers/worker_threadlocal_no_leak.kt @@ -4,11 +4,13 @@ */ import kotlin.native.concurrent.* +import kotlin.native.Platform @ThreadLocal var x = Any() fun main() { + Platform.isMemoryLeakCheckerActive = true val worker = Worker.start() worker.execute(TransferMode.SAFE, {}) { diff --git a/kotlin-native/runtime/src/main/cpp/Runtime.cpp b/kotlin-native/runtime/src/main/cpp/Runtime.cpp index 88ebcdf8e60..93d7bccf9e7 100644 --- a/kotlin-native/runtime/src/main/cpp/Runtime.cpp +++ b/kotlin-native/runtime/src/main/cpp/Runtime.cpp @@ -71,8 +71,8 @@ void InitOrDeinitGlobalVariables(int initialize, MemoryState* memory) { } } -KBoolean g_checkLeaks = KonanNeedDebugInfo; -KBoolean g_checkLeakedCleaners = KonanNeedDebugInfo; +KBoolean g_checkLeaks = false; +KBoolean g_checkLeakedCleaners = false; KBoolean g_forceCheckedShutdown = false; constexpr RuntimeState* kInvalidRuntime = nullptr; diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/test/Launcher.kt b/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/test/Launcher.kt index 5f11161fff1..22420b5141d 100644 --- a/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/test/Launcher.kt +++ b/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/test/Launcher.kt @@ -23,16 +23,21 @@ fun testLauncherEntryPoint(args: Array): Int { } fun main(args: Array) { - exitProcess(testLauncherEntryPoint(args)) + val exitCode = testLauncherEntryPoint(args) + if (exitCode != 0) { + exitProcess(exitCode) + } } fun worker(args: Array) { val worker = Worker.start() - val result = worker.execute(TransferMode.SAFE, { args.freeze() }) { + val exitCode = worker.execute(TransferMode.SAFE, { args.freeze() }) { it -> testLauncherEntryPoint(it) }.result worker.requestTermination().result - exitProcess(result) + if (exitCode != 0) { + exitProcess(exitCode) + } } fun mainNoExit(args: Array) {