Source file
src/runtime/abi_test.go
1
2
3
4
5
6
7
8
9
10 package runtime_test
11
12 import (
13 "internal/abi"
14 "internal/testenv"
15 "os"
16 "os/exec"
17 "runtime"
18 "strings"
19 "testing"
20 "time"
21 )
22
23 var regConfirmRun chan int
24
25
26 func regFinalizerPointer(v *Tint) (int, float32, [10]byte) {
27 regConfirmRun <- *(*int)(v)
28 return 5151, 4.0, [10]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
29 }
30
31
32 func regFinalizerIface(v Tinter) (int, float32, [10]byte) {
33 regConfirmRun <- *(*int)(v.(*Tint))
34 return 5151, 4.0, [10]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
35 }
36
37 func TestFinalizerRegisterABI(t *testing.T) {
38 testenv.MustHaveExec(t)
39
40
41
42 if os.Getenv("TEST_FINALIZER_REGABI") != "1" {
43 cmd := testenv.CleanCmdEnv(exec.Command(os.Args[0], "-test.run=TestFinalizerRegisterABI", "-test.v"))
44 cmd.Env = append(cmd.Env, "TEST_FINALIZER_REGABI=1")
45 out, err := cmd.CombinedOutput()
46 if !strings.Contains(string(out), "PASS\n") || err != nil {
47 t.Fatalf("%s\n(exit status %v)", string(out), err)
48 }
49 return
50 }
51
52
53
54
55
56
57
58
59 runtime.GC()
60 runtime.GC()
61
62
63
64 success := false
65 for i := 0; i < 100; i++ {
66 if runtime.FinalizerGAsleep() {
67 success = true
68 break
69 }
70 time.Sleep(20 * time.Millisecond)
71 }
72 if !success {
73 t.Fatal("finalizer not asleep?")
74 }
75
76 argRegsBefore := runtime.SetIntArgRegs(abi.IntArgRegs)
77 defer runtime.SetIntArgRegs(argRegsBefore)
78
79 tests := []struct {
80 name string
81 fin any
82 confirmValue int
83 }{
84 {"Pointer", regFinalizerPointer, -1},
85 {"Interface", regFinalizerIface, -2},
86 }
87 for i := range tests {
88 test := &tests[i]
89 t.Run(test.name, func(t *testing.T) {
90 regConfirmRun = make(chan int)
91
92 x := new(Tint)
93 *x = (Tint)(test.confirmValue)
94 runtime.SetFinalizer(x, test.fin)
95
96 runtime.KeepAlive(x)
97
98
99 runtime.GC()
100 runtime.GC()
101
102 select {
103 case <-time.After(time.Second):
104 t.Fatal("finalizer failed to execute")
105 case gotVal := <-regConfirmRun:
106 if gotVal != test.confirmValue {
107 t.Fatalf("wrong finalizer executed? got %d, want %d", gotVal, test.confirmValue)
108 }
109 }
110 })
111 }
112 }
113
View as plain text