Disable running checkers by default (#4644)

* Make checkers be disabled by default

* Allow running checkers in test launcher
This commit is contained in:
Alexander Shabalin
2021-01-22 12:23:53 +03:00
committed by Nikolay Krasko
parent 71f44dce0f
commit 77e2b9f9a0
22 changed files with 82 additions and 76 deletions
+13 -36
View File
@@ -783,9 +783,7 @@ task array_to_any(type: KonanLocalTest) {
} }
standaloneTest("runtime_basic_init") { standaloneTest("runtime_basic_init") {
disabled = (project.testTarget == 'wasm32') // -g not yet properly works for WASM.
source = "runtime/basic/init.kt" source = "runtime/basic/init.kt"
flags = ['-g']
expectedExitStatus = 0 expectedExitStatus = 0
} }
@@ -941,20 +939,6 @@ standaloneTest("cleaner_in_main_without_checker") {
goldValue = "" 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") { standaloneTest("cleaner_leak_without_checker") {
enabled = (project.testTarget != 'wasm32') // Cleaners need workers enabled = (project.testTarget != 'wasm32') // Cleaners need workers
source = "runtime/basic/cleaner_leak_without_checker.kt" source = "runtime/basic/cleaner_leak_without_checker.kt"
@@ -1066,9 +1050,8 @@ task worker11(type: KonanLocalTest) {
} }
standaloneTest("worker_threadlocal_no_leak") { 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" source = "runtime/workers/worker_threadlocal_no_leak.kt"
flags = ['-g']
} }
task freeze0(type: KonanLocalTest) { task freeze0(type: KonanLocalTest) {
@@ -1168,17 +1151,15 @@ task enumIdentity(type: KonanLocalTest) {
} }
standaloneTest("leakWorker") { 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" source = "runtime/workers/leak_worker.kt"
flags = ['-g']
expectedExitStatusChecker = { it != 0 } expectedExitStatusChecker = { it != 0 }
outputChecker = { s -> s.contains("Unfinished workers detected, 1 workers leaked!") } outputChecker = { s -> s.contains("Unfinished workers detected, 1 workers leaked!") }
} }
standaloneTest("leakMemoryWithWorkerTermination") { 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" source = "runtime/workers/leak_memory_with_worker_termination.kt"
flags = ['-g']
expectedExitStatusChecker = { it != 0 } expectedExitStatusChecker = { it != 0 }
outputChecker = { s -> s.contains("Memory leaks detected, 1 objects leaked!") } outputChecker = { s -> s.contains("Memory leaks detected, 1 objects leaked!") }
} }
@@ -2965,7 +2946,6 @@ standaloneTest("cycle_detector") {
standaloneTest("cycle_collector") { standaloneTest("cycle_collector") {
disabled = true // Needs USE_CYCLIC_GC, which is disabled. disabled = true // Needs USE_CYCLIC_GC, which is disabled.
flags = ['-g']
source = "runtime/memory/cycle_collector.kt" source = "runtime/memory/cycle_collector.kt"
} }
@@ -2975,9 +2955,14 @@ standaloneTest("cycle_collector_deadlock1") {
} }
standaloneTest("leakMemory") { standaloneTest("leakMemory") {
disabled = project.globalTestArgs.contains('-opt') || (project.testTarget == 'wasm32') // Needs debug build.
source = "runtime/memory/leak_memory.kt" 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 } expectedExitStatusChecker = { it != 0 }
outputChecker = { s -> s.contains("Memory leaks detected, 1 objects leaked!") } outputChecker = { s -> s.contains("Memory leaks detected, 1 objects leaked!") }
} }
@@ -4084,17 +4069,13 @@ interopTest("interop_kt43265") {
} }
interopTest("interop_leakMemoryWithRunningThreadUnchecked") { interopTest("interop_leakMemoryWithRunningThreadUnchecked") {
disabled = project.globalTestArgs.contains('-opt') || (project.testTarget == 'wasm32') // Needs debug build.
interop = 'leakMemoryWithRunningThread' interop = 'leakMemoryWithRunningThread'
source = "interop/leakMemoryWithRunningThread/unchecked.kt" source = "interop/leakMemoryWithRunningThread/unchecked.kt"
flags = ['-g']
} }
interopTest("interop_leakMemoryWithRunningThreadChecked") { interopTest("interop_leakMemoryWithRunningThreadChecked") {
disabled = project.globalTestArgs.contains('-opt') || (project.testTarget == 'wasm32') // Needs debug build.
interop = 'leakMemoryWithRunningThread' interop = 'leakMemoryWithRunningThread'
source = "interop/leakMemoryWithRunningThread/checked.kt" source = "interop/leakMemoryWithRunningThread/checked.kt"
flags = ['-g']
expectedExitStatusChecker = { it != 0 } expectedExitStatusChecker = { it != 0 }
outputChecker = { s -> s.contains("Cannot run checkers when there are 1 alive runtimes at the shutdown") } 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" goldValue = "OK\n"
source = "interop/objc_with_initializer/objc_test.kt" source = "interop/objc_with_initializer/objc_test.kt"
interop = 'objcMisc' interop = 'objcMisc'
flags = ['-g']
doBeforeBuild { doBeforeBuild {
mkdir(buildDir) mkdir(buildDir)
@@ -4395,11 +4375,10 @@ dynamicTest("interop_concurrentRuntime") {
} }
dynamicTest("interop_kt42397") { dynamicTest("interop_kt42397") {
disabled = project.target.name != project.hostName || project.globalTestArgs.contains('-opt') disabled = project.target.name != project.hostName
source = "interop/kt42397/knlibrary.kt" source = "interop/kt42397/knlibrary.kt"
cSource = "$projectDir/interop/kt42397/test.cpp" cSource = "$projectDir/interop/kt42397/test.cpp"
clangTool = "clang++" clangTool = "clang++"
flags = ['-g']
} }
dynamicTest("interop_cleaners_main_thread") { dynamicTest("interop_cleaners_main_thread") {
@@ -4447,12 +4426,11 @@ dynamicTest("interop_migrating_main_thread") {
} }
dynamicTest("interop_memory_leaks") { dynamicTest("interop_memory_leaks") {
disabled = (project.target.name != project.hostName) || disabled = (project.target.name != project.hostName)
project.globalTestArgs.contains('-opt') || (project.testTarget == 'wasm32') // Needs debug build.
source = "interop/memory_leaks/lib.kt" source = "interop/memory_leaks/lib.kt"
cSource = "$projectDir/interop/memory_leaks/main.cpp" cSource = "$projectDir/interop/memory_leaks/main.cpp"
clangTool = "clang++" 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 } expectedExitStatusChecker = { it != 0 }
outputChecker = { s -> s.contains("Memory leaks detected, 1 objects leaked!") } outputChecker = { s -> s.contains("Memory leaks detected, 1 objects leaked!") }
} }
@@ -4732,7 +4710,6 @@ if (isAppleTarget(project)) {
enabled = !project.globalTestArgs.contains('-opt') enabled = !project.globalTestArgs.contains('-opt')
framework("Kt42397") { framework("Kt42397") {
sources = ['framework/kt42397'] sources = ['framework/kt42397']
opts = ['-g']
} }
swiftSources = ['framework/kt42397'] swiftSources = ['framework/kt42397']
} }
@@ -1,3 +1,5 @@
import kotlin.native.Platform
// The following 2 singletons are unused. However, since we are generating ObjC bindings for them, // 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. // they should be marked as used, so that the code generator emits their deinitialization.
@@ -10,3 +12,7 @@ class B {
fun foo() = 2 fun foo() = 2
} }
} }
fun enableMemoryChecker() {
Platform.isMemoryLeakCheckerActive = true
}
@@ -7,6 +7,7 @@ class Results {
func runTestKt42397(pointer: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer? { func runTestKt42397(pointer: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer? {
autoreleasepool { autoreleasepool {
KnlibraryKt.enableMemoryChecker()
let results = pointer.bindMemory(to: Results.self, capacity: 1).pointee let results = pointer.bindMemory(to: Results.self, capacity: 1).pointee
results.aFoo = A().foo() results.aFoo = A().foo()
results.bFoo = B.Companion().foo() results.bFoo = B.Companion().foo()
@@ -1,5 +1,7 @@
package knlibrary package knlibrary
import kotlin.native.Platform
// The following 2 singletons are unused. However, since we are generating C bindings for them, // 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. // they should be marked as used, so that the code generator emits their deinitialization.
@@ -8,3 +10,7 @@ object A {}
class B { class B {
companion object {} companion object {}
} }
fun enableMemoryChecker() {
Platform.isMemoryLeakCheckerActive = true
}
@@ -6,6 +6,8 @@ int main() {
auto t = std::thread([] { auto t = std::thread([] {
auto lib = testlib_symbols(); auto lib = testlib_symbols();
lib->kotlin.root.knlibrary.enableMemoryChecker();
// Initialize A and B.Companion and get their stable pointers. // Initialize A and B.Companion and get their stable pointers.
auto a = lib->kotlin.root.knlibrary.A._instance(); auto a = lib->kotlin.root.knlibrary.A._instance();
auto bCompanion = lib->kotlin.root.knlibrary.B.Companion._instance(); auto bCompanion = lib->kotlin.root.knlibrary.B.Companion._instance();
@@ -1,5 +1,6 @@
import leakMemory.* import leakMemory.*
import kotlin.native.concurrent.* import kotlin.native.concurrent.*
import kotlin.native.Platform
import kotlin.test.* import kotlin.test.*
import kotlinx.cinterop.* import kotlinx.cinterop.*
@@ -13,6 +14,7 @@ fun ensureInititalized() {
} }
fun main() { fun main() {
Platform.isMemoryLeakCheckerActive = true
kotlin.native.internal.Debugging.forceCheckedShutdown = true kotlin.native.internal.Debugging.forceCheckedShutdown = true
assertTrue(global.value == 0) assertTrue(global.value == 0)
// Created a thread, made sure Kotlin is initialized there. // Created a thread, made sure Kotlin is initialized there.
@@ -1,5 +1,6 @@
import leakMemory.* import leakMemory.*
import kotlin.native.concurrent.* import kotlin.native.concurrent.*
import kotlin.native.Platform
import kotlin.test.* import kotlin.test.*
import kotlinx.cinterop.* import kotlinx.cinterop.*
@@ -13,6 +14,7 @@ fun ensureInititalized() {
} }
fun main() { fun main() {
Platform.isMemoryLeakCheckerActive = true
kotlin.native.internal.Debugging.forceCheckedShutdown = false kotlin.native.internal.Debugging.forceCheckedShutdown = false
assertTrue(global.value == 0) assertTrue(global.value == 0)
// Created a thread, made sure Kotlin is initialized there. // Created a thread, made sure Kotlin is initialized there.
@@ -4,6 +4,11 @@
*/ */
import kotlinx.cinterop.* import kotlinx.cinterop.*
import kotlin.native.Platform
fun enableMemoryChecker() {
Platform.isMemoryLeakCheckerActive = true
}
fun leakMemory() { fun leakMemory() {
StableRef.create(Any()) StableRef.create(Any())
@@ -9,6 +9,7 @@
int main() { int main() {
std::thread t([]() { std::thread t([]() {
testlib_symbols()->kotlin.root.enableMemoryChecker();
testlib_symbols()->kotlin.root.leakMemory(); testlib_symbols()->kotlin.root.leakMemory();
}); });
t.join(); t.join();
@@ -1,7 +1,9 @@
import objc_misc.* import objc_misc.*
import kotlin.native.Platform
val a = B.giveC()!! as C val a = B.giveC()!! as C
fun main() { fun main() {
Platform.isMemoryLeakCheckerActive = true
println("OK") println("OK")
} }
@@ -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)
}
@@ -16,10 +16,6 @@ val globalCleaner = createCleaner(42) {
} }
fun main() { 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 Platform.isCleanersLeakCheckerActive = true
// Make sure cleaner is initialized. // Make sure cleaner is initialized.
assertNotNull(globalCleaner) assertNotNull(globalCleaner)
@@ -16,11 +16,6 @@ val globalCleaner = createCleaner(42) {
} }
fun main() { 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. // Make sure cleaner is initialized.
assertNotNull(globalCleaner) assertNotNull(globalCleaner)
} }
@@ -1,5 +1,6 @@
import kotlin.native.concurrent.* import kotlin.native.concurrent.*
import kotlin.native.internal.GC import kotlin.native.internal.GC
import kotlin.native.Platform
import kotlin.test.* import kotlin.test.*
fun test1() { fun test1() {
@@ -175,6 +176,7 @@ fun test9() {
} }
fun main() { fun main() {
Platform.isMemoryLeakCheckerActive = true
kotlin.native.internal.GC.cyclicCollectorEnabled = true kotlin.native.internal.GC.cyclicCollectorEnabled = true
test1() test1()
test2() test2()
@@ -187,4 +189,4 @@ fun main() {
test7() test7()
test8() test8()
test9() test9()
} }
@@ -1,5 +1,6 @@
import kotlin.native.concurrent.* import kotlin.native.concurrent.*
import kotlin.native.internal.GC import kotlin.native.internal.GC
import kotlin.native.Platform
import kotlin.test.* import kotlin.test.*
class Holder(var other: Any?) class Holder(var other: Any?)
@@ -32,6 +33,11 @@ fun assertArrayEquals(
} }
} }
@BeforeTest
fun enableMemoryChecker() {
Platform.isMemoryLeakCheckerActive = true
}
@Test @Test
fun noCycles() { fun noCycles() {
val atomic1 = AtomicReference<Any?>(null) val atomic1 = AtomicReference<Any?>(null)
@@ -1,5 +1,7 @@
import kotlinx.cinterop.* import kotlinx.cinterop.*
import kotlin.native.Platform
fun main() { fun main() {
Platform.isMemoryLeakCheckerActive = true
StableRef.create(Any()) StableRef.create(Any())
} }
@@ -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())
}
@@ -1,7 +1,9 @@
import kotlin.native.concurrent.* import kotlin.native.concurrent.*
import kotlin.native.Platform
import kotlinx.cinterop.* import kotlinx.cinterop.*
fun main() { fun main() {
Platform.isMemoryLeakCheckerActive = true
val worker = Worker.start() val worker = Worker.start()
// Make sure worker is initialized. // Make sure worker is initialized.
worker.execute(TransferMode.SAFE, {}, {}).result; worker.execute(TransferMode.SAFE, {}, {}).result;
@@ -1,7 +1,9 @@
import kotlin.native.concurrent.* import kotlin.native.concurrent.*
import kotlin.native.Platform
import kotlinx.cinterop.* import kotlinx.cinterop.*
fun main() { fun main() {
Platform.isMemoryLeakCheckerActive = true
val worker = Worker.start() val worker = Worker.start()
// Make sure worker is initialized. // Make sure worker is initialized.
worker.execute(TransferMode.SAFE, {}, {}).result; worker.execute(TransferMode.SAFE, {}, {}).result;
@@ -4,11 +4,13 @@
*/ */
import kotlin.native.concurrent.* import kotlin.native.concurrent.*
import kotlin.native.Platform
@ThreadLocal @ThreadLocal
var x = Any() var x = Any()
fun main() { fun main() {
Platform.isMemoryLeakCheckerActive = true
val worker = Worker.start() val worker = Worker.start()
worker.execute(TransferMode.SAFE, {}) { worker.execute(TransferMode.SAFE, {}) {
@@ -71,8 +71,8 @@ void InitOrDeinitGlobalVariables(int initialize, MemoryState* memory) {
} }
} }
KBoolean g_checkLeaks = KonanNeedDebugInfo; KBoolean g_checkLeaks = false;
KBoolean g_checkLeakedCleaners = KonanNeedDebugInfo; KBoolean g_checkLeakedCleaners = false;
KBoolean g_forceCheckedShutdown = false; KBoolean g_forceCheckedShutdown = false;
constexpr RuntimeState* kInvalidRuntime = nullptr; constexpr RuntimeState* kInvalidRuntime = nullptr;
@@ -23,16 +23,21 @@ fun testLauncherEntryPoint(args: Array<String>): Int {
} }
fun main(args: Array<String>) { fun main(args: Array<String>) {
exitProcess(testLauncherEntryPoint(args)) val exitCode = testLauncherEntryPoint(args)
if (exitCode != 0) {
exitProcess(exitCode)
}
} }
fun worker(args: Array<String>) { fun worker(args: Array<String>) {
val worker = Worker.start() val worker = Worker.start()
val result = worker.execute(TransferMode.SAFE, { args.freeze() }) { val exitCode = worker.execute(TransferMode.SAFE, { args.freeze() }) {
it -> testLauncherEntryPoint(it) it -> testLauncherEntryPoint(it)
}.result }.result
worker.requestTermination().result worker.requestTermination().result
exitProcess(result) if (exitCode != 0) {
exitProcess(exitCode)
}
} }
fun mainNoExit(args: Array<String>) { fun mainNoExit(args: Array<String>) {