diff options
Diffstat (limited to 'src/runtime/testdata')
| -rw-r--r-- | src/runtime/testdata/testprog/checkfinalizers.go | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/src/runtime/testdata/testprog/checkfinalizers.go b/src/runtime/testdata/testprog/checkfinalizers.go new file mode 100644 index 0000000000..ef0108a7e0 --- /dev/null +++ b/src/runtime/testdata/testprog/checkfinalizers.go @@ -0,0 +1,50 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "runtime" +) + +func init() { + register("DetectFinalizerAndCleanupLeaks", DetectFinalizerAndCleanupLeaks) +} + +// Intended to be run only with `GODEBUG=checkfinalizers=1`. +func DetectFinalizerAndCleanupLeaks() { + type T *int + + // Leak a cleanup. + cLeak := new(T) + runtime.AddCleanup(cLeak, func(x int) { + **cLeak = x + }, int(0)) + + // Have a regular cleanup to make sure it doesn't trip the detector. + cNoLeak := new(T) + runtime.AddCleanup(cNoLeak, func(_ int) {}, int(0)) + + // Leak a finalizer. + fLeak := new(T) + runtime.SetFinalizer(fLeak, func(_ *T) { + **fLeak = 12 + }) + + // Have a regular finalizer to make sure it doesn't trip the detector. + fNoLeak := new(T) + runtime.SetFinalizer(fNoLeak, func(x *T) { + **x = 51 + }) + + // runtime.GC here should crash. + runtime.GC() + println("OK") + + // Keep everything alive. + runtime.KeepAlive(cLeak) + runtime.KeepAlive(cNoLeak) + runtime.KeepAlive(fLeak) + runtime.KeepAlive(fNoLeak) +} |
