Source file
test/fixedbugs/issue57823.go
1
2
3
4
5
6
7 package main
8
9 import (
10 "runtime"
11 "unsafe"
12 )
13
14
15 func g(x *byte) *byte { return x }
16
17 func main() {
18 slice()
19 str("AAAAAAAA", "BBBBBBBBB")
20 }
21
22 func wait(done <-chan struct{}) bool {
23 for i := 0; i < 10; i++ {
24 runtime.GC()
25 select {
26 case <-done:
27 return true
28 default:
29 }
30 }
31 return false
32 }
33
34 func slice() {
35 s := make([]byte, 100)
36 s[0] = 1
37 one := unsafe.SliceData(s)
38
39 done := make(chan struct{})
40 runtime.SetFinalizer(one, func(*byte) { close(done) })
41
42 h := g(one)
43
44 if wait(done) {
45 panic("GC'd early")
46 }
47
48 if *h != 1 {
49 panic("lost one")
50 }
51
52 if !wait(done) {
53 panic("never GC'd")
54 }
55 }
56
57 var strDone = make(chan struct{})
58
59
60 func str(x, y string) {
61 s := x + y
62 p := unsafe.StringData(s)
63 runtime.SetFinalizer(p, func(*byte) { close(strDone) })
64
65 if wait(strDone) {
66 panic("GC'd early")
67 }
68
69 if *p != 'A' {
70 panic("lost p")
71 }
72
73 if !wait(strDone) {
74 panic("never GC'd")
75 }
76 }
77
View as plain text