diff --git a/backport-0020-release-branch.go1.21-runtime-pprof-fix-generics-fun.patch b/backport-0020-release-branch.go1.21-runtime-pprof-fix-generics-fun.patch new file mode 100644 index 0000000000000000000000000000000000000000..fe0998db53fc39474afb8a25fc4b9f5d3b53d186 --- /dev/null +++ b/backport-0020-release-branch.go1.21-runtime-pprof-fix-generics-fun.patch @@ -0,0 +1,134 @@ +From 2e4454a248c40017e922db682f231c5a0330f4b2 Mon Sep 17 00:00:00 2001 +From: Tolya Korniltsev +Date: Mon, 4 Dec 2023 17:53:29 +0700 +Subject: [PATCH 07/20] [release-branch.go1.21] runtime/pprof: fix generics + function names + +Conflict:NA +Reference:https://go-review.googlesource.com/c/go/+/546815 + +profileBuilder is using Frame->Function as key for checking if we already +emitted a function. However for generics functions it has dots there [...], +so sometimes for different functions with different generics types, +the profileBuilder emits wrong functions. + +For #64528 +For #64609 + +Change-Id: I8b39245e0b18f4288ce758c912c6748f87cba39a +Reviewed-on: https://go-review.googlesource.com/c/go/+/546815 +Reviewed-by: Cherry Mui +LUCI-TryBot-Result: Go LUCI +Reviewed-by: Michael Pratt +(cherry picked from commit 20a03fc7130d8d99b513071c7e413b436ea649a2) +Reviewed-on: https://go-review.googlesource.com/c/go/+/549535 +Auto-Submit: Matthew Dempsky +--- + src/runtime/pprof/proto.go | 7 ++-- + src/runtime/pprof/protomem_test.go | 62 ++++++++++++++++++++++++++++++ + 2 files changed, 66 insertions(+), 3 deletions(-) + +diff --git a/src/runtime/pprof/proto.go b/src/runtime/pprof/proto.go +index cdc4bd7c80d8..db9384eb214e 100644 +--- a/src/runtime/pprof/proto.go ++++ b/src/runtime/pprof/proto.go +@@ -611,13 +611,14 @@ func (b *profileBuilder) emitLocation() uint64 { + b.pb.uint64Opt(tagLocation_Address, uint64(firstFrame.PC)) + for _, frame := range b.deck.frames { + // Write out each line in frame expansion. +- funcID := uint64(b.funcs[frame.Function]) ++ funcName := runtime_FrameSymbolName(&frame) ++ funcID := uint64(b.funcs[funcName]) + if funcID == 0 { + funcID = uint64(len(b.funcs)) + 1 +- b.funcs[frame.Function] = int(funcID) ++ b.funcs[funcName] = int(funcID) + newFuncs = append(newFuncs, newFunc{ + id: funcID, +- name: runtime_FrameSymbolName(&frame), ++ name: funcName, + file: frame.File, + startLine: int64(runtime_FrameStartLine(&frame)), + }) +diff --git a/src/runtime/pprof/protomem_test.go b/src/runtime/pprof/protomem_test.go +index 156f6286a92f..505c323d6867 100644 +--- a/src/runtime/pprof/protomem_test.go ++++ b/src/runtime/pprof/protomem_test.go +@@ -6,8 +6,11 @@ package pprof + + import ( + "bytes" ++ "fmt" + "internal/profile" + "runtime" ++ "slices" ++ "strings" + "testing" + ) + +@@ -82,3 +85,62 @@ func TestConvertMemProfile(t *testing.T) { + }) + } + } ++ ++func genericAllocFunc[T interface{ uint32 | uint64 }](n int) []T { ++ return make([]T, n) ++} ++ ++func profileToString(p *profile.Profile) []string { ++ var res []string ++ for _, s := range p.Sample { ++ var funcs []string ++ for i := len(s.Location) - 1; i >= 0; i-- { ++ loc := s.Location[i] ++ for j := len(loc.Line) - 1; j >= 0; j-- { ++ line := loc.Line[j] ++ funcs = append(funcs, line.Function.Name) ++ } ++ } ++ res = append(res, fmt.Sprintf("%s %v", strings.Join(funcs, ";"), s.Value)) ++ } ++ return res ++} ++ ++// This is a regression test for https://go.dev/issue/64528 . ++func TestGenericsHashKeyInPprofBuilder(t *testing.T) { ++ previousRate := runtime.MemProfileRate ++ runtime.MemProfileRate = 1 ++ defer func() { ++ runtime.MemProfileRate = previousRate ++ }() ++ for _, sz := range []int{128, 256} { ++ genericAllocFunc[uint32](sz / 4) ++ } ++ for _, sz := range []int{32, 64} { ++ genericAllocFunc[uint64](sz / 8) ++ } ++ ++ runtime.GC() ++ buf := bytes.NewBuffer(nil) ++ if err := WriteHeapProfile(buf); err != nil { ++ t.Fatalf("writing profile: %v", err) ++ } ++ p, err := profile.Parse(buf) ++ if err != nil { ++ t.Fatalf("profile.Parse: %v", err) ++ } ++ ++ actual := profileToString(p) ++ expected := []string{ ++ "testing.tRunner;runtime/pprof.TestGenericsHashKeyInPprofBuilder;runtime/pprof.genericAllocFunc[go.shape.uint32] [1 128 0 0]", ++ "testing.tRunner;runtime/pprof.TestGenericsHashKeyInPprofBuilder;runtime/pprof.genericAllocFunc[go.shape.uint32] [1 256 0 0]", ++ "testing.tRunner;runtime/pprof.TestGenericsHashKeyInPprofBuilder;runtime/pprof.genericAllocFunc[go.shape.uint64] [1 32 0 0]", ++ "testing.tRunner;runtime/pprof.TestGenericsHashKeyInPprofBuilder;runtime/pprof.genericAllocFunc[go.shape.uint64] [1 64 0 0]", ++ } ++ ++ for _, l := range expected { ++ if !slices.Contains(actual, l) { ++ t.Errorf("profile = %v\nwant = %v", strings.Join(actual, "\n"), l) ++ } ++ } ++} +-- +2.33.0 + diff --git a/golang.spec b/golang.spec index e05fc7ee5d391f395a96f5745b29a917b62de7ac..31f470823d691a72ff159da4d33f8335825111c5 100644 --- a/golang.spec +++ b/golang.spec @@ -66,7 +66,7 @@ Name: golang Version: 1.21.4 -Release: 21 +Release: 22 Summary: The Go Programming Language License: BSD and Public Domain URL: https://golang.org/ @@ -139,6 +139,7 @@ Patch6016: backport-0016-release-branch.go1.21-internal-poll-add-SPLICE_F_NON.pa Patch6017: backport-0017-release-branch.go1.21-runtime-call-enableMetadataHug.patch Patch6018: backport-0018-release-branch.go1.21-cmd-compile-fix-findIndVar-so-.patch Patch6019: backport-0019-release-branch.go1.21-cmd-compile-fix-escape-analysi.patch +Patch6020: backport-0020-release-branch.go1.21-runtime-pprof-fix-generics-fun.patch ExclusiveArch: %{golang_arches} @@ -378,6 +379,9 @@ fi %files devel -f go-tests.list -f go-misc.list -f go-src.list %changelog +* Wed Oct 09 2024 EulerOSWander <314264452@qq.com> - 1.21.4-22 +- runtime/pprof:fix generics function names + * Thu Sep 19 2024 Vanient - 1.21.4-21 - cmd/compile: fix escape analysis of string min/max