aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/vendor/github.com/google/pprof/internal
diff options
context:
space:
mode:
authorHeschi Kreinick <heschi@google.com>2022-03-16 18:17:58 -0400
committerGopher Robot <gobot@golang.org>2022-03-18 18:48:36 +0000
commit7e5804cb7014bf3154542a3d2afc68c3a61b7452 (patch)
tree7de804293b5c1d7057bff7924cce0bf5648e464b /src/cmd/vendor/github.com/google/pprof/internal
parent9f252a0462bd8c279beec56d1538e8a6c26c44c5 (diff)
downloadgo-7e5804cb7014bf3154542a3d2afc68c3a61b7452.tar.xz
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 <heschi@google.com> Run-TryBot: Heschi Kreinick <heschi@google.com> Auto-Submit: Heschi Kreinick <heschi@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Heschi Kreinick <heschi@google.com> Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com>
Diffstat (limited to 'src/cmd/vendor/github.com/google/pprof/internal')
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/binutils/binutils.go38
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/driver/cli.go2
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/driver/fetch.go6
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/driver/webhtml.go21
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/elfexec/elfexec.go6
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/graph/dotgraph.go4
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/plugin/plugin.go6
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/report/report.go2
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/report/source.go2
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/symbolizer/symbolizer.go5
10 files changed, 48 insertions, 44 deletions
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) {
</div>
{{template "script" .}}
<script>viewer(new URL(window.location.href), {{.Nodes}});</script>
- <script>{{template "d3script" .}}</script>
<script>{{template "d3flamegraphscript" .}}</script>
<script>
var data = {{.FlameGraph}};
var width = document.getElementById('chart').clientWidth;
- var flameGraph = d3.flamegraph()
+ var flameGraph = flamegraph()
.width(width)
.cellHeight(18)
.minFrameSize(1)
.transitionDuration(750)
- .transitionEase(d3.easeCubic)
.inverted(true)
.sort(true)
.title('')
.tooltip(false)
- .details(document.getElementById('flamegraphdetails'));
+ .setDetailsElement(document.getElementById('flamegraphdetails'));
// <full name> (percentage, value)
flameGraph.label((d) => d.data.f + ' (' + d.data.p + ', ' + d.data.l + ')');
- (function(flameGraph) {
- var oldColorMapper = flameGraph.color();
- function colorMapper(d) {
- // Hack to force default color mapper to use 'warm' color scheme by not passing libtype
- const { data, highlight } = d;
- return oldColorMapper({ data: { n: data.n }, highlight });
- }
-
- flameGraph.color(colorMapper);
- }(flameGraph));
+ flameGraph.setColorHue('warm');
- d3.select('#chart')
+ select('#chart')
.datum(data)
.call(flameGraph);
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/elfexec/elfexec.go b/src/cmd/vendor/github.com/google/pprof/internal/elfexec/elfexec.go
index 6447092d3d..718481b078 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/elfexec/elfexec.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/elfexec/elfexec.go
@@ -165,9 +165,9 @@ func GetBuildID(binary io.ReaderAt) ([]byte, error) {
return nil, nil
}
-// kernelBase caluclates the base for kernel mappings, which usually require
+// kernelBase calculates the base for kernel mappings, which usually require
// special handling. For kernel mappings, tools (like perf) use the address of
-// the kernel relocation symbol (_text or _stext) as the mmap start. Additionaly,
+// the kernel relocation symbol (_text or _stext) as the mmap start. Additionally,
// for obfuscation, ChromeOS profiles have the kernel image remapped to the 0-th page.
func kernelBase(loadSegment *elf.ProgHeader, stextOffset *uint64, start, limit, offset uint64) (uint64, bool) {
const (
@@ -217,7 +217,7 @@ func kernelBase(loadSegment *elf.ProgHeader, stextOffset *uint64, start, limit,
// GetBase determines the base address to subtract from virtual
// address to get symbol table address. For an executable, the base
// is 0. Otherwise, it's a shared library, and the base is the
-// address where the mapping starts. The kernel needs special hanldling.
+// address where the mapping starts. The kernel needs special handling.
func GetBase(fh *elf.FileHeader, loadSegment *elf.ProgHeader, stextOffset *uint64, start, limit, offset uint64) (uint64, error) {
if start == 0 && offset == 0 && (limit == ^uint64(0) || limit == 0) {
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/graph/dotgraph.go b/src/cmd/vendor/github.com/google/pprof/internal/graph/dotgraph.go
index 8008675248..9ff4c95adb 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/graph/dotgraph.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/graph/dotgraph.go
@@ -126,7 +126,7 @@ func (b *builder) addLegend() {
return
}
title := labels[0]
- fmt.Fprintf(b, `subgraph cluster_L { "%s" [shape=box fontsize=16`, title)
+ fmt.Fprintf(b, `subgraph cluster_L { "%s" [shape=box fontsize=16`, escapeForDot(title))
fmt.Fprintf(b, ` label="%s\l"`, strings.Join(escapeAllForDot(labels), `\l`))
if b.config.LegendURL != "" {
fmt.Fprintf(b, ` URL="%s" target="_blank"`, b.config.LegendURL)
@@ -485,7 +485,7 @@ func escapeAllForDot(in []string) []string {
// escapeForDot escapes double quotes and backslashes, and replaces Graphviz's
// "center" character (\n) with a left-justified character.
-// See https://graphviz.org/doc/info/attrs.html#k:escString for more info.
+// See https://graphviz.org/docs/attr-types/escString/ for more info.
func escapeForDot(str string) string {
return strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(str, `\`, `\\`), `"`, `\"`), "\n", `\l`)
}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/plugin/plugin.go b/src/cmd/vendor/github.com/google/pprof/internal/plugin/plugin.go
index a57a0b20a9..98eb1dd817 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/plugin/plugin.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/plugin/plugin.go
@@ -109,8 +109,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.
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/report/report.go b/src/cmd/vendor/github.com/google/pprof/internal/report/report.go
index e2fb00314c..36ddf2e934 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/report/report.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/report/report.go
@@ -526,7 +526,7 @@ func symbolsFromBinaries(prof *profile.Profile, g *graph.Graph, rx *regexp.Regex
}
}
- f, err := obj.Open(m.File, m.Start, m.Limit, m.Offset)
+ f, err := obj.Open(m.File, m.Start, m.Limit, m.Offset, m.KernelRelocationSymbol)
if err != nil {
fmt.Printf("%v\n", err)
continue
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/report/source.go b/src/cmd/vendor/github.com/google/pprof/internal/report/source.go
index 33d04c591d..d8b4395265 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/report/source.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/report/source.go
@@ -744,7 +744,7 @@ func (sp *sourcePrinter) objectFile(m *profile.Mapping) plugin.ObjFile {
if object, ok := sp.objects[m.File]; ok {
return object // May be nil if we detected an error earlier.
}
- object, err := sp.objectTool.Open(m.File, m.Start, m.Limit, m.Offset)
+ object, err := sp.objectTool.Open(m.File, m.Start, m.Limit, m.Offset, m.KernelRelocationSymbol)
if err != nil {
object = nil
}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/symbolizer/symbolizer.go b/src/cmd/vendor/github.com/google/pprof/internal/symbolizer/symbolizer.go
index d741e7ad7f..cbb0ed4d1b 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/symbolizer/symbolizer.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/symbolizer/symbolizer.go
@@ -325,7 +325,10 @@ func newMapping(prof *profile.Profile, obj plugin.ObjTool, ui plugin.UI, force b
}
name := filepath.Base(m.File)
- f, err := obj.Open(m.File, m.Start, m.Limit, m.Offset)
+ if m.BuildID != "" {
+ name += fmt.Sprintf(" (build ID %s)", m.BuildID)
+ }
+ f, err := obj.Open(m.File, m.Start, m.Limit, m.Offset, m.KernelRelocationSymbol)
if err != nil {
ui.PrintErr("Local symbolization failed for ", name, ": ", err)
missingBinaries = true