@@ -6,8 +6,11 @@ package pprof
6
6
7
7
import (
8
8
"bytes"
9
+ "fmt"
9
10
"internal/profile"
10
11
"runtime"
12
+ "slices"
13
+ "strings"
11
14
"testing"
12
15
)
13
16
@@ -82,3 +85,62 @@ func TestConvertMemProfile(t *testing.T) {
82
85
})
83
86
}
84
87
}
88
+
89
+ func genericAllocFunc [T interface { uint32 | uint64 }](n int ) []T {
90
+ return make ([]T , n )
91
+ }
92
+
93
+ func profileToString (p * profile.Profile ) []string {
94
+ var res []string
95
+ for _ , s := range p .Sample {
96
+ var funcs []string
97
+ for i := len (s .Location ) - 1 ; i >= 0 ; i -- {
98
+ loc := s .Location [i ]
99
+ for j := len (loc .Line ) - 1 ; j >= 0 ; j -- {
100
+ line := loc .Line [j ]
101
+ funcs = append (funcs , line .Function .Name )
102
+ }
103
+ }
104
+ res = append (res , fmt .Sprintf ("%s %v" , strings .Join (funcs , ";" ), s .Value ))
105
+ }
106
+ return res
107
+ }
108
+
109
+ // This is a regression test for https://go.dev/issue/64528 .
110
+ func TestGenericsHashKeyInPprofBuilder (t * testing.T ) {
111
+ previousRate := runtime .MemProfileRate
112
+ runtime .MemProfileRate = 1
113
+ defer func () {
114
+ runtime .MemProfileRate = previousRate
115
+ }()
116
+ for _ , sz := range []int {128 , 256 } {
117
+ genericAllocFunc [uint32 ](sz / 4 )
118
+ }
119
+ for _ , sz := range []int {32 , 64 } {
120
+ genericAllocFunc [uint64 ](sz / 8 )
121
+ }
122
+
123
+ runtime .GC ()
124
+ buf := bytes .NewBuffer (nil )
125
+ if err := WriteHeapProfile (buf ); err != nil {
126
+ t .Fatalf ("writing profile: %v" , err )
127
+ }
128
+ p , err := profile .Parse (buf )
129
+ if err != nil {
130
+ t .Fatalf ("profile.Parse: %v" , err )
131
+ }
132
+
133
+ actual := profileToString (p )
134
+ expected := []string {
135
+ "testing.tRunner;runtime/pprof.TestGenericsHashKeyInPprofBuilder;runtime/pprof.genericAllocFunc[go.shape.uint32] [1 128 0 0]" ,
136
+ "testing.tRunner;runtime/pprof.TestGenericsHashKeyInPprofBuilder;runtime/pprof.genericAllocFunc[go.shape.uint32] [1 256 0 0]" ,
137
+ "testing.tRunner;runtime/pprof.TestGenericsHashKeyInPprofBuilder;runtime/pprof.genericAllocFunc[go.shape.uint64] [1 32 0 0]" ,
138
+ "testing.tRunner;runtime/pprof.TestGenericsHashKeyInPprofBuilder;runtime/pprof.genericAllocFunc[go.shape.uint64] [1 64 0 0]" ,
139
+ }
140
+
141
+ for _ , l := range expected {
142
+ if ! slices .Contains (actual , l ) {
143
+ t .Errorf ("profile = %v\n want = %v" , strings .Join (actual , "\n " ), l )
144
+ }
145
+ }
146
+ }
0 commit comments