From 7e5804cb7014bf3154542a3d2afc68c3a61b7452 Mon Sep 17 00:00:00 2001 From: Heschi Kreinick Date: Wed, 16 Mar 2022 18:17:58 -0400 Subject: [PATCH] cmd: update vendored pprof go get github.com/google/pprof@latest go mod vendor Plus a tiny change to the pprof command to match an upstream interface change. Updates #36905. Change-Id: I4c7bbe8c317a6eeb217fce971b208f96ab0727fa Reviewed-on: https://go-review.googlesource.com/c/go/+/393370 Trust: Heschi Kreinick Run-TryBot: Heschi Kreinick Auto-Submit: Heschi Kreinick TryBot-Result: Gopher Robot Reviewed-by: Heschi Kreinick Reviewed-by: Dmitri Shuralyov Reviewed-by: Cherry Mui --- src/cmd/go.mod | 2 +- src/cmd/go.sum | 4 +- src/cmd/pprof/pprof.go | 2 +- .../github.com/google/pprof/driver/driver.go | 10 +- .../pprof/internal/binutils/binutils.go | 38 +- .../google/pprof/internal/driver/cli.go | 2 +- .../google/pprof/internal/driver/fetch.go | 6 +- .../google/pprof/internal/driver/webhtml.go | 21 +- .../google/pprof/internal/elfexec/elfexec.go | 6 +- .../google/pprof/internal/graph/dotgraph.go | 4 +- .../google/pprof/internal/plugin/plugin.go | 6 +- .../google/pprof/internal/report/report.go | 2 +- .../google/pprof/internal/report/source.go | 2 +- .../pprof/internal/symbolizer/symbolizer.go | 5 +- .../github.com/google/pprof/profile/encode.go | 9 + .../github.com/google/pprof/profile/merge.go | 21 +- .../google/pprof/profile/profile.go | 9 + .../google/pprof/third_party/d3/LICENSE | 27 - .../google/pprof/third_party/d3/README.md | 119 - .../google/pprof/third_party/d3/d3.go | 4675 ----------------- .../{LICENSE => D3_FLAME_GRAPH_LICENSE} | 0 .../pprof/third_party/d3flamegraph/D3_LICENSE | 13 + .../pprof/third_party/d3flamegraph/README.md | 33 + .../d3flamegraph/d3_flame_graph.go | 976 +--- .../pprof/third_party/d3flamegraph/index.js | 13 + .../d3flamegraph/package-lock.json | 1106 ++++ .../third_party/d3flamegraph/package.json | 17 + .../pprof/third_party/d3flamegraph/update.sh | 62 + .../d3flamegraph/webpack.config.js | 13 + src/cmd/vendor/modules.txt | 3 +- 30 files changed, 1361 insertions(+), 5845 deletions(-) delete mode 100644 src/cmd/vendor/github.com/google/pprof/third_party/d3/LICENSE delete mode 100644 src/cmd/vendor/github.com/google/pprof/third_party/d3/README.md delete mode 100644 src/cmd/vendor/github.com/google/pprof/third_party/d3/d3.go rename src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/{LICENSE => D3_FLAME_GRAPH_LICENSE} (100%) create mode 100644 src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/D3_LICENSE create mode 100644 src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/README.md create mode 100644 src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/index.js create mode 100644 src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/package-lock.json create mode 100644 src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/package.json create mode 100644 src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/update.sh create mode 100644 src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/webpack.config.js diff --git a/src/cmd/go.mod b/src/cmd/go.mod index ce1a32f386..c99cb8cdb3 100644 --- a/src/cmd/go.mod +++ b/src/cmd/go.mod @@ -3,7 +3,7 @@ module cmd go 1.19 require ( - github.com/google/pprof v0.0.0-20211104044539-f987b9c94b31 + github.com/google/pprof v0.0.0-20220314021825-5bba342933ea golang.org/x/arch v0.0.0-20210923205945-b76863e36670 golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c diff --git a/src/cmd/go.sum b/src/cmd/go.sum index b4a800b07e..39d9e109ad 100644 --- a/src/cmd/go.sum +++ b/src/cmd/go.sum @@ -1,8 +1,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/google/pprof v0.0.0-20211104044539-f987b9c94b31 h1:YvpxjnjGhf/vDEeYOysNbsrtB///PKS8lqkFNSDm1p8= -github.com/google/pprof v0.0.0-20211104044539-f987b9c94b31/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg= +github.com/google/pprof v0.0.0-20220314021825-5bba342933ea h1:yVDp4C9ff/qoEAhHNf5cqk/YTxTGECSzGYzahdhEKBI= +github.com/google/pprof v0.0.0-20220314021825-5bba342933ea/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg= github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d h1:uGg2frlt3IcT7kbV6LEp5ONv4vmoO2FW4qSO+my/aoM= github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU= diff --git a/src/cmd/pprof/pprof.go b/src/cmd/pprof/pprof.go index e72c765adc..c073c964b4 100644 --- a/src/cmd/pprof/pprof.go +++ b/src/cmd/pprof/pprof.go @@ -149,7 +149,7 @@ type objTool struct { disasmCache map[string]*objfile.Disasm } -func (*objTool) Open(name string, start, limit, offset uint64) (driver.ObjFile, error) { +func (*objTool) Open(name string, start, limit, offset uint64, relocationSymbol string) (driver.ObjFile, error) { of, err := objfile.Open(name) if err != nil { return nil, err diff --git a/src/cmd/vendor/github.com/google/pprof/driver/driver.go b/src/cmd/vendor/github.com/google/pprof/driver/driver.go index fc05f919ba..5a8222f70a 100644 --- a/src/cmd/vendor/github.com/google/pprof/driver/driver.go +++ b/src/cmd/vendor/github.com/google/pprof/driver/driver.go @@ -137,8 +137,10 @@ type MappingSources map[string][]struct { type ObjTool interface { // Open opens the named object file. If the object is a shared // library, start/limit/offset are the addresses where it is mapped - // into memory in the address space being inspected. - Open(file string, start, limit, offset uint64) (ObjFile, error) + // into memory in the address space being inspected. If the object + // is a linux kernel, relocationSymbol is the name of the symbol + // corresponding to the start address. + Open(file string, start, limit, offset uint64, relocationSymbol string) (ObjFile, error) // Disasm disassembles the named object file, starting at // the start address and stopping at (before) the end address. @@ -232,8 +234,8 @@ type internalObjTool struct { ObjTool } -func (o *internalObjTool) Open(file string, start, limit, offset uint64) (plugin.ObjFile, error) { - f, err := o.ObjTool.Open(file, start, limit, offset) +func (o *internalObjTool) Open(file string, start, limit, offset uint64, relocationSymbol string) (plugin.ObjFile, error) { + f, err := o.ObjTool.Open(file, start, limit, offset, relocationSymbol) if err != nil { return nil, err } diff --git a/src/cmd/vendor/github.com/google/pprof/internal/binutils/binutils.go b/src/cmd/vendor/github.com/google/pprof/internal/binutils/binutils.go index e920eeb2fa..efa9167af7 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/binutils/binutils.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/binutils/binutils.go @@ -284,7 +284,7 @@ func (bu *Binutils) Disasm(file string, start, end uint64, intelSyntax bool) ([] } // Open satisfies the plugin.ObjTool interface. -func (bu *Binutils) Open(name string, start, limit, offset uint64) (plugin.ObjFile, error) { +func (bu *Binutils) Open(name string, start, limit, offset uint64, relocationSymbol string) (plugin.ObjFile, error) { b := bu.get() // Make sure file is a supported executable. @@ -316,7 +316,7 @@ func (bu *Binutils) Open(name string, start, limit, offset uint64) (plugin.ObjFi // Match against supported file types. if elfMagic == elf.ELFMAG { - f, err := b.openELF(name, start, limit, offset) + f, err := b.openELF(name, start, limit, offset, relocationSymbol) if err != nil { return nil, fmt.Errorf("error reading ELF file %s: %v", name, err) } @@ -425,7 +425,7 @@ func (b *binrep) openMachO(name string, start, limit, offset uint64) (plugin.Obj return b.openMachOCommon(name, of, start, limit, offset) } -func (b *binrep) openELF(name string, start, limit, offset uint64) (plugin.ObjFile, error) { +func (b *binrep) openELF(name string, start, limit, offset uint64, relocationSymbol string) (plugin.ObjFile, error) { ef, err := elfOpen(name) if err != nil { return nil, fmt.Errorf("error parsing %s: %v", name, err) @@ -440,8 +440,8 @@ func (b *binrep) openELF(name string, start, limit, offset uint64) (plugin.ObjFi } var ( - stextOffset *uint64 - pageAligned = func(addr uint64) bool { return addr%4096 == 0 } + kernelOffset *uint64 + pageAligned = func(addr uint64) bool { return addr%4096 == 0 } ) if strings.Contains(name, "vmlinux") || !pageAligned(start) || !pageAligned(limit) || !pageAligned(offset) { // Reading all Symbols is expensive, and we only rarely need it so @@ -455,10 +455,18 @@ func (b *binrep) openELF(name string, start, limit, offset uint64) (plugin.ObjFi if err != nil && err != elf.ErrNoSymbols { return nil, err } + + // The kernel relocation symbol (the mapping start address) can be either + // _text or _stext. When profiles are generated by `perf`, which one was used is + // distinguished by the mapping name for the kernel image: + // '[kernel.kallsyms]_text' or '[kernel.kallsyms]_stext', respectively. If we haven't + // been able to parse it from the mapping, we default to _stext. + if relocationSymbol == "" { + relocationSymbol = "_stext" + } for _, s := range symbols { - if s.Name == "_stext" { - // The kernel may use _stext as the mapping start address. - stextOffset = &s.Value + if s.Name == relocationSymbol { + kernelOffset = &s.Value break } } @@ -469,7 +477,7 @@ func (b *binrep) openELF(name string, start, limit, offset uint64) (plugin.ObjFi // value until we have a sample address for this mapping, so that we can // correctly identify the associated program segment that is needed to compute // the base. - if _, err := elfexec.GetBase(&ef.FileHeader, elfexec.FindTextProgHeader(ef), stextOffset, start, limit, offset); err != nil { + if _, err := elfexec.GetBase(&ef.FileHeader, elfexec.FindTextProgHeader(ef), kernelOffset, start, limit, offset); err != nil { return nil, fmt.Errorf("could not identify base for %s: %v", name, err) } @@ -478,14 +486,14 @@ func (b *binrep) openELF(name string, start, limit, offset uint64) (plugin.ObjFi b: b, name: name, buildID: buildID, - m: &elfMapping{start: start, limit: limit, offset: offset, stextOffset: stextOffset}, + m: &elfMapping{start: start, limit: limit, offset: offset, kernelOffset: kernelOffset}, }}, nil } return &fileAddr2Line{file: file{ b: b, name: name, buildID: buildID, - m: &elfMapping{start: start, limit: limit, offset: offset, stextOffset: stextOffset}, + m: &elfMapping{start: start, limit: limit, offset: offset, kernelOffset: kernelOffset}, }}, nil } @@ -521,8 +529,8 @@ func (b *binrep) openPE(name string, start, limit, offset uint64) (plugin.ObjFil type elfMapping struct { // Runtime mapping parameters. start, limit, offset uint64 - // Offset of _stext symbol. Only defined for kernel images, nil otherwise. - stextOffset *uint64 + // Offset of kernel relocation symbol. Only defined for kernel images, nil otherwise. + kernelOffset *uint64 } // findProgramHeader returns the program segment that matches the current @@ -535,7 +543,7 @@ func (m *elfMapping) findProgramHeader(ef *elf.File, addr uint64) (*elf.ProgHead // it's a kernel / .ko module mapping, because with quipper address remapping // enabled, the address would be in the lower half of the address space. - if m.stextOffset != nil || m.start >= m.limit || m.limit >= (uint64(1)<<63) { + if m.kernelOffset != nil || m.start >= m.limit || m.limit >= (uint64(1)<<63) { // For the kernel, find the program segment that includes the .text section. return elfexec.FindTextProgHeader(ef), nil } @@ -601,7 +609,7 @@ func (f *file) computeBase(addr uint64) error { return fmt.Errorf("failed to find program header for file %q, ELF mapping %#v, address %x: %v", f.name, *f.m, addr, err) } - base, err := elfexec.GetBase(&ef.FileHeader, ph, f.m.stextOffset, f.m.start, f.m.limit, f.m.offset) + base, err := elfexec.GetBase(&ef.FileHeader, ph, f.m.kernelOffset, f.m.start, f.m.limit, f.m.offset) if err != nil { return err } diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/cli.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/cli.go index 492400c5f3..237cc33233 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/driver/cli.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/cli.go @@ -98,7 +98,7 @@ func parseFlags(o *plugin.Options) (*source, []string, error) { // Recognize first argument as an executable or buildid override. if len(args) > 1 { arg0 := args[0] - if file, err := o.Obj.Open(arg0, 0, ^uint64(0), 0); err == nil { + if file, err := o.Obj.Open(arg0, 0, ^uint64(0), 0, ""); err == nil { file.Close() execName = arg0 args = args[1:] diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/fetch.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/fetch.go index b8a69e87fc..0b361651bc 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/driver/fetch.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/fetch.go @@ -420,12 +420,14 @@ mapping: fileNames = append(fileNames, filepath.Join(path, m.File)) } for _, name := range fileNames { - if f, err := obj.Open(name, m.Start, m.Limit, m.Offset); err == nil { + if f, err := obj.Open(name, m.Start, m.Limit, m.Offset, m.KernelRelocationSymbol); err == nil { defer f.Close() fileBuildID := f.BuildID() if m.BuildID != "" && m.BuildID != fileBuildID { ui.PrintErr("Ignoring local file " + name + ": build-id mismatch (" + m.BuildID + " != " + fileBuildID + ")") } else { + // Explicitly do not update KernelRelocationSymbol -- + // the new local file name is most likely missing it. m.File = name continue mapping } @@ -449,6 +451,8 @@ mapping: if execName, buildID := s.ExecName, s.BuildID; execName != "" || buildID != "" { m := p.Mapping[0] if execName != "" { + // Explicitly do not update KernelRelocationSymbol -- + // the source override is most likely missing it. m.File = execName } if buildID != "" { diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/webhtml.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/webhtml.go index b9c73271b8..63df668321 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/driver/webhtml.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/webhtml.go @@ -17,13 +17,11 @@ package driver import ( "html/template" - "github.com/google/pprof/third_party/d3" "github.com/google/pprof/third_party/d3flamegraph" ) // addTemplates adds a set of template definitions to templates. func addTemplates(templates *template.Template) { - template.Must(templates.Parse(`{{define "d3script"}}` + d3.JSSource + `{{end}}`)) template.Must(templates.Parse(`{{define "d3flamegraphscript"}}` + d3flamegraph.JSSource + `{{end}}`)) template.Must(templates.Parse(`{{define "d3flamegraphcss"}}` + d3flamegraph.CSSSource + `{{end}}`)) template.Must(templates.Parse(` @@ -1329,40 +1327,29 @@ function viewer(baseUrl, nodes) { {{template "script" .}} -